1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package arm64
32
33 import (
34 "cmd/internal/obj"
35 "cmd/internal/objabi"
36 "encoding/binary"
37 "errors"
38 "fmt"
39 "log"
40 "math"
41 "math/bits"
42 "slices"
43 "strings"
44 )
45
46
47
48
49 type ctxt7 struct {
50 ctxt *obj.Link
51 newprog obj.ProgAlloc
52 cursym *obj.LSym
53 blitrl *obj.Prog
54 elitrl *obj.Prog
55 autosize int32
56 extrasize int32
57 instoffset int64
58 pc int64
59 pool struct {
60 start uint32
61 size uint32
62 }
63 }
64
65 const (
66 funcAlign = 16
67 )
68
69 const (
70 REGFROM = 1
71 )
72
73 type Optab struct {
74 as obj.As
75 a1 uint8
76 a2 uint8
77 a3 uint8
78 a4 uint8
79 a5 uint8
80 type_ int8
81 size_ int8
82 param int16
83 flag int8
84 scond uint8
85 }
86
87 func IsAtomicInstruction(as obj.As) bool {
88 if _, ok := atomicLDADD[as]; ok {
89 return true
90 }
91 if _, ok := atomicSWP[as]; ok {
92 return true
93 }
94 return false
95 }
96
97
98 var atomicLDADD = map[obj.As]uint32{
99 ALDADDAD: 3<<30 | 0x1c5<<21 | 0x00<<10,
100 ALDADDAW: 2<<30 | 0x1c5<<21 | 0x00<<10,
101 ALDADDAH: 1<<30 | 0x1c5<<21 | 0x00<<10,
102 ALDADDAB: 0<<30 | 0x1c5<<21 | 0x00<<10,
103 ALDADDALD: 3<<30 | 0x1c7<<21 | 0x00<<10,
104 ALDADDALW: 2<<30 | 0x1c7<<21 | 0x00<<10,
105 ALDADDALH: 1<<30 | 0x1c7<<21 | 0x00<<10,
106 ALDADDALB: 0<<30 | 0x1c7<<21 | 0x00<<10,
107 ALDADDD: 3<<30 | 0x1c1<<21 | 0x00<<10,
108 ALDADDW: 2<<30 | 0x1c1<<21 | 0x00<<10,
109 ALDADDH: 1<<30 | 0x1c1<<21 | 0x00<<10,
110 ALDADDB: 0<<30 | 0x1c1<<21 | 0x00<<10,
111 ALDADDLD: 3<<30 | 0x1c3<<21 | 0x00<<10,
112 ALDADDLW: 2<<30 | 0x1c3<<21 | 0x00<<10,
113 ALDADDLH: 1<<30 | 0x1c3<<21 | 0x00<<10,
114 ALDADDLB: 0<<30 | 0x1c3<<21 | 0x00<<10,
115 ALDCLRAD: 3<<30 | 0x1c5<<21 | 0x04<<10,
116 ALDCLRAW: 2<<30 | 0x1c5<<21 | 0x04<<10,
117 ALDCLRAH: 1<<30 | 0x1c5<<21 | 0x04<<10,
118 ALDCLRAB: 0<<30 | 0x1c5<<21 | 0x04<<10,
119 ALDCLRALD: 3<<30 | 0x1c7<<21 | 0x04<<10,
120 ALDCLRALW: 2<<30 | 0x1c7<<21 | 0x04<<10,
121 ALDCLRALH: 1<<30 | 0x1c7<<21 | 0x04<<10,
122 ALDCLRALB: 0<<30 | 0x1c7<<21 | 0x04<<10,
123 ALDCLRD: 3<<30 | 0x1c1<<21 | 0x04<<10,
124 ALDCLRW: 2<<30 | 0x1c1<<21 | 0x04<<10,
125 ALDCLRH: 1<<30 | 0x1c1<<21 | 0x04<<10,
126 ALDCLRB: 0<<30 | 0x1c1<<21 | 0x04<<10,
127 ALDCLRLD: 3<<30 | 0x1c3<<21 | 0x04<<10,
128 ALDCLRLW: 2<<30 | 0x1c3<<21 | 0x04<<10,
129 ALDCLRLH: 1<<30 | 0x1c3<<21 | 0x04<<10,
130 ALDCLRLB: 0<<30 | 0x1c3<<21 | 0x04<<10,
131 ALDEORAD: 3<<30 | 0x1c5<<21 | 0x08<<10,
132 ALDEORAW: 2<<30 | 0x1c5<<21 | 0x08<<10,
133 ALDEORAH: 1<<30 | 0x1c5<<21 | 0x08<<10,
134 ALDEORAB: 0<<30 | 0x1c5<<21 | 0x08<<10,
135 ALDEORALD: 3<<30 | 0x1c7<<21 | 0x08<<10,
136 ALDEORALW: 2<<30 | 0x1c7<<21 | 0x08<<10,
137 ALDEORALH: 1<<30 | 0x1c7<<21 | 0x08<<10,
138 ALDEORALB: 0<<30 | 0x1c7<<21 | 0x08<<10,
139 ALDEORD: 3<<30 | 0x1c1<<21 | 0x08<<10,
140 ALDEORW: 2<<30 | 0x1c1<<21 | 0x08<<10,
141 ALDEORH: 1<<30 | 0x1c1<<21 | 0x08<<10,
142 ALDEORB: 0<<30 | 0x1c1<<21 | 0x08<<10,
143 ALDEORLD: 3<<30 | 0x1c3<<21 | 0x08<<10,
144 ALDEORLW: 2<<30 | 0x1c3<<21 | 0x08<<10,
145 ALDEORLH: 1<<30 | 0x1c3<<21 | 0x08<<10,
146 ALDEORLB: 0<<30 | 0x1c3<<21 | 0x08<<10,
147 ALDORAD: 3<<30 | 0x1c5<<21 | 0x0c<<10,
148 ALDORAW: 2<<30 | 0x1c5<<21 | 0x0c<<10,
149 ALDORAH: 1<<30 | 0x1c5<<21 | 0x0c<<10,
150 ALDORAB: 0<<30 | 0x1c5<<21 | 0x0c<<10,
151 ALDORALD: 3<<30 | 0x1c7<<21 | 0x0c<<10,
152 ALDORALW: 2<<30 | 0x1c7<<21 | 0x0c<<10,
153 ALDORALH: 1<<30 | 0x1c7<<21 | 0x0c<<10,
154 ALDORALB: 0<<30 | 0x1c7<<21 | 0x0c<<10,
155 ALDORD: 3<<30 | 0x1c1<<21 | 0x0c<<10,
156 ALDORW: 2<<30 | 0x1c1<<21 | 0x0c<<10,
157 ALDORH: 1<<30 | 0x1c1<<21 | 0x0c<<10,
158 ALDORB: 0<<30 | 0x1c1<<21 | 0x0c<<10,
159 ALDORLD: 3<<30 | 0x1c3<<21 | 0x0c<<10,
160 ALDORLW: 2<<30 | 0x1c3<<21 | 0x0c<<10,
161 ALDORLH: 1<<30 | 0x1c3<<21 | 0x0c<<10,
162 ALDORLB: 0<<30 | 0x1c3<<21 | 0x0c<<10,
163 }
164
165 var atomicSWP = map[obj.As]uint32{
166 ASWPAD: 3<<30 | 0x1c5<<21 | 0x20<<10,
167 ASWPAW: 2<<30 | 0x1c5<<21 | 0x20<<10,
168 ASWPAH: 1<<30 | 0x1c5<<21 | 0x20<<10,
169 ASWPAB: 0<<30 | 0x1c5<<21 | 0x20<<10,
170 ASWPALD: 3<<30 | 0x1c7<<21 | 0x20<<10,
171 ASWPALW: 2<<30 | 0x1c7<<21 | 0x20<<10,
172 ASWPALH: 1<<30 | 0x1c7<<21 | 0x20<<10,
173 ASWPALB: 0<<30 | 0x1c7<<21 | 0x20<<10,
174 ASWPD: 3<<30 | 0x1c1<<21 | 0x20<<10,
175 ASWPW: 2<<30 | 0x1c1<<21 | 0x20<<10,
176 ASWPH: 1<<30 | 0x1c1<<21 | 0x20<<10,
177 ASWPB: 0<<30 | 0x1c1<<21 | 0x20<<10,
178 ASWPLD: 3<<30 | 0x1c3<<21 | 0x20<<10,
179 ASWPLW: 2<<30 | 0x1c3<<21 | 0x20<<10,
180 ASWPLH: 1<<30 | 0x1c3<<21 | 0x20<<10,
181 ASWPLB: 0<<30 | 0x1c3<<21 | 0x20<<10,
182 ACASD: 3<<30 | 0x45<<21 | 0x1f<<10,
183 ACASW: 2<<30 | 0x45<<21 | 0x1f<<10,
184 ACASH: 1<<30 | 0x45<<21 | 0x1f<<10,
185 ACASB: 0<<30 | 0x45<<21 | 0x1f<<10,
186 ACASAD: 3<<30 | 0x47<<21 | 0x1f<<10,
187 ACASAW: 2<<30 | 0x47<<21 | 0x1f<<10,
188 ACASLD: 3<<30 | 0x45<<21 | 0x3f<<10,
189 ACASLW: 2<<30 | 0x45<<21 | 0x3f<<10,
190 ACASALD: 3<<30 | 0x47<<21 | 0x3f<<10,
191 ACASALW: 2<<30 | 0x47<<21 | 0x3f<<10,
192 ACASALH: 1<<30 | 0x47<<21 | 0x3f<<10,
193 ACASALB: 0<<30 | 0x47<<21 | 0x3f<<10,
194 }
195 var atomicCASP = map[obj.As]uint32{
196 ACASPD: 1<<30 | 0x41<<21 | 0x1f<<10,
197 ACASPW: 0<<30 | 0x41<<21 | 0x1f<<10,
198 }
199
200 var oprange [ALAST & obj.AMask][]Optab
201
202 var xcmp [C_NCLASS][C_NCLASS]bool
203
204 const (
205 S32 = 0 << 31
206 S64 = 1 << 31
207 Sbit = 1 << 29
208 LSL0_32 = 2 << 13
209 LSL0_64 = 3 << 13
210 )
211
212 func OPDP2(x uint32) uint32 {
213 return 0<<30 | 0<<29 | 0xd6<<21 | x<<10
214 }
215
216 func OPDP3(sf uint32, op54 uint32, op31 uint32, o0 uint32) uint32 {
217 return sf<<31 | op54<<29 | 0x1B<<24 | op31<<21 | o0<<15
218 }
219
220 func OPBcc(x uint32) uint32 {
221 return 0x2A<<25 | 0<<24 | 0<<4 | x&15
222 }
223
224 func OPBLR(x uint32) uint32 {
225
226 return 0x6B<<25 | 0<<23 | x<<21 | 0x1F<<16 | 0<<10
227 }
228
229 func SYSOP(l uint32, op0 uint32, op1 uint32, crn uint32, crm uint32, op2 uint32, rt uint32) uint32 {
230 return 0x354<<22 | l<<21 | op0<<19 | op1<<16 | crn&15<<12 | crm&15<<8 | op2<<5 | rt
231 }
232
233 func SYSHINT(x uint32) uint32 {
234 return SYSOP(0, 0, 3, 2, 0, x, 0x1F)
235 }
236
237 func LDSTR(sz uint32, v uint32, opc uint32) uint32 {
238 return sz<<30 | 7<<27 | v<<26 | opc<<22
239 }
240
241 func LD2STR(o uint32) uint32 {
242 return o &^ (3 << 22)
243 }
244
245 func LDSTX(sz uint32, o2 uint32, l uint32, o1 uint32, o0 uint32) uint32 {
246 return sz<<30 | 0x8<<24 | o2<<23 | l<<22 | o1<<21 | o0<<15
247 }
248
249 func FPCMP(m uint32, s uint32, type_ uint32, op uint32, op2 uint32) uint32 {
250 return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<14 | 8<<10 | op2
251 }
252
253 func FPCCMP(m uint32, s uint32, type_ uint32, op uint32) uint32 {
254 return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | 1<<10 | op<<4
255 }
256
257 func FPOP1S(m uint32, s uint32, type_ uint32, op uint32) uint32 {
258 return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<15 | 0x10<<10
259 }
260
261 func FPOP2S(m uint32, s uint32, type_ uint32, op uint32) uint32 {
262 return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<12 | 2<<10
263 }
264
265 func FPOP3S(m uint32, s uint32, type_ uint32, op uint32, op2 uint32) uint32 {
266 return m<<31 | s<<29 | 0x1F<<24 | type_<<22 | op<<21 | op2<<15
267 }
268
269 func FPCVTI(sf uint32, s uint32, type_ uint32, rmode uint32, op uint32) uint32 {
270 return sf<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | rmode<<19 | op<<16 | 0<<10
271 }
272
273 func ADR(p uint32, o uint32, rt uint32) uint32 {
274 return p<<31 | (o&3)<<29 | 0x10<<24 | ((o>>2)&0x7FFFF)<<5 | rt&31
275 }
276
277 func OPBIT(x uint32) uint32 {
278 return 1<<30 | 0<<29 | 0xD6<<21 | 0<<16 | x<<10
279 }
280
281 func MOVCONST(d int64, s int, rt int) uint32 {
282 return uint32(((d>>uint(s*16))&0xFFFF)<<5) | uint32(s)&3<<21 | uint32(rt&31)
283 }
284
285 const (
286
287 LFROM = 1 << iota
288 LTO
289 NOTUSETMP
290 BRANCH14BITS
291 BRANCH19BITS
292 )
293
294 var optab = []Optab{
295
297 {obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, C_NONE, 0, 0, 0, 0, 0},
298
299
300 {AADD, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
301 {AADD, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
302 {AADC, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
303 {AADC, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
304 {ANEG, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 25, 4, 0, 0, 0},
305 {ANEG, C_NONE, C_NONE, C_NONE, C_ZREG, C_NONE, 25, 4, 0, 0, 0},
306 {ANGC, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 17, 4, 0, 0, 0},
307 {ACMP, C_ZREG, C_ZREG, C_NONE, C_NONE, C_NONE, 1, 4, 0, 0, 0},
308 {AADD, C_ADDCON, C_RSP, C_NONE, C_RSP, C_NONE, 2, 4, 0, 0, 0},
309 {AADD, C_ADDCON, C_NONE, C_NONE, C_RSP, C_NONE, 2, 4, 0, 0, 0},
310 {ACMP, C_ADDCON, C_RSP, C_NONE, C_NONE, C_NONE, 2, 4, 0, 0, 0},
311 {AADD, C_MOVCON, C_RSP, C_NONE, C_RSP, C_NONE, 62, 8, 0, 0, 0},
312 {AADD, C_MOVCON, C_NONE, C_NONE, C_RSP, C_NONE, 62, 8, 0, 0, 0},
313 {ACMP, C_MOVCON, C_RSP, C_NONE, C_NONE, C_NONE, 62, 8, 0, 0, 0},
314 {AADD, C_BITCON, C_RSP, C_NONE, C_RSP, C_NONE, 62, 8, 0, 0, 0},
315 {AADD, C_BITCON, C_NONE, C_NONE, C_RSP, C_NONE, 62, 8, 0, 0, 0},
316 {ACMP, C_BITCON, C_RSP, C_NONE, C_NONE, C_NONE, 62, 8, 0, 0, 0},
317 {AADD, C_ADDCON2, C_RSP, C_NONE, C_RSP, C_NONE, 48, 8, 0, NOTUSETMP, 0},
318 {AADD, C_ADDCON2, C_NONE, C_NONE, C_RSP, C_NONE, 48, 8, 0, NOTUSETMP, 0},
319 {AADD, C_MOVCON2, C_RSP, C_NONE, C_RSP, C_NONE, 13, 12, 0, 0, 0},
320 {AADD, C_MOVCON2, C_NONE, C_NONE, C_RSP, C_NONE, 13, 12, 0, 0, 0},
321 {AADD, C_MOVCON3, C_RSP, C_NONE, C_RSP, C_NONE, 13, 16, 0, 0, 0},
322 {AADD, C_MOVCON3, C_NONE, C_NONE, C_RSP, C_NONE, 13, 16, 0, 0, 0},
323 {AADD, C_VCON, C_RSP, C_NONE, C_RSP, C_NONE, 13, 20, 0, 0, 0},
324 {AADD, C_VCON, C_NONE, C_NONE, C_RSP, C_NONE, 13, 20, 0, 0, 0},
325 {ACMP, C_MOVCON2, C_ZREG, C_NONE, C_NONE, C_NONE, 13, 12, 0, 0, 0},
326 {ACMP, C_MOVCON3, C_ZREG, C_NONE, C_NONE, C_NONE, 13, 16, 0, 0, 0},
327 {ACMP, C_VCON, C_ZREG, C_NONE, C_NONE, C_NONE, 13, 20, 0, 0, 0},
328 {AADD, C_SHIFT, C_ZREG, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
329 {AADD, C_SHIFT, C_NONE, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
330 {AMVN, C_SHIFT, C_NONE, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
331 {ACMP, C_SHIFT, C_ZREG, C_NONE, C_NONE, C_NONE, 3, 4, 0, 0, 0},
332 {ANEG, C_SHIFT, C_NONE, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
333 {AADD, C_ZREG, C_RSP, C_NONE, C_RSP, C_NONE, 27, 4, 0, 0, 0},
334 {AADD, C_ZREG, C_NONE, C_NONE, C_RSP, C_NONE, 27, 4, 0, 0, 0},
335 {ACMP, C_ZREG, C_RSP, C_NONE, C_NONE, C_NONE, 27, 4, 0, 0, 0},
336 {AADD, C_EXTREG, C_RSP, C_NONE, C_RSP, C_NONE, 27, 4, 0, 0, 0},
337 {AADD, C_EXTREG, C_NONE, C_NONE, C_RSP, C_NONE, 27, 4, 0, 0, 0},
338 {ACMP, C_EXTREG, C_RSP, C_NONE, C_NONE, C_NONE, 27, 4, 0, 0, 0},
339 {AADD, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
340 {AADD, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
341 {AMUL, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 15, 4, 0, 0, 0},
342 {AMUL, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 15, 4, 0, 0, 0},
343 {AMADD, C_ZREG, C_ZREG, C_ZREG, C_ZREG, C_NONE, 15, 4, 0, 0, 0},
344 {AREM, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 16, 8, 0, 0, 0},
345 {AREM, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 16, 8, 0, 0, 0},
346 {ASDIV, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
347 {ASDIV, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
348
349 {AFADDS, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 54, 4, 0, 0, 0},
350 {AFADDS, C_FREG, C_FREG, C_NONE, C_FREG, C_NONE, 54, 4, 0, 0, 0},
351 {AFMSUBD, C_FREG, C_FREG, C_FREG, C_FREG, C_NONE, 15, 4, 0, 0, 0},
352 {AFCMPS, C_FREG, C_FREG, C_NONE, C_NONE, C_NONE, 56, 4, 0, 0, 0},
353 {AFCMPS, C_FCON, C_FREG, C_NONE, C_NONE, C_NONE, 56, 4, 0, 0, 0},
354 {AVADDP, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 72, 4, 0, 0, 0},
355 {AVADD, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 72, 4, 0, 0, 0},
356 {AVADD, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 89, 4, 0, 0, 0},
357 {AVADD, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 89, 4, 0, 0, 0},
358 {AVADDV, C_ARNG, C_NONE, C_NONE, C_VREG, C_NONE, 85, 4, 0, 0, 0},
359
360
361 {AAND, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
362 {AAND, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
363 {AANDS, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
364 {AANDS, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
365 {ATST, C_ZREG, C_ZREG, C_NONE, C_NONE, C_NONE, 1, 4, 0, 0, 0},
366 {AAND, C_MBCON, C_ZREG, C_NONE, C_RSP, C_NONE, 53, 4, 0, 0, 0},
367 {AAND, C_MBCON, C_NONE, C_NONE, C_RSP, C_NONE, 53, 4, 0, 0, 0},
368 {AANDS, C_MBCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 53, 4, 0, 0, 0},
369 {AANDS, C_MBCON, C_NONE, C_NONE, C_ZREG, C_NONE, 53, 4, 0, 0, 0},
370 {ATST, C_MBCON, C_ZREG, C_NONE, C_NONE, C_NONE, 53, 4, 0, 0, 0},
371 {AAND, C_BITCON, C_ZREG, C_NONE, C_RSP, C_NONE, 53, 4, 0, 0, 0},
372 {AAND, C_BITCON, C_NONE, C_NONE, C_RSP, C_NONE, 53, 4, 0, 0, 0},
373 {AANDS, C_BITCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 53, 4, 0, 0, 0},
374 {AANDS, C_BITCON, C_NONE, C_NONE, C_ZREG, C_NONE, 53, 4, 0, 0, 0},
375 {ATST, C_BITCON, C_ZREG, C_NONE, C_NONE, C_NONE, 53, 4, 0, 0, 0},
376 {AAND, C_MOVCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 62, 8, 0, 0, 0},
377 {AAND, C_MOVCON, C_NONE, C_NONE, C_ZREG, C_NONE, 62, 8, 0, 0, 0},
378 {AANDS, C_MOVCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 62, 8, 0, 0, 0},
379 {AANDS, C_MOVCON, C_NONE, C_NONE, C_ZREG, C_NONE, 62, 8, 0, 0, 0},
380 {ATST, C_MOVCON, C_ZREG, C_NONE, C_NONE, C_NONE, 62, 8, 0, 0, 0},
381 {AAND, C_MOVCON2, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 12, 0, 0, 0},
382 {AAND, C_MOVCON2, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 12, 0, 0, 0},
383 {AAND, C_MOVCON3, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 16, 0, 0, 0},
384 {AAND, C_MOVCON3, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 16, 0, 0, 0},
385 {AAND, C_VCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 20, 0, 0, 0},
386 {AAND, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 20, 0, 0, 0},
387 {AANDS, C_MOVCON2, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 12, 0, 0, 0},
388 {AANDS, C_MOVCON2, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 12, 0, 0, 0},
389 {AANDS, C_MOVCON3, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 16, 0, 0, 0},
390 {AANDS, C_MOVCON3, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 16, 0, 0, 0},
391 {AANDS, C_VCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 20, 0, 0, 0},
392 {AANDS, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 20, 0, 0, 0},
393 {ATST, C_MOVCON2, C_ZREG, C_NONE, C_NONE, C_NONE, 28, 12, 0, 0, 0},
394 {ATST, C_MOVCON3, C_ZREG, C_NONE, C_NONE, C_NONE, 28, 16, 0, 0, 0},
395 {ATST, C_VCON, C_ZREG, C_NONE, C_NONE, C_NONE, 28, 20, 0, 0, 0},
396 {AAND, C_SHIFT, C_ZREG, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
397 {AAND, C_SHIFT, C_NONE, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
398 {AANDS, C_SHIFT, C_ZREG, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
399 {AANDS, C_SHIFT, C_NONE, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
400 {ATST, C_SHIFT, C_ZREG, C_NONE, C_NONE, C_NONE, 3, 4, 0, 0, 0},
401 {AMOVD, C_RSP, C_NONE, C_NONE, C_RSP, C_NONE, 24, 4, 0, 0, 0},
402 {AMOVD, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 24, 4, 0, 0, 0},
403 {AMVN, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 24, 4, 0, 0, 0},
404 {AMOVB, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 45, 4, 0, 0, 0},
405 {AMOVH, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 45, 4, 0, 0, 0},
406 {AMOVW, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 45, 4, 0, 0, 0},
407
408
409
410 {AMOVW, C_MBCON, C_NONE, C_NONE, C_ZREG, C_NONE, 32, 4, 0, 0, 0},
411 {AMOVD, C_MBCON, C_NONE, C_NONE, C_ZREG, C_NONE, 32, 4, 0, 0, 0},
412 {AMOVW, C_MOVCON, C_NONE, C_NONE, C_ZREG, C_NONE, 32, 4, 0, 0, 0},
413 {AMOVD, C_MOVCON, C_NONE, C_NONE, C_ZREG, C_NONE, 32, 4, 0, 0, 0},
414 {AMOVW, C_BITCON, C_NONE, C_NONE, C_RSP, C_NONE, 32, 4, 0, 0, 0},
415 {AMOVD, C_BITCON, C_NONE, C_NONE, C_RSP, C_NONE, 32, 4, 0, 0, 0},
416 {AMOVW, C_MOVCON2, C_NONE, C_NONE, C_ZREG, C_NONE, 12, 8, 0, NOTUSETMP, 0},
417 {AMOVD, C_MOVCON2, C_NONE, C_NONE, C_ZREG, C_NONE, 12, 8, 0, NOTUSETMP, 0},
418 {AMOVD, C_MOVCON3, C_NONE, C_NONE, C_ZREG, C_NONE, 12, 12, 0, NOTUSETMP, 0},
419 {AMOVD, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 12, 16, 0, NOTUSETMP, 0},
420
421 {AMOVK, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 33, 4, 0, 0, 0},
422 {AMOVD, C_AACON, C_NONE, C_NONE, C_RSP, C_NONE, 4, 4, REGFROM, 0, 0},
423 {AMOVD, C_AACON2, C_NONE, C_NONE, C_RSP, C_NONE, 4, 8, REGFROM, NOTUSETMP, 0},
424
425
426 {AMOVD, C_LACON, C_NONE, C_NONE, C_RSP, C_NONE, 34, 8, REGSP, LFROM, 0},
427
428
429 {AVMOVS, C_ADDR, C_NONE, C_NONE, C_VREG, C_NONE, 65, 12, 0, 0, 0},
430 {AVMOVD, C_ADDR, C_NONE, C_NONE, C_VREG, C_NONE, 65, 12, 0, 0, 0},
431 {AVMOVQ, C_ADDR, C_NONE, C_NONE, C_VREG, C_NONE, 65, 12, 0, 0, 0},
432
433
434 {AB, C_NONE, C_NONE, C_NONE, C_SBRA, C_NONE, 5, 4, 0, 0, 0},
435 {ABL, C_NONE, C_NONE, C_NONE, C_SBRA, C_NONE, 5, 4, 0, 0, 0},
436 {AB, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 6, 4, 0, 0, 0},
437 {ABL, C_NONE, C_NONE, C_NONE, C_ZREG, C_NONE, 6, 4, 0, 0, 0},
438 {ABL, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 6, 4, 0, 0, 0},
439 {obj.ARET, C_NONE, C_NONE, C_NONE, C_ZREG, C_NONE, 6, 4, 0, 0, 0},
440 {obj.ARET, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 6, 4, 0, 0, 0},
441 {ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, C_NONE, 7, 4, 0, BRANCH19BITS, 0},
442 {ACBZ, C_ZREG, C_NONE, C_NONE, C_SBRA, C_NONE, 39, 4, 0, BRANCH19BITS, 0},
443 {ATBZ, C_VCON, C_ZREG, C_NONE, C_SBRA, C_NONE, 40, 4, 0, BRANCH14BITS, 0},
444 {AERET, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0},
445
446
447 {AADRP, C_SBRA, C_NONE, C_NONE, C_ZREG, C_NONE, 60, 4, 0, 0, 0},
448 {AADR, C_SBRA, C_NONE, C_NONE, C_ZREG, C_NONE, 61, 4, 0, 0, 0},
449
450 {ACLREX, C_NONE, C_NONE, C_NONE, C_VCON, C_NONE, 38, 4, 0, 0, 0},
451 {ACLREX, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0, 0},
452 {ABFM, C_VCON, C_ZREG, C_VCON, C_ZREG, C_NONE, 42, 4, 0, 0, 0},
453 {ABFI, C_VCON, C_ZREG, C_VCON, C_ZREG, C_NONE, 43, 4, 0, 0, 0},
454 {AEXTR, C_VCON, C_ZREG, C_ZREG, C_ZREG, C_NONE, 44, 4, 0, 0, 0},
455 {ASXTB, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 45, 4, 0, 0, 0},
456 {ACLS, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 46, 4, 0, 0, 0},
457 {ALSL, C_VCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 8, 4, 0, 0, 0},
458 {ALSL, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 8, 4, 0, 0, 0},
459 {ALSL, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 9, 4, 0, 0, 0},
460 {ALSL, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 9, 4, 0, 0, 0},
461 {ASVC, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0},
462 {ASVC, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0},
463 {ADWORD, C_NONE, C_NONE, C_NONE, C_VCON, C_NONE, 11, 8, 0, NOTUSETMP, 0},
464 {ADWORD, C_NONE, C_NONE, C_NONE, C_LEXT, C_NONE, 11, 8, 0, NOTUSETMP, 0},
465 {ADWORD, C_NONE, C_NONE, C_NONE, C_ADDR, C_NONE, 11, 8, 0, NOTUSETMP, 0},
466 {ADWORD, C_NONE, C_NONE, C_NONE, C_LACON, C_NONE, 11, 8, 0, NOTUSETMP, 0},
467 {AWORD, C_NONE, C_NONE, C_NONE, C_LCON, C_NONE, 14, 4, 0, 0, 0},
468 {AWORD, C_NONE, C_NONE, C_NONE, C_LEXT, C_NONE, 14, 4, 0, 0, 0},
469 {AWORD, C_NONE, C_NONE, C_NONE, C_ADDR, C_NONE, 14, 4, 0, 0, 0},
470 {AMOVW, C_VCONADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 68, 8, 0, NOTUSETMP, 0},
471 {AMOVD, C_VCONADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 68, 8, 0, NOTUSETMP, 0},
472 {AMOVB, C_ZREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
473 {AMOVH, C_ZREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
474 {AMOVW, C_ZREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
475 {AMOVD, C_ZREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
476 {AMOVB, C_ADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 65, 12, 0, 0, 0},
477 {AMOVH, C_ADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 65, 12, 0, 0, 0},
478 {AMOVW, C_ADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 65, 12, 0, 0, 0},
479 {AMOVD, C_ADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 65, 12, 0, 0, 0},
480 {AMOVD, C_GOTADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 71, 8, 0, 0, 0},
481 {AMOVD, C_TLS_LE, C_NONE, C_NONE, C_ZREG, C_NONE, 69, 4, 0, 0, 0},
482 {AMOVD, C_TLS_IE, C_NONE, C_NONE, C_ZREG, C_NONE, 70, 8, 0, 0, 0},
483
484 {AFMOVS, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
485 {AFMOVS, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 65, 12, 0, 0, 0},
486 {AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
487 {AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 65, 12, 0, 0, 0},
488 {AFMOVS, C_FCON, C_NONE, C_NONE, C_FREG, C_NONE, 55, 4, 0, 0, 0},
489 {AFMOVS, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 54, 4, 0, 0, 0},
490 {AFMOVD, C_FCON, C_NONE, C_NONE, C_FREG, C_NONE, 55, 4, 0, 0, 0},
491 {AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 54, 4, 0, 0, 0},
492 {AFMOVS, C_ZREG, C_NONE, C_NONE, C_FREG, C_NONE, 29, 4, 0, 0, 0},
493 {AFMOVS, C_FREG, C_NONE, C_NONE, C_ZREG, C_NONE, 29, 4, 0, 0, 0},
494 {AFMOVD, C_ZREG, C_NONE, C_NONE, C_FREG, C_NONE, 29, 4, 0, 0, 0},
495 {AFMOVD, C_FREG, C_NONE, C_NONE, C_ZREG, C_NONE, 29, 4, 0, 0, 0},
496 {AFCVTZSD, C_FREG, C_NONE, C_NONE, C_ZREG, C_NONE, 29, 4, 0, 0, 0},
497 {ASCVTFD, C_ZREG, C_NONE, C_NONE, C_FREG, C_NONE, 29, 4, 0, 0, 0},
498 {AFCVTSD, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 29, 4, 0, 0, 0},
499 {AVMOV, C_ELEM, C_NONE, C_NONE, C_ZREG, C_NONE, 73, 4, 0, 0, 0},
500 {AVMOV, C_ELEM, C_NONE, C_NONE, C_ELEM, C_NONE, 92, 4, 0, 0, 0},
501 {AVMOV, C_ELEM, C_NONE, C_NONE, C_VREG, C_NONE, 80, 4, 0, 0, 0},
502 {AVMOV, C_ZREG, C_NONE, C_NONE, C_ARNG, C_NONE, 82, 4, 0, 0, 0},
503 {AVMOV, C_ZREG, C_NONE, C_NONE, C_ELEM, C_NONE, 78, 4, 0, 0, 0},
504 {AVMOV, C_ARNG, C_NONE, C_NONE, C_ARNG, C_NONE, 83, 4, 0, 0, 0},
505 {AVDUP, C_ELEM, C_NONE, C_NONE, C_ARNG, C_NONE, 79, 4, 0, 0, 0},
506 {AVDUP, C_ELEM, C_NONE, C_NONE, C_VREG, C_NONE, 80, 4, 0, 0, 0},
507 {AVDUP, C_ZREG, C_NONE, C_NONE, C_ARNG, C_NONE, 82, 4, 0, 0, 0},
508 {AVMOVI, C_ADDCON, C_NONE, C_NONE, C_ARNG, C_NONE, 86, 4, 0, 0, 0},
509 {AVFMLA, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 72, 4, 0, 0, 0},
510 {AVEXT, C_VCON, C_ARNG, C_ARNG, C_ARNG, C_NONE, 94, 4, 0, 0, 0},
511 {AVTBL, C_ARNG, C_NONE, C_LIST, C_ARNG, C_NONE, 100, 4, 0, 0, 0},
512 {AVUSHR, C_VCON, C_ARNG, C_NONE, C_ARNG, C_NONE, 95, 4, 0, 0, 0},
513 {AVZIP1, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 72, 4, 0, 0, 0},
514 {AVUSHLL, C_VCON, C_ARNG, C_NONE, C_ARNG, C_NONE, 102, 4, 0, 0, 0},
515 {AVUXTL, C_ARNG, C_NONE, C_NONE, C_ARNG, C_NONE, 102, 4, 0, 0, 0},
516 {AVUADDW, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 105, 4, 0, 0, 0},
517
518
519 {ACSEL, C_COND, C_ZREG, C_ZREG, C_ZREG, C_NONE, 18, 4, 0, 0, 0},
520 {ACINC, C_COND, C_ZREG, C_NONE, C_ZREG, C_NONE, 18, 4, 0, 0, 0},
521 {ACSET, C_COND, C_NONE, C_NONE, C_ZREG, C_NONE, 18, 4, 0, 0, 0},
522 {AFCSELD, C_COND, C_FREG, C_FREG, C_FREG, C_NONE, 18, 4, 0, 0, 0},
523 {ACCMN, C_COND, C_ZREG, C_ZREG, C_VCON, C_NONE, 19, 4, 0, 0, 0},
524 {ACCMN, C_COND, C_ZREG, C_VCON, C_VCON, C_NONE, 19, 4, 0, 0, 0},
525 {AFCCMPS, C_COND, C_FREG, C_FREG, C_VCON, C_NONE, 57, 4, 0, 0, 0},
526
527
528 {AMOVB, C_ZREG, C_NONE, C_NONE, C_UAUTO4K, C_NONE, 20, 4, REGSP, 0, 0},
529 {AMOVB, C_ZREG, C_NONE, C_NONE, C_UOREG4K, C_NONE, 20, 4, 0, 0, 0},
530 {AMOVH, C_ZREG, C_NONE, C_NONE, C_UAUTO8K, C_NONE, 20, 4, REGSP, 0, 0},
531 {AMOVH, C_ZREG, C_NONE, C_NONE, C_UOREG8K, C_NONE, 20, 4, 0, 0, 0},
532 {AMOVW, C_ZREG, C_NONE, C_NONE, C_UAUTO16K, C_NONE, 20, 4, REGSP, 0, 0},
533 {AMOVW, C_ZREG, C_NONE, C_NONE, C_UOREG16K, C_NONE, 20, 4, 0, 0, 0},
534 {AMOVD, C_ZREG, C_NONE, C_NONE, C_UAUTO32K, C_NONE, 20, 4, REGSP, 0, 0},
535 {AMOVD, C_ZREG, C_NONE, C_NONE, C_UOREG32K, C_NONE, 20, 4, 0, 0, 0},
536
537 {AFMOVS, C_FREG, C_NONE, C_NONE, C_UAUTO16K, C_NONE, 20, 4, REGSP, 0, 0},
538 {AFMOVS, C_FREG, C_NONE, C_NONE, C_UOREG16K, C_NONE, 20, 4, 0, 0, 0},
539 {AFMOVD, C_FREG, C_NONE, C_NONE, C_UAUTO32K, C_NONE, 20, 4, REGSP, 0, 0},
540 {AFMOVD, C_FREG, C_NONE, C_NONE, C_UOREG32K, C_NONE, 20, 4, 0, 0, 0},
541 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_UAUTO64K, C_NONE, 20, 4, REGSP, 0, 0},
542 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_UOREG64K, C_NONE, 20, 4, 0, 0, 0},
543
544
545 {AMOVB, C_ZREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
546 {AMOVB, C_ZREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
547 {AMOVH, C_ZREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
548 {AMOVH, C_ZREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
549 {AMOVW, C_ZREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
550 {AMOVW, C_ZREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
551 {AMOVD, C_ZREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
552 {AMOVD, C_ZREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
553
554 {AFMOVS, C_FREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
555 {AFMOVS, C_FREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
556 {AFMOVD, C_FREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
557 {AFMOVD, C_FREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
558 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
559 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
560
561
562 {AMOVB, C_UAUTO4K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
563 {AMOVB, C_UOREG4K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
564 {AMOVH, C_UAUTO8K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
565 {AMOVH, C_UOREG8K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
566 {AMOVW, C_UAUTO16K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
567 {AMOVW, C_UOREG16K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
568 {AMOVD, C_UAUTO32K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
569 {AMOVD, C_UOREG32K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
570
571 {AFMOVS, C_UAUTO16K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
572 {AFMOVS, C_UOREG16K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
573 {AFMOVD, C_UAUTO32K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
574 {AFMOVD, C_UOREG32K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
575 {AFMOVQ, C_UAUTO64K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
576 {AFMOVQ, C_UOREG64K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
577
578
579 {AMOVB, C_NSAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
580 {AMOVB, C_NSOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
581 {AMOVH, C_NSAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
582 {AMOVH, C_NSOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
583 {AMOVW, C_NSAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
584 {AMOVW, C_NSOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
585 {AMOVD, C_NSAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
586 {AMOVD, C_NSOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
587
588 {AFMOVS, C_NSAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
589 {AFMOVS, C_NSOREG, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
590 {AFMOVD, C_NSAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
591 {AFMOVD, C_NSOREG, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
592 {AFMOVQ, C_NSAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
593 {AFMOVQ, C_NSOREG, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
594
595
596 {AMOVB, C_ZREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
597 {AMOVB, C_ZREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
598 {AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
599 {AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
600 {AMOVH, C_ZREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
601 {AMOVH, C_ZREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
602 {AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
603 {AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
604 {AMOVW, C_ZREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
605 {AMOVW, C_ZREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
606 {AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
607 {AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
608 {AMOVD, C_ZREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
609 {AMOVD, C_ZREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
610 {AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
611 {AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
612
613 {AFMOVS, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
614 {AFMOVS, C_FREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
615 {AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
616 {AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
617 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
618 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
619 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
620 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
621 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
622 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
623 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
624 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
625
626
627 {AMOVB, C_LAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, 0, 0},
628 {AMOVB, C_LAUTOPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, LFROM, 0},
629 {AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, 0, 0},
630 {AMOVB, C_LOREGPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, LFROM, 0},
631 {AMOVH, C_LAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, 0, 0},
632 {AMOVH, C_LAUTOPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, LFROM, 0},
633 {AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, 0, 0},
634 {AMOVH, C_LOREGPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, LFROM, 0},
635 {AMOVW, C_LAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, 0, 0},
636 {AMOVW, C_LAUTOPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, LFROM, 0},
637 {AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, 0, 0},
638 {AMOVW, C_LOREGPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, LFROM, 0},
639 {AMOVD, C_LAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, 0, 0},
640 {AMOVD, C_LAUTOPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, LFROM, 0},
641 {AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, 0, 0},
642 {AMOVD, C_LOREGPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, LFROM, 0},
643
644 {AFMOVS, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, 0, 0},
645 {AFMOVS, C_LAUTOPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, LFROM, 0},
646 {AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, 0, 0},
647 {AFMOVS, C_LOREGPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, LFROM, 0},
648 {AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, 0, 0},
649 {AFMOVD, C_LAUTOPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, LFROM, 0},
650 {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, 0, 0},
651 {AFMOVD, C_LOREGPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, LFROM, 0},
652 {AFMOVQ, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, 0, 0},
653 {AFMOVQ, C_LAUTOPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, LFROM, 0},
654 {AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, 0, 0},
655 {AFMOVQ, C_LOREGPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, LFROM, 0},
656
657
658 {AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPOST},
659 {AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPOST},
660 {AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPOST},
661 {AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPOST},
662 {AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPOST},
663 {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPOST},
664 {AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPOST},
665
666 {AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPRE},
667 {AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPRE},
668 {AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPRE},
669 {AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPRE},
670 {AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPRE},
671 {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPRE},
672 {AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPRE},
673
674
675 {AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
676 {AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
677 {AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
678 {AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
679 {AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
680 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
681 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
682
683 {AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
684 {AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
685 {AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
686 {AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
687 {AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
688 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
689 {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
690
691
692 {AMOVD, C_ROFF, C_NONE, C_NONE, C_ZREG, C_NONE, 98, 4, 0, 0, 0},
693 {AMOVW, C_ROFF, C_NONE, C_NONE, C_ZREG, C_NONE, 98, 4, 0, 0, 0},
694 {AMOVH, C_ROFF, C_NONE, C_NONE, C_ZREG, C_NONE, 98, 4, 0, 0, 0},
695 {AMOVB, C_ROFF, C_NONE, C_NONE, C_ZREG, C_NONE, 98, 4, 0, 0, 0},
696 {AFMOVS, C_ROFF, C_NONE, C_NONE, C_FREG, C_NONE, 98, 4, 0, 0, 0},
697 {AFMOVD, C_ROFF, C_NONE, C_NONE, C_FREG, C_NONE, 98, 4, 0, 0, 0},
698
699
700 {AMOVD, C_ZREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
701 {AMOVW, C_ZREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
702 {AMOVH, C_ZREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
703 {AMOVB, C_ZREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
704 {AFMOVS, C_FREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
705 {AFMOVD, C_FREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
706
707
712 {AFLDPQ, C_NQAUTO_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
713 {AFLDPQ, C_PQAUTO_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
714 {AFLDPQ, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
715 {AFLDPQ, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
716 {AFLDPQ, C_LAUTO, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, 0, 0},
717 {AFLDPQ, C_LAUTOPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, LFROM, 0},
718 {AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
719 {AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
720 {AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
721 {AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
722 {AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
723 {AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
724 {AFLDPQ, C_UOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
725 {AFLDPQ, C_NOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
726 {AFLDPQ, C_LOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, 0, 0},
727 {AFLDPQ, C_LOREGPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, LFROM, 0},
728 {AFLDPQ, C_ADDR, C_NONE, C_NONE, C_PAIR, C_NONE, 88, 12, 0, 0, 0},
729
730 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQAUTO_16, C_NONE, 67, 4, REGSP, 0, 0},
731 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQAUTO_16, C_NONE, 67, 4, REGSP, 0, 0},
732 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
733 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
734 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LAUTO, C_NONE, 77, 12, REGSP, 0, 0},
735 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 77, 12, REGSP, LTO, 0},
736 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, C_NONE, 67, 4, 0, 0, 0},
737 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, C_NONE, 67, 4, 0, 0, C_XPRE},
738 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, C_NONE, 67, 4, 0, 0, C_XPOST},
739 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, C_NONE, 67, 4, 0, 0, 0},
740 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, C_NONE, 67, 4, 0, 0, C_XPRE},
741 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, C_NONE, 67, 4, 0, 0, C_XPOST},
742 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_UOREG4K, C_NONE, 76, 8, 0, 0, 0},
743 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NOREG4K, C_NONE, 76, 8, 0, 0, 0},
744 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LOREG, C_NONE, 77, 12, 0, 0, 0},
745 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 77, 12, 0, LTO, 0},
746 {AFSTPQ, C_PAIR, C_NONE, C_NONE, C_ADDR, C_NONE, 87, 12, 0, 0, 0},
747
748 {ALDP, C_NPAUTO, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
749 {ALDP, C_PPAUTO, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
750 {ALDP, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
751 {ALDP, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
752 {ALDP, C_LAUTO, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, 0, 0},
753 {ALDP, C_LAUTOPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, LFROM, 0},
754 {ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
755 {ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
756 {ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
757 {ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
758 {ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
759 {ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
760 {ALDP, C_UOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
761 {ALDP, C_NOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
762 {ALDP, C_LOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, 0, 0},
763 {ALDP, C_LOREGPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, LFROM, 0},
764 {ALDP, C_ADDR, C_NONE, C_NONE, C_PAIR, C_NONE, 88, 12, 0, 0, 0},
765
766 {ASTP, C_PAIR, C_NONE, C_NONE, C_NPAUTO, C_NONE, 67, 4, REGSP, 0, 0},
767 {ASTP, C_PAIR, C_NONE, C_NONE, C_PPAUTO, C_NONE, 67, 4, REGSP, 0, 0},
768 {ASTP, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
769 {ASTP, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
770 {ASTP, C_PAIR, C_NONE, C_NONE, C_LAUTO, C_NONE, 77, 12, REGSP, 0, 0},
771 {ASTP, C_PAIR, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 77, 12, REGSP, LTO, 0},
772 {ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, C_NONE, 67, 4, 0, 0, 0},
773 {ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, C_NONE, 67, 4, 0, 0, C_XPRE},
774 {ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, C_NONE, 67, 4, 0, 0, C_XPOST},
775 {ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, C_NONE, 67, 4, 0, 0, 0},
776 {ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, C_NONE, 67, 4, 0, 0, C_XPRE},
777 {ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, C_NONE, 67, 4, 0, 0, C_XPOST},
778 {ASTP, C_PAIR, C_NONE, C_NONE, C_UOREG4K, C_NONE, 76, 8, 0, 0, 0},
779 {ASTP, C_PAIR, C_NONE, C_NONE, C_NOREG4K, C_NONE, 76, 8, 0, 0, 0},
780 {ASTP, C_PAIR, C_NONE, C_NONE, C_LOREG, C_NONE, 77, 12, 0, 0, 0},
781 {ASTP, C_PAIR, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 77, 12, 0, LTO, 0},
782 {ASTP, C_PAIR, C_NONE, C_NONE, C_ADDR, C_NONE, 87, 12, 0, 0, 0},
783
784
785 {ALDPW, C_NSAUTO_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
786 {ALDPW, C_PSAUTO_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
787 {ALDPW, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
788 {ALDPW, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
789 {ALDPW, C_LAUTO, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, 0, 0},
790 {ALDPW, C_LAUTOPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, LFROM, 0},
791 {ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
792 {ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
793 {ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
794 {ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
795 {ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
796 {ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
797 {ALDPW, C_UOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
798 {ALDPW, C_NOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
799 {ALDPW, C_LOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, 0, 0},
800 {ALDPW, C_LOREGPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, LFROM, 0},
801 {ALDPW, C_ADDR, C_NONE, C_NONE, C_PAIR, C_NONE, 88, 12, 0, 0, 0},
802
803 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NSAUTO_4, C_NONE, 67, 4, REGSP, 0, 0},
804 {ASTPW, C_PAIR, C_NONE, C_NONE, C_PSAUTO_4, C_NONE, 67, 4, REGSP, 0, 0},
805 {ASTPW, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
806 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
807 {ASTPW, C_PAIR, C_NONE, C_NONE, C_LAUTO, C_NONE, 77, 12, REGSP, 0, 0},
808 {ASTPW, C_PAIR, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 77, 12, REGSP, LTO, 0},
809 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, C_NONE, 67, 4, 0, 0, 0},
810 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, C_NONE, 67, 4, 0, 0, C_XPRE},
811 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, C_NONE, 67, 4, 0, 0, C_XPOST},
812 {ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, C_NONE, 67, 4, 0, 0, 0},
813 {ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, C_NONE, 67, 4, 0, 0, C_XPRE},
814 {ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, C_NONE, 67, 4, 0, 0, C_XPOST},
815 {ASTPW, C_PAIR, C_NONE, C_NONE, C_UOREG4K, C_NONE, 76, 8, 0, 0, 0},
816 {ASTPW, C_PAIR, C_NONE, C_NONE, C_NOREG4K, C_NONE, 76, 8, 0, 0, 0},
817 {ASTPW, C_PAIR, C_NONE, C_NONE, C_LOREG, C_NONE, 77, 12, 0, 0, 0},
818 {ASTPW, C_PAIR, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 77, 12, 0, LTO, 0},
819 {ASTPW, C_PAIR, C_NONE, C_NONE, C_ADDR, C_NONE, 87, 12, 0, 0, 0},
820
821 {ASWPD, C_ZREG, C_NONE, C_NONE, C_ZOREG, C_ZREG, 47, 4, 0, 0, 0},
822 {ASWPD, C_ZREG, C_NONE, C_NONE, C_ZAUTO, C_ZREG, 47, 4, REGSP, 0, 0},
823 {ACASPD, C_PAIR, C_NONE, C_NONE, C_ZOREG, C_PAIR, 106, 4, 0, 0, 0},
824 {ACASPD, C_PAIR, C_NONE, C_NONE, C_ZAUTO, C_PAIR, 106, 4, REGSP, 0, 0},
825 {ALDAR, C_ZOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 58, 4, 0, 0, 0},
826 {ALDXR, C_ZOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 58, 4, 0, 0, 0},
827 {ALDAXR, C_ZOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 58, 4, 0, 0, 0},
828 {ALDXP, C_ZOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 58, 4, 0, 0, 0},
829 {ASTLR, C_ZREG, C_NONE, C_NONE, C_ZOREG, C_NONE, 59, 4, 0, 0, 0},
830 {ASTXR, C_ZREG, C_NONE, C_NONE, C_ZOREG, C_ZREG, 59, 4, 0, 0, 0},
831 {ASTLXR, C_ZREG, C_NONE, C_NONE, C_ZOREG, C_ZREG, 59, 4, 0, 0, 0},
832 {ASTXP, C_PAIR, C_NONE, C_NONE, C_ZOREG, C_ZREG, 59, 4, 0, 0, 0},
833
834
835 {AVLD1, C_ZOREG, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, 0},
836 {AVLD1, C_LOREG, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, C_XPOST},
837 {AVLD1, C_ROFF, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, C_XPOST},
838 {AVLD1R, C_ZOREG, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, 0},
839 {AVLD1R, C_LOREG, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, C_XPOST},
840 {AVLD1R, C_ROFF, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, C_XPOST},
841 {AVLD1, C_LOREG, C_NONE, C_NONE, C_ELEM, C_NONE, 97, 4, 0, 0, C_XPOST},
842 {AVLD1, C_ROFF, C_NONE, C_NONE, C_ELEM, C_NONE, 97, 4, 0, 0, C_XPOST},
843 {AVLD1, C_LOREG, C_NONE, C_NONE, C_ELEM, C_NONE, 97, 4, 0, 0, 0},
844 {AVST1, C_LIST, C_NONE, C_NONE, C_ZOREG, C_NONE, 84, 4, 0, 0, 0},
845 {AVST1, C_LIST, C_NONE, C_NONE, C_LOREG, C_NONE, 84, 4, 0, 0, C_XPOST},
846 {AVST1, C_LIST, C_NONE, C_NONE, C_ROFF, C_NONE, 84, 4, 0, 0, C_XPOST},
847 {AVST2, C_LIST, C_NONE, C_NONE, C_ZOREG, C_NONE, 84, 4, 0, 0, 0},
848 {AVST2, C_LIST, C_NONE, C_NONE, C_LOREG, C_NONE, 84, 4, 0, 0, C_XPOST},
849 {AVST2, C_LIST, C_NONE, C_NONE, C_ROFF, C_NONE, 84, 4, 0, 0, C_XPOST},
850 {AVST3, C_LIST, C_NONE, C_NONE, C_ZOREG, C_NONE, 84, 4, 0, 0, 0},
851 {AVST3, C_LIST, C_NONE, C_NONE, C_LOREG, C_NONE, 84, 4, 0, 0, C_XPOST},
852 {AVST3, C_LIST, C_NONE, C_NONE, C_ROFF, C_NONE, 84, 4, 0, 0, C_XPOST},
853 {AVST4, C_LIST, C_NONE, C_NONE, C_ZOREG, C_NONE, 84, 4, 0, 0, 0},
854 {AVST4, C_LIST, C_NONE, C_NONE, C_LOREG, C_NONE, 84, 4, 0, 0, C_XPOST},
855 {AVST4, C_LIST, C_NONE, C_NONE, C_ROFF, C_NONE, 84, 4, 0, 0, C_XPOST},
856 {AVST1, C_ELEM, C_NONE, C_NONE, C_LOREG, C_NONE, 96, 4, 0, 0, C_XPOST},
857 {AVST1, C_ELEM, C_NONE, C_NONE, C_ROFF, C_NONE, 96, 4, 0, 0, C_XPOST},
858 {AVST1, C_ELEM, C_NONE, C_NONE, C_LOREG, C_NONE, 96, 4, 0, 0, 0},
859
860
861 {AMOVD, C_SPR, C_NONE, C_NONE, C_ZREG, C_NONE, 35, 4, 0, 0, 0},
862 {AMRS, C_SPR, C_NONE, C_NONE, C_ZREG, C_NONE, 35, 4, 0, 0, 0},
863 {AMOVD, C_ZREG, C_NONE, C_NONE, C_SPR, C_NONE, 36, 4, 0, 0, 0},
864 {AMSR, C_ZREG, C_NONE, C_NONE, C_SPR, C_NONE, 36, 4, 0, 0, 0},
865 {AMOVD, C_VCON, C_NONE, C_NONE, C_SPR, C_NONE, 37, 4, 0, 0, 0},
866 {AMSR, C_VCON, C_NONE, C_NONE, C_SPR, C_NONE, 37, 4, 0, 0, 0},
867 {AMSR, C_VCON, C_NONE, C_NONE, C_SPOP, C_NONE, 37, 4, 0, 0, 0},
868 {APRFM, C_UOREG32K, C_NONE, C_NONE, C_SPOP, C_NONE, 91, 4, 0, 0, 0},
869 {APRFM, C_UOREG32K, C_NONE, C_NONE, C_LCON, C_NONE, 91, 4, 0, 0, 0},
870 {ADMB, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 51, 4, 0, 0, 0},
871 {AHINT, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 52, 4, 0, 0, 0},
872 {ASYS, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 50, 4, 0, 0, 0},
873 {ASYS, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 50, 4, 0, 0, 0},
874 {ASYSL, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 50, 4, 0, 0, 0},
875 {ATLBI, C_SPOP, C_NONE, C_NONE, C_NONE, C_NONE, 107, 4, 0, 0, 0},
876 {ATLBI, C_SPOP, C_NONE, C_NONE, C_ZREG, C_NONE, 107, 4, 0, 0, 0},
877 {ABTI, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 108, 4, 0, 0, 0},
878 {ABTI, C_SPOP, C_NONE, C_NONE, C_NONE, C_NONE, 108, 4, 0, 0, 0},
879
880
881 {AAESD, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 26, 4, 0, 0, 0},
882 {AAESD, C_ARNG, C_NONE, C_NONE, C_ARNG, C_NONE, 26, 4, 0, 0, 0},
883 {ASHA1C, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 49, 4, 0, 0, 0},
884 {ASHA1C, C_ARNG, C_VREG, C_NONE, C_VREG, C_NONE, 49, 4, 0, 0, 0},
885 {ASHA1SU0, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 63, 4, 0, 0, 0},
886 {AVREV32, C_ARNG, C_NONE, C_NONE, C_ARNG, C_NONE, 83, 4, 0, 0, 0},
887 {AVPMULL, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 93, 4, 0, 0, 0},
888 {AVEOR3, C_ARNG, C_ARNG, C_ARNG, C_ARNG, C_NONE, 103, 4, 0, 0, 0},
889 {AVXAR, C_VCON, C_ARNG, C_ARNG, C_ARNG, C_NONE, 104, 4, 0, 0, 0},
890 {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0},
891 {obj.APCDATA, C_VCON, C_NONE, C_NONE, C_VCON, C_NONE, 0, 0, 0, 0, 0},
892 {obj.AFUNCDATA, C_VCON, C_NONE, C_NONE, C_ADDR, C_NONE, 0, 0, 0, 0, 0},
893 {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
894 {obj.ANOP, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
895 {obj.ANOP, C_ZREG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
896 {obj.ANOP, C_VREG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
897 {obj.APCALIGN, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
898 {obj.APCALIGNMAX, C_LCON, C_NONE, C_NONE, C_LCON, C_NONE, 0, 0, 0, 0, 0},
899 }
900
901
902
903 var pstatefield = []struct {
904 opd SpecialOperand
905 enc uint32
906 }{
907 {SPOP_DAIFSet, 3<<16 | 4<<12 | 6<<5},
908 {SPOP_DAIFClr, 3<<16 | 4<<12 | 7<<5},
909 }
910
911 var prfopfield = map[SpecialOperand]uint32{
912 SPOP_PLDL1KEEP: 0,
913 SPOP_PLDL1STRM: 1,
914 SPOP_PLDL2KEEP: 2,
915 SPOP_PLDL2STRM: 3,
916 SPOP_PLDL3KEEP: 4,
917 SPOP_PLDL3STRM: 5,
918 SPOP_PLIL1KEEP: 8,
919 SPOP_PLIL1STRM: 9,
920 SPOP_PLIL2KEEP: 10,
921 SPOP_PLIL2STRM: 11,
922 SPOP_PLIL3KEEP: 12,
923 SPOP_PLIL3STRM: 13,
924 SPOP_PSTL1KEEP: 16,
925 SPOP_PSTL1STRM: 17,
926 SPOP_PSTL2KEEP: 18,
927 SPOP_PSTL2STRM: 19,
928 SPOP_PSTL3KEEP: 20,
929 SPOP_PSTL3STRM: 21,
930 }
931
932
933
934
935
936
937 var sysInstFields = map[SpecialOperand]struct {
938 op1 uint8
939 cn uint8
940 cm uint8
941 op2 uint8
942 hasOperand2 bool
943 }{
944
945 SPOP_VMALLE1IS: {0, 8, 3, 0, false},
946 SPOP_VAE1IS: {0, 8, 3, 1, true},
947 SPOP_ASIDE1IS: {0, 8, 3, 2, true},
948 SPOP_VAAE1IS: {0, 8, 3, 3, true},
949 SPOP_VALE1IS: {0, 8, 3, 5, true},
950 SPOP_VAALE1IS: {0, 8, 3, 7, true},
951 SPOP_VMALLE1: {0, 8, 7, 0, false},
952 SPOP_VAE1: {0, 8, 7, 1, true},
953 SPOP_ASIDE1: {0, 8, 7, 2, true},
954 SPOP_VAAE1: {0, 8, 7, 3, true},
955 SPOP_VALE1: {0, 8, 7, 5, true},
956 SPOP_VAALE1: {0, 8, 7, 7, true},
957 SPOP_IPAS2E1IS: {4, 8, 0, 1, true},
958 SPOP_IPAS2LE1IS: {4, 8, 0, 5, true},
959 SPOP_ALLE2IS: {4, 8, 3, 0, false},
960 SPOP_VAE2IS: {4, 8, 3, 1, true},
961 SPOP_ALLE1IS: {4, 8, 3, 4, false},
962 SPOP_VALE2IS: {4, 8, 3, 5, true},
963 SPOP_VMALLS12E1IS: {4, 8, 3, 6, false},
964 SPOP_IPAS2E1: {4, 8, 4, 1, true},
965 SPOP_IPAS2LE1: {4, 8, 4, 5, true},
966 SPOP_ALLE2: {4, 8, 7, 0, false},
967 SPOP_VAE2: {4, 8, 7, 1, true},
968 SPOP_ALLE1: {4, 8, 7, 4, false},
969 SPOP_VALE2: {4, 8, 7, 5, true},
970 SPOP_VMALLS12E1: {4, 8, 7, 6, false},
971 SPOP_ALLE3IS: {6, 8, 3, 0, false},
972 SPOP_VAE3IS: {6, 8, 3, 1, true},
973 SPOP_VALE3IS: {6, 8, 3, 5, true},
974 SPOP_ALLE3: {6, 8, 7, 0, false},
975 SPOP_VAE3: {6, 8, 7, 1, true},
976 SPOP_VALE3: {6, 8, 7, 5, true},
977 SPOP_VMALLE1OS: {0, 8, 1, 0, false},
978 SPOP_VAE1OS: {0, 8, 1, 1, true},
979 SPOP_ASIDE1OS: {0, 8, 1, 2, true},
980 SPOP_VAAE1OS: {0, 8, 1, 3, true},
981 SPOP_VALE1OS: {0, 8, 1, 5, true},
982 SPOP_VAALE1OS: {0, 8, 1, 7, true},
983 SPOP_RVAE1IS: {0, 8, 2, 1, true},
984 SPOP_RVAAE1IS: {0, 8, 2, 3, true},
985 SPOP_RVALE1IS: {0, 8, 2, 5, true},
986 SPOP_RVAALE1IS: {0, 8, 2, 7, true},
987 SPOP_RVAE1OS: {0, 8, 5, 1, true},
988 SPOP_RVAAE1OS: {0, 8, 5, 3, true},
989 SPOP_RVALE1OS: {0, 8, 5, 5, true},
990 SPOP_RVAALE1OS: {0, 8, 5, 7, true},
991 SPOP_RVAE1: {0, 8, 6, 1, true},
992 SPOP_RVAAE1: {0, 8, 6, 3, true},
993 SPOP_RVALE1: {0, 8, 6, 5, true},
994 SPOP_RVAALE1: {0, 8, 6, 7, true},
995 SPOP_RIPAS2E1IS: {4, 8, 0, 2, true},
996 SPOP_RIPAS2LE1IS: {4, 8, 0, 6, true},
997 SPOP_ALLE2OS: {4, 8, 1, 0, false},
998 SPOP_VAE2OS: {4, 8, 1, 1, true},
999 SPOP_ALLE1OS: {4, 8, 1, 4, false},
1000 SPOP_VALE2OS: {4, 8, 1, 5, true},
1001 SPOP_VMALLS12E1OS: {4, 8, 1, 6, false},
1002 SPOP_RVAE2IS: {4, 8, 2, 1, true},
1003 SPOP_RVALE2IS: {4, 8, 2, 5, true},
1004 SPOP_IPAS2E1OS: {4, 8, 4, 0, true},
1005 SPOP_RIPAS2E1: {4, 8, 4, 2, true},
1006 SPOP_RIPAS2E1OS: {4, 8, 4, 3, true},
1007 SPOP_IPAS2LE1OS: {4, 8, 4, 4, true},
1008 SPOP_RIPAS2LE1: {4, 8, 4, 6, true},
1009 SPOP_RIPAS2LE1OS: {4, 8, 4, 7, true},
1010 SPOP_RVAE2OS: {4, 8, 5, 1, true},
1011 SPOP_RVALE2OS: {4, 8, 5, 5, true},
1012 SPOP_RVAE2: {4, 8, 6, 1, true},
1013 SPOP_RVALE2: {4, 8, 6, 5, true},
1014 SPOP_ALLE3OS: {6, 8, 1, 0, false},
1015 SPOP_VAE3OS: {6, 8, 1, 1, true},
1016 SPOP_VALE3OS: {6, 8, 1, 5, true},
1017 SPOP_RVAE3IS: {6, 8, 2, 1, true},
1018 SPOP_RVALE3IS: {6, 8, 2, 5, true},
1019 SPOP_RVAE3OS: {6, 8, 5, 1, true},
1020 SPOP_RVALE3OS: {6, 8, 5, 5, true},
1021 SPOP_RVAE3: {6, 8, 6, 1, true},
1022 SPOP_RVALE3: {6, 8, 6, 5, true},
1023
1024 SPOP_IVAC: {0, 7, 6, 1, true},
1025 SPOP_ISW: {0, 7, 6, 2, true},
1026 SPOP_CSW: {0, 7, 10, 2, true},
1027 SPOP_CISW: {0, 7, 14, 2, true},
1028 SPOP_ZVA: {3, 7, 4, 1, true},
1029 SPOP_CVAC: {3, 7, 10, 1, true},
1030 SPOP_CVAU: {3, 7, 11, 1, true},
1031 SPOP_CIVAC: {3, 7, 14, 1, true},
1032 SPOP_IGVAC: {0, 7, 6, 3, true},
1033 SPOP_IGSW: {0, 7, 6, 4, true},
1034 SPOP_IGDVAC: {0, 7, 6, 5, true},
1035 SPOP_IGDSW: {0, 7, 6, 6, true},
1036 SPOP_CGSW: {0, 7, 10, 4, true},
1037 SPOP_CGDSW: {0, 7, 10, 6, true},
1038 SPOP_CIGSW: {0, 7, 14, 4, true},
1039 SPOP_CIGDSW: {0, 7, 14, 6, true},
1040 SPOP_GVA: {3, 7, 4, 3, true},
1041 SPOP_GZVA: {3, 7, 4, 4, true},
1042 SPOP_CGVAC: {3, 7, 10, 3, true},
1043 SPOP_CGDVAC: {3, 7, 10, 5, true},
1044 SPOP_CGVAP: {3, 7, 12, 3, true},
1045 SPOP_CGDVAP: {3, 7, 12, 5, true},
1046 SPOP_CGVADP: {3, 7, 13, 3, true},
1047 SPOP_CGDVADP: {3, 7, 13, 5, true},
1048 SPOP_CIGVAC: {3, 7, 14, 3, true},
1049 SPOP_CIGDVAC: {3, 7, 14, 5, true},
1050 SPOP_CVAP: {3, 7, 12, 1, true},
1051 SPOP_CVADP: {3, 7, 13, 1, true},
1052 }
1053
1054
1055 const OP_NOOP = 0xd503201f
1056
1057
1058
1059
1060
1061 func (o *Optab) size(ctxt *obj.Link, p *obj.Prog) int {
1062
1063 sz := movesize(p.As)
1064 if sz != -1 {
1065
1066
1067
1068
1069
1070
1071
1072
1073 align := int64(1 << sz)
1074 if o.a1 == C_ADDR && p.From.Offset%align == 0 && symAlign(p.From.Sym) >= align ||
1075 o.a4 == C_ADDR && p.To.Offset%align == 0 && symAlign(p.To.Sym) >= align {
1076 return 8
1077 }
1078 }
1079 return int(o.size_)
1080 }
1081
1082
1083
1084 func symAlign(s *obj.LSym) int64 {
1085 name := s.Name
1086 switch {
1087 case strings.HasPrefix(name, "go:string."),
1088 strings.HasPrefix(name, "type:.namedata."),
1089 strings.HasPrefix(name, "type:.importpath."),
1090 strings.HasSuffix(name, ".opendefer"),
1091 strings.HasSuffix(name, ".arginfo0"),
1092 strings.HasSuffix(name, ".arginfo1"),
1093 strings.HasSuffix(name, ".argliveinfo"):
1094
1095 return 1
1096 case strings.HasPrefix(name, "gclocals·"):
1097
1098 return 4
1099 default:
1100 switch {
1101 case s.Size%8 == 0:
1102 return 8
1103 case s.Size%4 == 0:
1104 return 4
1105 case s.Size%2 == 0:
1106 return 2
1107 }
1108 }
1109 return 1
1110 }
1111
1112 func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
1113 if ctxt.Retpoline {
1114 ctxt.Diag("-spectre=ret not supported on arm64")
1115 ctxt.Retpoline = false
1116 }
1117
1118 p := cursym.Func().Text
1119 if p == nil || p.Link == nil {
1120 return
1121 }
1122
1123 if oprange[AAND&obj.AMask] == nil {
1124 ctxt.Diag("arm64 ops not initialized, call arm64.buildop first")
1125 }
1126
1127 c := ctxt7{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset & 0xffffffff), extrasize: int32(p.To.Offset >> 32)}
1128 p.To.Offset &= 0xffffffff
1129
1130
1131
1132 pc := int64(0)
1133 p.Pc = pc
1134 for p = p.Link; p != nil; p = p.Link {
1135 p.Pc = pc
1136 c.addLiteralsToPool(p)
1137 pc += int64(c.asmsizeBytes(p))
1138 }
1139
1140
1146 changed := true
1147 for changed {
1148 changed = false
1149 pc = 0
1150 for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
1151 p.Pc = pc
1152 changed = changed || c.fixUpLongBranch(p)
1153 pc += int64(c.asmsizeBytes(p))
1154 }
1155 }
1156
1157
1160 buf := codeBuffer{&c.cursym.P}
1161
1162 for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
1163 c.pc = p.Pc
1164 switch p.As {
1165 case obj.APCALIGN, obj.APCALIGNMAX:
1166 v := obj.AlignmentPaddingLength(int32(p.Pc), p, c.ctxt)
1167 for i := 0; i < v/4; i++ {
1168
1169 buf.emit(OP_NOOP)
1170 }
1171 case obj.ANOP, obj.AFUNCDATA, obj.APCDATA:
1172 continue
1173 default:
1174 var out [6]uint32
1175 count := c.asmout(p, out[:])
1176 buf.emit(out[:count]...)
1177 }
1178 }
1179 buf.finish()
1180 c.cursym.Size = int64(len(c.cursym.P))
1181
1182
1183
1184
1185
1186 obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable)
1187
1188
1189 for _, jt := range cursym.Func().JumpTables {
1190 for i, p := range jt.Targets {
1191
1192
1193
1194 jt.Sym.WriteAddr(ctxt, int64(i)*8, 8, cursym, p.Pc)
1195 }
1196 }
1197 }
1198
1199 type codeBuffer struct {
1200 data *[]byte
1201 }
1202
1203
1204 func (cb *codeBuffer) emit(op ...uint32) {
1205 for _, o := range op {
1206 *cb.data = binary.LittleEndian.AppendUint32(*cb.data, o)
1207 }
1208 }
1209
1210
1211
1212 func (cb *codeBuffer) finish() {
1213 for len(*cb.data)%funcAlign > 0 {
1214 *cb.data = append(*cb.data, 0)
1215 }
1216 }
1217
1218
1219 func (c *ctxt7) asmsizeBytes(p *obj.Prog) int {
1220 switch p.As {
1221 case obj.APCALIGN, obj.APCALIGNMAX:
1222 return obj.AlignmentPadding(int32(p.Pc), p, c.ctxt, c.cursym)
1223 case obj.ANOP, obj.AFUNCDATA, obj.APCDATA:
1224 return 0
1225 default:
1226 o := c.oplook(p)
1227 return o.size(c.ctxt, p)
1228 }
1229 }
1230
1231
1232
1233 func (c *ctxt7) fixUpLongBranch(p *obj.Prog) bool {
1234 var toofar bool
1235
1236 o := c.oplook(p)
1237
1238
1239 if (o.flag&BRANCH14BITS != 0 || o.flag&BRANCH19BITS != 0) && p.To.Target() != nil {
1240 otxt := p.To.Target().Pc - p.Pc
1241 if o.flag&BRANCH14BITS != 0 {
1242 toofar = otxt <= -(1<<15)+10 || otxt >= (1<<15)-10
1243 } else if o.flag&BRANCH19BITS != 0 {
1244 toofar = otxt <= -(1<<20)+10 || otxt >= (1<<20)-10
1245 }
1246 if toofar {
1247 q := c.newprog()
1248 q.Link = p.Link
1249 p.Link = q
1250 q.As = AB
1251 q.To.Type = obj.TYPE_BRANCH
1252 q.To.SetTarget(p.To.Target())
1253 p.To.SetTarget(q)
1254 q = c.newprog()
1255 q.Link = p.Link
1256 p.Link = q
1257 q.As = AB
1258 q.To.Type = obj.TYPE_BRANCH
1259 q.To.SetTarget(q.Link.Link)
1260 }
1261 }
1262
1263 return toofar
1264 }
1265
1266
1267 func (c *ctxt7) addLiteralsToPool(p *obj.Prog) {
1268 o := c.oplook(p)
1269
1270 if o.flag&LFROM != 0 {
1271 c.addpool(p, &p.From)
1272 }
1273 if o.flag<O != 0 {
1274 c.addpool(p, &p.To)
1275 }
1276 if c.blitrl != nil {
1277 c.checkpool(p)
1278 }
1279 }
1280
1281
1282 func (c *ctxt7) isUnsafePoint(p *obj.Prog) bool {
1283
1284
1285 return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP ||
1286 p.From.Type == obj.TYPE_REGREG && p.From.Offset == REGTMP ||
1287 p.To.Type == obj.TYPE_REGREG && p.To.Offset == REGTMP
1288 }
1289
1290
1291
1292 func (c *ctxt7) isRestartable(p *obj.Prog) bool {
1293 if c.isUnsafePoint(p) {
1294 return false
1295 }
1296
1297
1298
1299
1300
1301
1302
1303 o := c.oplook(p)
1304 return o.size(c.ctxt, p) > 4 && o.flag&NOTUSETMP == 0
1305 }
1306
1307
1312 func (c *ctxt7) checkpool(p *obj.Prog) {
1313
1314
1315 if c.pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(c.pool.size)-int64(c.pool.start)+8)) || p.Link == nil {
1316 c.flushpool(p)
1317 }
1318 }
1319
1320 func (c *ctxt7) flushpool(p *obj.Prog) {
1321
1322
1323
1324 if !(p.As == AB || p.As == obj.ARET || p.As == AERET) {
1325 if c.ctxt.Debugvlog {
1326 fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), c.pool.size, c.pool.start)
1327 }
1328 q := c.newprog()
1329 if p.Link == nil {
1330
1331
1332 q.As = obj.AUNDEF
1333 } else {
1334
1335 q.As = AB
1336 q.To.Type = obj.TYPE_BRANCH
1337 q.To.SetTarget(p.Link)
1338 }
1339 q.Link = c.blitrl
1340 q.Pos = p.Pos
1341 c.blitrl = q
1342 }
1343
1344
1345
1346
1347 for q := c.blitrl; q != nil; q = q.Link {
1348 q.Pos = p.Pos
1349 }
1350
1351 c.elitrl.Link = p.Link
1352 p.Link = c.blitrl
1353
1354 c.blitrl = nil
1355 c.elitrl = nil
1356 c.pool.size = 0
1357 c.pool.start = 0
1358 }
1359
1360
1368 func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
1369 cls := c.aclass(a)
1370 lit := c.instoffset
1371 t := c.newprog()
1372 t.As = AWORD
1373 sz := 4
1374
1375 if a.Type == obj.TYPE_CONST {
1376 if lit != int64(int32(lit)) && uint64(lit) != uint64(uint32(lit)) {
1377
1378 t.As = ADWORD
1379 sz = 8
1380 }
1381 } else if p.As == AMOVD && a.Type != obj.TYPE_MEM || cls == C_ADDR || cls == C_VCON || lit != int64(int32(lit)) || uint64(lit) != uint64(uint32(lit)) {
1382
1383
1384 t.As = ADWORD
1385 sz = 8
1386 }
1387
1388 t.To.Type = obj.TYPE_CONST
1389 t.To.Offset = lit
1390
1391 for q := c.blitrl; q != nil; q = q.Link {
1392 if q.To == t.To {
1393 p.Pool = q
1394 return
1395 }
1396 }
1397
1398 if c.blitrl == nil {
1399 c.blitrl = t
1400 c.pool.start = uint32(p.Pc)
1401 } else {
1402 c.elitrl.Link = t
1403 }
1404 c.elitrl = t
1405 if t.As == ADWORD {
1406
1407
1408
1409 c.pool.size = roundUp(c.pool.size, 8)
1410 }
1411 c.pool.size += uint32(sz)
1412 p.Pool = t
1413 }
1414
1415
1416 func roundUp(x, to uint32) uint32 {
1417 if to == 0 || to&(to-1) != 0 {
1418 log.Fatalf("rounded up to a value that is not a power of 2: %d\n", to)
1419 }
1420 return (x + to - 1) &^ (to - 1)
1421 }
1422
1423
1424
1425
1426
1427 func splitImm24uScaled(v int32, shift int) (int32, int32, error) {
1428 if v < 0 {
1429 return 0, 0, fmt.Errorf("%d is not a 24 bit unsigned immediate", v)
1430 }
1431 if v > 0xfff000+0xfff<<shift {
1432 return 0, 0, fmt.Errorf("%d is too large for a scaled 24 bit unsigned immediate", v)
1433 }
1434 if v&((1<<shift)-1) != 0 {
1435 return 0, 0, fmt.Errorf("%d is not a multiple of %d", v, 1<<shift)
1436 }
1437 lo := (v >> shift) & 0xfff
1438 hi := v - (lo << shift)
1439 if hi > 0xfff000 {
1440 hi = 0xfff000
1441 lo = (v - hi) >> shift
1442 }
1443 if hi & ^0xfff000 != 0 {
1444 panic(fmt.Sprintf("bad split for %x with shift %v (%x, %x)", v, shift, hi, lo))
1445 }
1446 return hi, lo, nil
1447 }
1448
1449 func (c *ctxt7) regoff(a *obj.Addr) int32 {
1450 c.instoffset = 0
1451 c.aclass(a)
1452 return int32(c.instoffset)
1453 }
1454
1455 func isSTLXRop(op obj.As) bool {
1456 switch op {
1457 case ASTLXR, ASTLXRW, ASTLXRB, ASTLXRH,
1458 ASTXR, ASTXRW, ASTXRB, ASTXRH:
1459 return true
1460 }
1461 return false
1462 }
1463
1464 func isSTXPop(op obj.As) bool {
1465 switch op {
1466 case ASTXP, ASTLXP, ASTXPW, ASTLXPW:
1467 return true
1468 }
1469 return false
1470 }
1471
1472 func isANDop(op obj.As) bool {
1473 switch op {
1474 case AAND, AORR, AEOR, AANDS, ATST,
1475 ABIC, AEON, AORN, ABICS:
1476 return true
1477 }
1478 return false
1479 }
1480
1481 func isANDWop(op obj.As) bool {
1482 switch op {
1483 case AANDW, AORRW, AEORW, AANDSW, ATSTW,
1484 ABICW, AEONW, AORNW, ABICSW:
1485 return true
1486 }
1487 return false
1488 }
1489
1490 func isADDop(op obj.As) bool {
1491 switch op {
1492 case AADD, AADDS, ASUB, ASUBS, ACMN, ACMP:
1493 return true
1494 }
1495 return false
1496 }
1497
1498 func isADDWop(op obj.As) bool {
1499 switch op {
1500 case AADDW, AADDSW, ASUBW, ASUBSW, ACMNW, ACMPW:
1501 return true
1502 }
1503 return false
1504 }
1505
1506 func isADDSop(op obj.As) bool {
1507 switch op {
1508 case AADDS, AADDSW, ASUBS, ASUBSW:
1509 return true
1510 }
1511 return false
1512 }
1513
1514 func isNEGop(op obj.As) bool {
1515 switch op {
1516 case ANEG, ANEGW, ANEGS, ANEGSW:
1517 return true
1518 }
1519 return false
1520 }
1521
1522 func isLoadStorePairOp(op obj.As) bool {
1523 switch op {
1524 case AFLDPQ, AFSTPQ, ALDP, ASTP, ALDPW, ASTPW:
1525 return true
1526 }
1527 return false
1528 }
1529
1530 func isMOVop(op obj.As) bool {
1531 switch op {
1532 case AMOVB, AMOVBU, AMOVH, AMOVHU, AMOVW, AMOVWU, AMOVD, AFMOVS, AFMOVD, AFMOVQ:
1533 return true
1534 }
1535 return false
1536 }
1537
1538 func isRegShiftOrExt(a *obj.Addr) bool {
1539 return (a.Index-obj.RBaseARM64)®_EXT != 0 || (a.Index-obj.RBaseARM64)®_LSL != 0
1540 }
1541
1542
1543
1544
1545
1546 const maxPCDisp = 512 * 1024
1547
1548
1549 func ispcdisp(v int32) bool {
1550 return -maxPCDisp < v && v < maxPCDisp && v&3 == 0
1551 }
1552
1553 func isaddcon(v int64) bool {
1554
1555 if v < 0 {
1556 return false
1557 }
1558 if (v & 0xFFF) == 0 {
1559 v >>= 12
1560 }
1561 return v <= 0xFFF
1562 }
1563
1564 func isaddcon2(v int64) bool {
1565 return 0 <= v && v <= 0xFFFFFF
1566 }
1567
1568
1569
1570
1571
1572
1573
1574 func isbitcon(x uint64) bool {
1575 if x == 1<<64-1 || x == 0 {
1576 return false
1577 }
1578
1579 switch {
1580 case x != x>>32|x<<32:
1581
1582
1583 case x != x>>16|x<<48:
1584
1585 x = uint64(int64(int32(x)))
1586 case x != x>>8|x<<56:
1587
1588 x = uint64(int64(int16(x)))
1589 case x != x>>4|x<<60:
1590
1591 x = uint64(int64(int8(x)))
1592 default:
1593
1594
1595
1596
1597
1598 return true
1599 }
1600 return sequenceOfOnes(x) || sequenceOfOnes(^x)
1601 }
1602
1603
1604 func sequenceOfOnes(x uint64) bool {
1605 y := x & -x
1606 y += x
1607 return (y-1)&y == 0
1608 }
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623 func bitconEncode(x uint64, mode int) uint32 {
1624 if mode == 32 {
1625 x &= 0xffffffff
1626 x = x<<32 | x
1627 }
1628 var period uint32
1629
1630 switch {
1631 case x != x>>32|x<<32:
1632 period = 64
1633 case x != x>>16|x<<48:
1634 period = 32
1635 x = uint64(int64(int32(x)))
1636 case x != x>>8|x<<56:
1637 period = 16
1638 x = uint64(int64(int16(x)))
1639 case x != x>>4|x<<60:
1640 period = 8
1641 x = uint64(int64(int8(x)))
1642 case x != x>>2|x<<62:
1643 period = 4
1644 x = uint64(int64(x<<60) >> 60)
1645 default:
1646 period = 2
1647 x = uint64(int64(x<<62) >> 62)
1648 }
1649 neg := false
1650 if int64(x) < 0 {
1651 x = ^x
1652 neg = true
1653 }
1654 y := x & -x
1655 s := log2(y)
1656 n := log2(x+y) - s
1657 if neg {
1658
1659
1660 s = n + s
1661 n = period - n
1662 }
1663
1664 N := uint32(0)
1665 if mode == 64 && period == 64 {
1666 N = 1
1667 }
1668 R := (period - s) & (period - 1) & uint32(mode-1)
1669 S := (n - 1) | 63&^(period<<1-1)
1670 return N<<22 | R<<16 | S<<10
1671 }
1672
1673 func log2(x uint64) uint32 {
1674 if x == 0 {
1675 panic("log2 of 0")
1676 }
1677 n := uint32(0)
1678 if x >= 1<<32 {
1679 x >>= 32
1680 n += 32
1681 }
1682 if x >= 1<<16 {
1683 x >>= 16
1684 n += 16
1685 }
1686 if x >= 1<<8 {
1687 x >>= 8
1688 n += 8
1689 }
1690 if x >= 1<<4 {
1691 x >>= 4
1692 n += 4
1693 }
1694 if x >= 1<<2 {
1695 x >>= 2
1696 n += 2
1697 }
1698 if x >= 1<<1 {
1699 x >>= 1
1700 n += 1
1701 }
1702 return n
1703 }
1704
1705 func autoclass(l int64) int {
1706 if l == 0 {
1707 return C_ZAUTO
1708 }
1709
1710 if l < 0 {
1711 if l >= -256 && (l&15) == 0 {
1712 return C_NSAUTO_16
1713 }
1714 if l >= -256 && (l&7) == 0 {
1715 return C_NSAUTO_8
1716 }
1717 if l >= -256 && (l&3) == 0 {
1718 return C_NSAUTO_4
1719 }
1720 if l >= -256 {
1721 return C_NSAUTO
1722 }
1723 if l >= -512 && (l&15) == 0 {
1724 return C_NPAUTO_16
1725 }
1726 if l >= -512 && (l&7) == 0 {
1727 return C_NPAUTO
1728 }
1729 if l >= -1024 && (l&15) == 0 {
1730 return C_NQAUTO_16
1731 }
1732 if l >= -4095 {
1733 return C_NAUTO4K
1734 }
1735 return C_LAUTO
1736 }
1737
1738 if l <= 255 {
1739 if (l & 15) == 0 {
1740 return C_PSAUTO_16
1741 }
1742 if (l & 7) == 0 {
1743 return C_PSAUTO_8
1744 }
1745 if (l & 3) == 0 {
1746 return C_PSAUTO_4
1747 }
1748 return C_PSAUTO
1749 }
1750 if l <= 504 {
1751 if l&15 == 0 {
1752 return C_PPAUTO_16
1753 }
1754 if l&7 == 0 {
1755 return C_PPAUTO
1756 }
1757 }
1758 if l <= 1008 {
1759 if l&15 == 0 {
1760 return C_PQAUTO_16
1761 }
1762 }
1763 if l <= 4095 {
1764 if l&15 == 0 {
1765 return C_UAUTO4K_16
1766 }
1767 if l&7 == 0 {
1768 return C_UAUTO4K_8
1769 }
1770 if l&3 == 0 {
1771 return C_UAUTO4K_4
1772 }
1773 if l&1 == 0 {
1774 return C_UAUTO4K_2
1775 }
1776 return C_UAUTO4K
1777 }
1778 if l <= 8190 {
1779 if l&15 == 0 {
1780 return C_UAUTO8K_16
1781 }
1782 if l&7 == 0 {
1783 return C_UAUTO8K_8
1784 }
1785 if l&3 == 0 {
1786 return C_UAUTO8K_4
1787 }
1788 if l&1 == 0 {
1789 return C_UAUTO8K
1790 }
1791 }
1792 if l <= 16380 {
1793 if l&15 == 0 {
1794 return C_UAUTO16K_16
1795 }
1796 if l&7 == 0 {
1797 return C_UAUTO16K_8
1798 }
1799 if l&3 == 0 {
1800 return C_UAUTO16K
1801 }
1802 }
1803 if l <= 32760 {
1804 if l&15 == 0 {
1805 return C_UAUTO32K_16
1806 }
1807 if l&7 == 0 {
1808 return C_UAUTO32K
1809 }
1810 }
1811 if l <= 65520 && (l&15) == 0 {
1812 return C_UAUTO64K
1813 }
1814 return C_LAUTO
1815 }
1816
1817 func oregclass(l int64) int {
1818 return autoclass(l) - C_ZAUTO + C_ZOREG
1819 }
1820
1821
1826 func (c *ctxt7) offsetshift(p *obj.Prog, v int64, cls int) int64 {
1827 s := 0
1828 if cls >= C_SEXT1 && cls <= C_SEXT16 {
1829 s = cls - C_SEXT1
1830 } else {
1831 switch cls {
1832 case C_UAUTO4K, C_UOREG4K, C_ZOREG:
1833 s = 0
1834 case C_UAUTO8K, C_UOREG8K:
1835 s = 1
1836 case C_UAUTO16K, C_UOREG16K:
1837 s = 2
1838 case C_UAUTO32K, C_UOREG32K:
1839 s = 3
1840 case C_UAUTO64K, C_UOREG64K:
1841 s = 4
1842 default:
1843 c.ctxt.Diag("bad class: %v\n%v", DRconv(cls), p)
1844 }
1845 }
1846 vs := v >> uint(s)
1847 if vs<<uint(s) != v {
1848 c.ctxt.Diag("odd offset: %d\n%v", v, p)
1849 }
1850 return vs
1851 }
1852
1853
1854
1855
1856
1857 func movcon(v int64) int {
1858 for s := 0; s < 64; s += 16 {
1859 if (uint64(v) &^ (uint64(0xFFFF) << uint(s))) == 0 {
1860 return s
1861 }
1862 }
1863 return -1
1864 }
1865
1866 func rclass(r int16) int {
1867 switch {
1868 case REG_R0 <= r && r <= REG_R30:
1869 return C_REG
1870 case r == REGZERO:
1871 return C_ZREG
1872 case REG_F0 <= r && r <= REG_F31:
1873 return C_FREG
1874 case REG_V0 <= r && r <= REG_V31:
1875 return C_VREG
1876 case r == REGSP:
1877 return C_RSP
1878 case r >= REG_ARNG && r < REG_ELEM:
1879 return C_ARNG
1880 case r >= REG_ELEM && r < REG_ELEM_END:
1881 return C_ELEM
1882 case r >= REG_UXTB && r < REG_SPECIAL,
1883 r >= REG_LSL && r < REG_ARNG:
1884 return C_EXTREG
1885 case r >= REG_SPECIAL:
1886 return C_SPR
1887 }
1888 return C_GOK
1889 }
1890
1891
1892 func conclass(v int64, mode int) int {
1893
1894
1895
1896
1897 vbitcon := uint64(v)
1898 if mode == 32 {
1899 vbitcon = uint64(v)<<32 | uint64(v)
1900 }
1901
1902 vnotcon := ^v
1903 if mode == 32 {
1904 vnotcon = int64(uint32(vnotcon))
1905 }
1906
1907 if v == 0 {
1908 return C_ZCON
1909 }
1910 if isaddcon(v) {
1911 if v <= 0xFFF {
1912 if isbitcon(vbitcon) {
1913 return C_ABCON0
1914 }
1915 return C_ADDCON0
1916 }
1917 if isbitcon(vbitcon) {
1918 return C_ABCON
1919 }
1920 if movcon(v) >= 0 {
1921 return C_AMCON
1922 }
1923 if movcon(vnotcon) >= 0 {
1924 return C_AMCON
1925 }
1926 return C_ADDCON
1927 }
1928
1929 if t := movcon(v); t >= 0 {
1930 if isbitcon(vbitcon) {
1931 return C_MBCON
1932 }
1933 return C_MOVCON
1934 }
1935 if t := movcon(vnotcon); t >= 0 {
1936 if isbitcon(vbitcon) {
1937 return C_MBCON
1938 }
1939 return C_MOVCON
1940 }
1941
1942 if isbitcon(vbitcon) {
1943 return C_BITCON
1944 }
1945
1946 if isaddcon2(v) {
1947 return C_ADDCON2
1948 }
1949
1950 if uint64(v) == uint64(uint32(v)) || v == int64(int32(v)) {
1951 return C_LCON
1952 }
1953
1954 return C_VCON
1955 }
1956
1957
1958
1959
1960 func (c *ctxt7) con32class(a *obj.Addr) int {
1961 return conclass(int64(uint32(a.Offset)), 32)
1962 }
1963
1964
1965 func (c *ctxt7) con64class(a *obj.Addr) int {
1966 zeroCount := 0
1967 negCount := 0
1968 for i := uint(0); i < 4; i++ {
1969 immh := uint32(a.Offset >> (i * 16) & 0xffff)
1970 if immh == 0 {
1971 zeroCount++
1972 } else if immh == 0xffff {
1973 negCount++
1974 }
1975 }
1976 if zeroCount >= 3 || negCount >= 3 {
1977 return C_MOVCON
1978 } else if zeroCount == 2 || negCount == 2 {
1979 return C_MOVCON2
1980 }
1981
1982 for i := 0; i < 4; i++ {
1983 mask := uint64(0xffff) << (i * 16)
1984 for period := 2; period <= 32; period *= 2 {
1985 x := uint64(a.Offset)&^mask | bits.RotateLeft64(uint64(a.Offset), max(period, 16))&mask
1986 if isbitcon(x) {
1987 return C_MOVCON2
1988 }
1989 }
1990 }
1991 if zeroCount == 1 || negCount == 1 {
1992 return C_MOVCON3
1993 } else {
1994 return C_VCON
1995 }
1996 }
1997
1998
1999 func (c *ctxt7) loadStoreClass(p *obj.Prog, lsc int, v int64) int {
2000
2001 if p.Scond == C_XPRE || p.Scond == C_XPOST {
2002 return lsc
2003 }
2004 if cmp(C_NSAUTO, lsc) || cmp(C_NSOREG, lsc) {
2005 return lsc
2006 }
2007
2008 needsPool := true
2009 if v >= -4095 && v <= 4095 {
2010 needsPool = false
2011 }
2012
2013 switch p.As {
2014 case AMOVB, AMOVBU:
2015 if cmp(C_UAUTO4K, lsc) || cmp(C_UOREG4K, lsc) {
2016 return lsc
2017 }
2018 if v >= 0 && v <= 0xffffff {
2019 needsPool = false
2020 }
2021 case AMOVH, AMOVHU:
2022 if cmp(C_UAUTO8K, lsc) || cmp(C_UOREG8K, lsc) {
2023 return lsc
2024 }
2025 if v >= 0 && v <= 0xfff000+0xfff<<1 && v&1 == 0 {
2026 needsPool = false
2027 }
2028 case AMOVW, AMOVWU, AFMOVS:
2029 if cmp(C_UAUTO16K, lsc) || cmp(C_UOREG16K, lsc) {
2030 return lsc
2031 }
2032 if v >= 0 && v <= 0xfff000+0xfff<<2 && v&3 == 0 {
2033 needsPool = false
2034 }
2035 case AMOVD, AFMOVD:
2036 if cmp(C_UAUTO32K, lsc) || cmp(C_UOREG32K, lsc) {
2037 return lsc
2038 }
2039 if v >= 0 && v <= 0xfff000+0xfff<<3 && v&7 == 0 {
2040 needsPool = false
2041 }
2042 case AFMOVQ:
2043 if cmp(C_UAUTO64K, lsc) || cmp(C_UOREG64K, lsc) {
2044 return lsc
2045 }
2046 if v >= 0 && v <= 0xfff000+0xfff<<4 && v&15 == 0 {
2047 needsPool = false
2048 }
2049 }
2050 if needsPool && cmp(C_LAUTO, lsc) {
2051 return C_LAUTOPOOL
2052 }
2053 if needsPool && cmp(C_LOREG, lsc) {
2054 return C_LOREGPOOL
2055 }
2056 return lsc
2057 }
2058
2059
2060 func (c *ctxt7) loadStorePairClass(p *obj.Prog, lsc int, v int64) int {
2061
2062 if p.Scond == C_XPRE || p.Scond == C_XPOST {
2063 return lsc
2064 }
2065
2066 if cmp(C_NAUTO4K, lsc) || cmp(C_NOREG4K, lsc) {
2067 return lsc
2068 }
2069 if cmp(C_UAUTO4K, lsc) || cmp(C_UOREG4K, lsc) {
2070 return lsc
2071 }
2072
2073 needsPool := true
2074 if v >= 0 && v <= 0xffffff {
2075 needsPool = false
2076 }
2077 if needsPool && cmp(C_LAUTO, lsc) {
2078 return C_LAUTOPOOL
2079 }
2080 if needsPool && cmp(C_LOREG, lsc) {
2081 return C_LOREGPOOL
2082 }
2083 return lsc
2084 }
2085
2086 func (c *ctxt7) aclass(a *obj.Addr) int {
2087 switch a.Type {
2088 case obj.TYPE_NONE:
2089 return C_NONE
2090
2091 case obj.TYPE_REG:
2092 return rclass(a.Reg)
2093
2094 case obj.TYPE_REGREG:
2095 return C_PAIR
2096
2097 case obj.TYPE_SHIFT:
2098 return C_SHIFT
2099
2100 case obj.TYPE_REGLIST:
2101 return C_LIST
2102
2103 case obj.TYPE_MEM:
2104
2105 if int16(REG_F0) <= a.Reg && a.Reg <= int16(REG_V31) {
2106 break
2107 }
2108 switch a.Name {
2109 case obj.NAME_EXTERN, obj.NAME_STATIC:
2110 if a.Sym == nil {
2111 break
2112 }
2113 c.instoffset = a.Offset
2114 if a.Sym != nil {
2115 if a.Sym.Type == objabi.STLSBSS {
2116 if c.ctxt.Flag_shared {
2117 return C_TLS_IE
2118 } else {
2119 return C_TLS_LE
2120 }
2121 }
2122 return C_ADDR
2123 }
2124 return C_LEXT
2125
2126 case obj.NAME_GOTREF:
2127 return C_GOTADDR
2128
2129 case obj.NAME_AUTO:
2130 if a.Reg == REGSP {
2131
2132
2133 a.Reg = obj.REG_NONE
2134 }
2135
2136 c.instoffset = int64(c.autosize) + a.Offset - int64(c.extrasize)
2137 return autoclass(c.instoffset)
2138
2139 case obj.NAME_PARAM:
2140 if a.Reg == REGSP {
2141
2142
2143 a.Reg = obj.REG_NONE
2144 }
2145 c.instoffset = int64(c.autosize) + a.Offset + 8
2146 return autoclass(c.instoffset)
2147
2148 case obj.NAME_NONE:
2149 if a.Index != 0 {
2150 if a.Offset != 0 {
2151 if isRegShiftOrExt(a) {
2152
2153 return C_ROFF
2154 }
2155 return C_GOK
2156 }
2157
2158 return C_ROFF
2159 }
2160 c.instoffset = a.Offset
2161 return oregclass(c.instoffset)
2162 }
2163 return C_GOK
2164
2165 case obj.TYPE_FCONST:
2166 return C_FCON
2167
2168 case obj.TYPE_TEXTSIZE:
2169 return C_TEXTSIZE
2170
2171 case obj.TYPE_CONST, obj.TYPE_ADDR:
2172 switch a.Name {
2173 case obj.NAME_NONE:
2174 c.instoffset = a.Offset
2175 if a.Reg != 0 && a.Reg != REGZERO {
2176 break
2177 }
2178 return conclass(c.instoffset, 64)
2179
2180 case obj.NAME_EXTERN, obj.NAME_STATIC:
2181 if a.Sym == nil {
2182 return C_GOK
2183 }
2184 if a.Sym.Type == objabi.STLSBSS {
2185 c.ctxt.Diag("taking address of TLS variable is not supported")
2186 }
2187 c.instoffset = a.Offset
2188 return C_VCONADDR
2189
2190 case obj.NAME_AUTO:
2191 if a.Reg == REGSP {
2192
2193
2194 a.Reg = obj.REG_NONE
2195 }
2196
2197 c.instoffset = int64(c.autosize) + a.Offset - int64(c.extrasize)
2198
2199 case obj.NAME_PARAM:
2200 if a.Reg == REGSP {
2201
2202
2203 a.Reg = obj.REG_NONE
2204 }
2205 c.instoffset = int64(c.autosize) + a.Offset + 8
2206 default:
2207 return C_GOK
2208 }
2209 cf := c.instoffset
2210 if isaddcon(cf) || isaddcon(-cf) {
2211 return C_AACON
2212 }
2213 if isaddcon2(cf) {
2214 return C_AACON2
2215 }
2216
2217 return C_LACON
2218
2219 case obj.TYPE_BRANCH:
2220 return C_SBRA
2221
2222 case obj.TYPE_SPECIAL:
2223 opd := SpecialOperand(a.Offset)
2224 if SPOP_EQ <= opd && opd <= SPOP_NV {
2225 return C_COND
2226 }
2227 return C_SPOP
2228 }
2229 return C_GOK
2230 }
2231
2232 func (c *ctxt7) oplook(p *obj.Prog) *Optab {
2233 a1 := int(p.Optab)
2234 if a1 != 0 {
2235 return &optab[a1-1]
2236 }
2237 a1 = int(p.From.Class)
2238 if a1 == 0 {
2239 a1 = c.aclass(&p.From)
2240
2241 if (p.As == AADDS || p.As == AADDSW || p.As == ASUBS || p.As == ASUBSW) && a1 == C_ADDCON2 {
2242 a1 = C_LCON
2243 }
2244 if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE {
2245 if p.As == AMOVW || isADDWop(p.As) || isANDWop(p.As) {
2246
2247
2248 a1 = c.con32class(&p.From)
2249
2250 if (p.As == AADDSW || p.As == ASUBSW) && a1 == C_ADDCON2 {
2251 a1 = C_LCON
2252 }
2253 }
2254 if ((p.As == AMOVD) || isANDop(p.As) || isADDop(p.As)) && (a1 == C_LCON || a1 == C_VCON) {
2255
2256 a1 = c.con64class(&p.From)
2257 }
2258 }
2259 if p.From.Type == obj.TYPE_MEM {
2260 if isMOVop(p.As) && (cmp(C_LAUTO, a1) || cmp(C_LOREG, a1)) {
2261
2262 a1 = c.loadStoreClass(p, a1, c.instoffset)
2263 }
2264 if isLoadStorePairOp(p.As) && (cmp(C_LAUTO, a1) || cmp(C_LOREG, a1)) {
2265
2266 a1 = c.loadStorePairClass(p, a1, c.instoffset)
2267 }
2268 }
2269 p.From.Class = int8(a1)
2270 }
2271
2272 a2 := C_NONE
2273 if p.Reg != 0 {
2274 a2 = rclass(p.Reg)
2275 }
2276
2277 a3 := C_NONE
2278 if p.GetFrom3() != nil {
2279 a3 = int(p.GetFrom3().Class)
2280 if a3 == 0 {
2281 a3 = c.aclass(p.GetFrom3())
2282 p.GetFrom3().Class = int8(a3)
2283 }
2284 }
2285
2286 a4 := int(p.To.Class)
2287 if a4 == 0 {
2288 a4 = c.aclass(&p.To)
2289 if p.To.Type == obj.TYPE_MEM {
2290 if isMOVop(p.As) && (cmp(C_LAUTO, a4) || cmp(C_LOREG, a4)) {
2291
2292 a4 = c.loadStoreClass(p, a4, c.instoffset)
2293 }
2294 if isLoadStorePairOp(p.As) && (cmp(C_LAUTO, a4) || cmp(C_LOREG, a4)) {
2295
2296 a4 = c.loadStorePairClass(p, a4, c.instoffset)
2297 }
2298 }
2299 p.To.Class = int8(a4)
2300 }
2301
2302 a5 := C_NONE
2303 if p.RegTo2 != 0 {
2304 a5 = rclass(p.RegTo2)
2305 } else if p.GetTo2() != nil {
2306 a5 = int(p.GetTo2().Class)
2307 if a5 == 0 {
2308 a5 = c.aclass(p.GetTo2())
2309 p.GetTo2().Class = int8(a5)
2310 }
2311 }
2312
2313 if false {
2314 fmt.Printf("oplook %v %d %d %d %d %d\n", p.As, a1, a2, a3, a4, a5)
2315 fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type)
2316 }
2317
2318 ops := oprange[p.As&obj.AMask]
2319 c1 := &xcmp[a1]
2320 c2 := &xcmp[a2]
2321 c3 := &xcmp[a3]
2322 c4 := &xcmp[a4]
2323 c5 := &xcmp[a5]
2324 for i := range ops {
2325 op := &ops[i]
2326 if c1[op.a1] && c2[op.a2] && c3[op.a3] && c4[op.a4] && c5[op.a5] && p.Scond == op.scond {
2327 p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
2328 return op
2329 }
2330 }
2331
2332 c.ctxt.Diag("illegal combination: %v %v %v %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4), DRconv(a5), p.From.Type, p.To.Type)
2333
2334 return &Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0}
2335 }
2336
2337 func cmp(a int, b int) bool {
2338 if a == b {
2339 return true
2340 }
2341 switch a {
2342 case C_RSP:
2343 if b == C_REG {
2344 return true
2345 }
2346
2347 case C_ZREG:
2348 if b == C_REG {
2349 return true
2350 }
2351
2352 case C_ADDCON0:
2353 if b == C_ZCON || b == C_ABCON0 {
2354 return true
2355 }
2356
2357 case C_ADDCON:
2358 if b == C_ZCON || b == C_ABCON0 || b == C_ADDCON0 || b == C_ABCON || b == C_AMCON {
2359 return true
2360 }
2361
2362 case C_MBCON:
2363 if b == C_ABCON0 {
2364 return true
2365 }
2366
2367 case C_BITCON:
2368 if b == C_ABCON0 || b == C_ABCON || b == C_MBCON {
2369 return true
2370 }
2371
2372 case C_MOVCON:
2373 if b == C_MBCON || b == C_ZCON || b == C_ADDCON0 || b == C_ABCON0 || b == C_AMCON {
2374 return true
2375 }
2376
2377 case C_ADDCON2:
2378 if b == C_ZCON || b == C_ADDCON || b == C_ADDCON0 {
2379 return true
2380 }
2381
2382 case C_LCON:
2383 if b == C_ZCON || b == C_BITCON || b == C_ADDCON || b == C_ADDCON0 || b == C_ABCON || b == C_ABCON0 || b == C_MBCON || b == C_MOVCON || b == C_ADDCON2 || b == C_AMCON {
2384 return true
2385 }
2386
2387 case C_MOVCON2:
2388 return cmp(C_LCON, b)
2389
2390 case C_VCON:
2391 return cmp(C_LCON, b)
2392
2393 case C_LACON:
2394 if b == C_AACON || b == C_AACON2 {
2395 return true
2396 }
2397
2398 case C_SEXT2:
2399 if b == C_SEXT1 {
2400 return true
2401 }
2402
2403 case C_SEXT4:
2404 if b == C_SEXT1 || b == C_SEXT2 {
2405 return true
2406 }
2407
2408 case C_SEXT8:
2409 if b >= C_SEXT1 && b <= C_SEXT4 {
2410 return true
2411 }
2412
2413 case C_SEXT16:
2414 if b >= C_SEXT1 && b <= C_SEXT8 {
2415 return true
2416 }
2417
2418 case C_LEXT:
2419 if b >= C_SEXT1 && b <= C_SEXT16 {
2420 return true
2421 }
2422
2423 case C_NSAUTO_8:
2424 if b == C_NSAUTO_16 {
2425 return true
2426 }
2427
2428 case C_NSAUTO_4:
2429 if b == C_NSAUTO_16 || b == C_NSAUTO_8 {
2430 return true
2431 }
2432
2433 case C_NSAUTO:
2434 switch b {
2435 case C_NSAUTO_4, C_NSAUTO_8, C_NSAUTO_16:
2436 return true
2437 }
2438
2439 case C_NPAUTO_16:
2440 switch b {
2441 case C_NSAUTO_16:
2442 return true
2443 }
2444
2445 case C_NPAUTO:
2446 switch b {
2447 case C_NSAUTO_16, C_NSAUTO_8, C_NPAUTO_16:
2448 return true
2449 }
2450
2451 case C_NQAUTO_16:
2452 switch b {
2453 case C_NSAUTO_16, C_NPAUTO_16:
2454 return true
2455 }
2456
2457 case C_NAUTO4K:
2458 switch b {
2459 case C_NSAUTO_16, C_NSAUTO_8, C_NSAUTO_4, C_NSAUTO, C_NPAUTO_16,
2460 C_NPAUTO, C_NQAUTO_16:
2461 return true
2462 }
2463
2464 case C_PSAUTO_16:
2465 if b == C_ZAUTO {
2466 return true
2467 }
2468
2469 case C_PSAUTO_8:
2470 if b == C_ZAUTO || b == C_PSAUTO_16 {
2471 return true
2472 }
2473
2474 case C_PSAUTO_4:
2475 switch b {
2476 case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8:
2477 return true
2478 }
2479
2480 case C_PSAUTO:
2481 switch b {
2482 case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8, C_PSAUTO_4:
2483 return true
2484 }
2485
2486 case C_PPAUTO_16:
2487 switch b {
2488 case C_ZAUTO, C_PSAUTO_16:
2489 return true
2490 }
2491
2492 case C_PPAUTO:
2493 switch b {
2494 case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8, C_PPAUTO_16:
2495 return true
2496 }
2497
2498 case C_PQAUTO_16:
2499 switch b {
2500 case C_ZAUTO, C_PSAUTO_16, C_PPAUTO_16:
2501 return true
2502 }
2503
2504 case C_UAUTO4K:
2505 switch b {
2506 case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
2507 C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
2508 C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16:
2509 return true
2510 }
2511
2512 case C_UAUTO8K:
2513 switch b {
2514 case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
2515 C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
2516 C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16,
2517 C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16:
2518 return true
2519 }
2520
2521 case C_UAUTO16K:
2522 switch b {
2523 case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
2524 C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
2525 C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16,
2526 C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16,
2527 C_UAUTO16K_8, C_UAUTO16K_16:
2528 return true
2529 }
2530
2531 case C_UAUTO32K:
2532 switch b {
2533 case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
2534 C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
2535 C_UAUTO4K_8, C_UAUTO4K_16,
2536 C_UAUTO8K_8, C_UAUTO8K_16,
2537 C_UAUTO16K_8, C_UAUTO16K_16,
2538 C_UAUTO32K_16:
2539 return true
2540 }
2541
2542 case C_UAUTO64K:
2543 switch b {
2544 case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
2545 C_PPAUTO_16, C_PQAUTO_16, C_UAUTO4K_16, C_UAUTO8K_16, C_UAUTO16K_16,
2546 C_UAUTO32K_16:
2547 return true
2548 }
2549
2550 case C_LAUTO:
2551 switch b {
2552 case C_ZAUTO, C_NSAUTO, C_NSAUTO_4, C_NSAUTO_8, C_NSAUTO_16, C_NPAUTO_16, C_NPAUTO, C_NQAUTO_16, C_NAUTO4K,
2553 C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
2554 C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
2555 C_UAUTO4K, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16,
2556 C_UAUTO8K, C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16,
2557 C_UAUTO16K, C_UAUTO16K_8, C_UAUTO16K_16,
2558 C_UAUTO32K, C_UAUTO32K_16,
2559 C_UAUTO64K:
2560 return true
2561 }
2562
2563 case C_NSOREG_8:
2564 if b == C_NSOREG_16 {
2565 return true
2566 }
2567
2568 case C_NSOREG_4:
2569 if b == C_NSOREG_8 || b == C_NSOREG_16 {
2570 return true
2571 }
2572
2573 case C_NSOREG:
2574 switch b {
2575 case C_NSOREG_4, C_NSOREG_8, C_NSOREG_16:
2576 return true
2577 }
2578
2579 case C_NPOREG_16:
2580 switch b {
2581 case C_NSOREG_16:
2582 return true
2583 }
2584
2585 case C_NPOREG:
2586 switch b {
2587 case C_NSOREG_16, C_NSOREG_8, C_NPOREG_16:
2588 return true
2589 }
2590
2591 case C_NQOREG_16:
2592 switch b {
2593 case C_NSOREG_16, C_NPOREG_16:
2594 return true
2595 }
2596
2597 case C_NOREG4K:
2598 switch b {
2599 case C_NSOREG_16, C_NSOREG_8, C_NSOREG_4, C_NSOREG, C_NPOREG_16, C_NPOREG, C_NQOREG_16:
2600 return true
2601 }
2602
2603 case C_PSOREG_16:
2604 if b == C_ZOREG {
2605 return true
2606 }
2607
2608 case C_PSOREG_8:
2609 if b == C_ZOREG || b == C_PSOREG_16 {
2610 return true
2611 }
2612
2613 case C_PSOREG_4:
2614 switch b {
2615 case C_ZOREG, C_PSOREG_16, C_PSOREG_8:
2616 return true
2617 }
2618
2619 case C_PSOREG:
2620 switch b {
2621 case C_ZOREG, C_PSOREG_16, C_PSOREG_8, C_PSOREG_4:
2622 return true
2623 }
2624
2625 case C_PPOREG_16:
2626 switch b {
2627 case C_ZOREG, C_PSOREG_16:
2628 return true
2629 }
2630
2631 case C_PPOREG:
2632 switch b {
2633 case C_ZOREG, C_PSOREG_16, C_PSOREG_8, C_PPOREG_16:
2634 return true
2635 }
2636
2637 case C_PQOREG_16:
2638 switch b {
2639 case C_ZOREG, C_PSOREG_16, C_PPOREG_16:
2640 return true
2641 }
2642
2643 case C_UOREG4K:
2644 switch b {
2645 case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
2646 C_PPOREG, C_PPOREG_16, C_PQOREG_16,
2647 C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16:
2648 return true
2649 }
2650
2651 case C_UOREG8K:
2652 switch b {
2653 case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
2654 C_PPOREG, C_PPOREG_16, C_PQOREG_16,
2655 C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16,
2656 C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16:
2657 return true
2658 }
2659
2660 case C_UOREG16K:
2661 switch b {
2662 case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
2663 C_PPOREG, C_PPOREG_16, C_PQOREG_16,
2664 C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16,
2665 C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16,
2666 C_UOREG16K_8, C_UOREG16K_16:
2667 return true
2668 }
2669
2670 case C_UOREG32K:
2671 switch b {
2672 case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
2673 C_PPOREG, C_PPOREG_16, C_PQOREG_16,
2674 C_UOREG4K_8, C_UOREG4K_16,
2675 C_UOREG8K_8, C_UOREG8K_16,
2676 C_UOREG16K_8, C_UOREG16K_16,
2677 C_UOREG32K_16:
2678 return true
2679 }
2680
2681 case C_UOREG64K:
2682 switch b {
2683 case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
2684 C_PPOREG_16, C_PQOREG_16, C_UOREG4K_16, C_UOREG8K_16, C_UOREG16K_16,
2685 C_UOREG32K_16:
2686 return true
2687 }
2688
2689 case C_LOREG:
2690 switch b {
2691 case C_ZOREG, C_NSOREG, C_NSOREG_4, C_NSOREG_8, C_NSOREG_16, C_NPOREG, C_NPOREG_16, C_NQOREG_16, C_NOREG4K,
2692 C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
2693 C_PPOREG, C_PPOREG_16, C_PQOREG_16,
2694 C_UOREG4K, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16,
2695 C_UOREG8K, C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16,
2696 C_UOREG16K, C_UOREG16K_8, C_UOREG16K_16,
2697 C_UOREG32K, C_UOREG32K_16,
2698 C_UOREG64K:
2699 return true
2700 }
2701
2702 case C_LBRA:
2703 if b == C_SBRA {
2704 return true
2705 }
2706 }
2707
2708 return false
2709 }
2710
2711 func ocmp(p1, p2 Optab) int {
2712 if p1.as != p2.as {
2713 return int(p1.as) - int(p2.as)
2714 }
2715 if p1.a1 != p2.a1 {
2716 return int(p1.a1) - int(p2.a1)
2717 }
2718 if p1.a2 != p2.a2 {
2719 return int(p1.a2) - int(p2.a2)
2720 }
2721 if p1.a3 != p2.a3 {
2722 return int(p1.a3) - int(p2.a3)
2723 }
2724 if p1.a4 != p2.a4 {
2725 return int(p1.a4) - int(p2.a4)
2726 }
2727 if p1.scond != p2.scond {
2728 return int(p1.scond) - int(p2.scond)
2729 }
2730 return 0
2731 }
2732
2733 func oprangeset(a obj.As, t []Optab) {
2734 oprange[a&obj.AMask] = t
2735 }
2736
2737 func buildop(ctxt *obj.Link) {
2738 if oprange[AAND&obj.AMask] != nil {
2739
2740
2741
2742 return
2743 }
2744
2745 for i := 0; i < C_GOK; i++ {
2746 for j := 0; j < C_GOK; j++ {
2747 if cmp(j, i) {
2748 xcmp[i][j] = true
2749 }
2750 }
2751 }
2752
2753 slices.SortFunc(optab, ocmp)
2754 for i := 0; i < len(optab); i++ {
2755 as, start := optab[i].as, i
2756 for ; i < len(optab)-1; i++ {
2757 if optab[i+1].as != as {
2758 break
2759 }
2760 }
2761 t := optab[start : i+1]
2762 oprangeset(as, t)
2763 switch as {
2764 default:
2765 ctxt.Diag("unknown op in build: %v", as)
2766 ctxt.DiagFlush()
2767 log.Fatalf("bad code")
2768
2769 case AADD:
2770 oprangeset(AADDS, t)
2771 oprangeset(ASUB, t)
2772 oprangeset(ASUBS, t)
2773 oprangeset(AADDW, t)
2774 oprangeset(AADDSW, t)
2775 oprangeset(ASUBW, t)
2776 oprangeset(ASUBSW, t)
2777
2778 case AAND:
2779 oprangeset(AANDW, t)
2780 oprangeset(AEOR, t)
2781 oprangeset(AEORW, t)
2782 oprangeset(AORR, t)
2783 oprangeset(AORRW, t)
2784 oprangeset(ABIC, t)
2785 oprangeset(ABICW, t)
2786 oprangeset(AEON, t)
2787 oprangeset(AEONW, t)
2788 oprangeset(AORN, t)
2789 oprangeset(AORNW, t)
2790
2791 case AANDS:
2792 oprangeset(AANDSW, t)
2793 oprangeset(ABICS, t)
2794 oprangeset(ABICSW, t)
2795
2796 case ANEG:
2797 oprangeset(ANEGS, t)
2798 oprangeset(ANEGSW, t)
2799 oprangeset(ANEGW, t)
2800
2801 case AADC:
2802 oprangeset(AADCW, t)
2803
2804 oprangeset(AADCS, t)
2805 oprangeset(AADCSW, t)
2806 oprangeset(ASBC, t)
2807 oprangeset(ASBCW, t)
2808 oprangeset(ASBCS, t)
2809 oprangeset(ASBCSW, t)
2810
2811 case ANGC:
2812 oprangeset(ANGCW, t)
2813
2814 oprangeset(ANGCS, t)
2815 oprangeset(ANGCSW, t)
2816
2817 case ACMP:
2818 oprangeset(ACMPW, t)
2819 oprangeset(ACMN, t)
2820 oprangeset(ACMNW, t)
2821
2822 case ATST:
2823 oprangeset(ATSTW, t)
2824
2825
2826 case AMVN:
2827 oprangeset(AMVNW, t)
2828
2829 case AMOVK:
2830 oprangeset(AMOVKW, t)
2831 oprangeset(AMOVN, t)
2832 oprangeset(AMOVNW, t)
2833 oprangeset(AMOVZ, t)
2834 oprangeset(AMOVZW, t)
2835
2836 case ASWPD:
2837 for i := range atomicLDADD {
2838 oprangeset(i, t)
2839 }
2840 for i := range atomicSWP {
2841 if i == ASWPD {
2842 continue
2843 }
2844 oprangeset(i, t)
2845 }
2846
2847 case ACASPD:
2848 oprangeset(ACASPW, t)
2849 case ABEQ:
2850 oprangeset(ABNE, t)
2851 oprangeset(ABCS, t)
2852 oprangeset(ABHS, t)
2853 oprangeset(ABCC, t)
2854 oprangeset(ABLO, t)
2855 oprangeset(ABMI, t)
2856 oprangeset(ABPL, t)
2857 oprangeset(ABVS, t)
2858 oprangeset(ABVC, t)
2859 oprangeset(ABHI, t)
2860 oprangeset(ABLS, t)
2861 oprangeset(ABGE, t)
2862 oprangeset(ABLT, t)
2863 oprangeset(ABGT, t)
2864 oprangeset(ABLE, t)
2865
2866 case ALSL:
2867 oprangeset(ALSLW, t)
2868 oprangeset(ALSR, t)
2869 oprangeset(ALSRW, t)
2870 oprangeset(AASR, t)
2871 oprangeset(AASRW, t)
2872 oprangeset(AROR, t)
2873 oprangeset(ARORW, t)
2874
2875 case ACLS:
2876 oprangeset(ACLSW, t)
2877 oprangeset(ACLZ, t)
2878 oprangeset(ACLZW, t)
2879 oprangeset(ARBIT, t)
2880 oprangeset(ARBITW, t)
2881 oprangeset(AREV, t)
2882 oprangeset(AREVW, t)
2883 oprangeset(AREV16, t)
2884 oprangeset(AREV16W, t)
2885 oprangeset(AREV32, t)
2886
2887 case ASDIV:
2888 oprangeset(ASDIVW, t)
2889 oprangeset(AUDIV, t)
2890 oprangeset(AUDIVW, t)
2891 oprangeset(ACRC32B, t)
2892 oprangeset(ACRC32CB, t)
2893 oprangeset(ACRC32CH, t)
2894 oprangeset(ACRC32CW, t)
2895 oprangeset(ACRC32CX, t)
2896 oprangeset(ACRC32H, t)
2897 oprangeset(ACRC32W, t)
2898 oprangeset(ACRC32X, t)
2899
2900 case AMADD:
2901 oprangeset(AMADDW, t)
2902 oprangeset(AMSUB, t)
2903 oprangeset(AMSUBW, t)
2904 oprangeset(ASMADDL, t)
2905 oprangeset(ASMSUBL, t)
2906 oprangeset(AUMADDL, t)
2907 oprangeset(AUMSUBL, t)
2908
2909 case AREM:
2910 oprangeset(AREMW, t)
2911 oprangeset(AUREM, t)
2912 oprangeset(AUREMW, t)
2913
2914 case AMUL:
2915 oprangeset(AMULW, t)
2916 oprangeset(AMNEG, t)
2917 oprangeset(AMNEGW, t)
2918 oprangeset(ASMNEGL, t)
2919 oprangeset(ASMULL, t)
2920 oprangeset(ASMULH, t)
2921 oprangeset(AUMNEGL, t)
2922 oprangeset(AUMULH, t)
2923 oprangeset(AUMULL, t)
2924
2925 case AMOVB:
2926 oprangeset(AMOVBU, t)
2927
2928 case AMOVH:
2929 oprangeset(AMOVHU, t)
2930
2931 case AMOVW:
2932 oprangeset(AMOVWU, t)
2933
2934 case ABFM:
2935 oprangeset(ABFMW, t)
2936 oprangeset(ASBFM, t)
2937 oprangeset(ASBFMW, t)
2938 oprangeset(AUBFM, t)
2939 oprangeset(AUBFMW, t)
2940
2941 case ABFI:
2942 oprangeset(ABFIW, t)
2943 oprangeset(ABFXIL, t)
2944 oprangeset(ABFXILW, t)
2945 oprangeset(ASBFIZ, t)
2946 oprangeset(ASBFIZW, t)
2947 oprangeset(ASBFX, t)
2948 oprangeset(ASBFXW, t)
2949 oprangeset(AUBFIZ, t)
2950 oprangeset(AUBFIZW, t)
2951 oprangeset(AUBFX, t)
2952 oprangeset(AUBFXW, t)
2953
2954 case AEXTR:
2955 oprangeset(AEXTRW, t)
2956
2957 case ASXTB:
2958 oprangeset(ASXTBW, t)
2959 oprangeset(ASXTH, t)
2960 oprangeset(ASXTHW, t)
2961 oprangeset(ASXTW, t)
2962 oprangeset(AUXTB, t)
2963 oprangeset(AUXTH, t)
2964 oprangeset(AUXTW, t)
2965 oprangeset(AUXTBW, t)
2966 oprangeset(AUXTHW, t)
2967
2968 case ACCMN:
2969 oprangeset(ACCMNW, t)
2970 oprangeset(ACCMP, t)
2971 oprangeset(ACCMPW, t)
2972
2973 case ACSEL:
2974 oprangeset(ACSELW, t)
2975 oprangeset(ACSINC, t)
2976 oprangeset(ACSINCW, t)
2977 oprangeset(ACSINV, t)
2978 oprangeset(ACSINVW, t)
2979 oprangeset(ACSNEG, t)
2980 oprangeset(ACSNEGW, t)
2981
2982 case ACINC:
2983
2984 oprangeset(ACINCW, t)
2985 oprangeset(ACINV, t)
2986 oprangeset(ACINVW, t)
2987 oprangeset(ACNEG, t)
2988 oprangeset(ACNEGW, t)
2989
2990
2991 case ACSET:
2992 oprangeset(ACSETW, t)
2993
2994 oprangeset(ACSETM, t)
2995 oprangeset(ACSETMW, t)
2996
2997 case AMOVD,
2998 AB,
2999 ABL,
3000 AWORD,
3001 ADWORD,
3002 ABTI,
3003 obj.ARET,
3004 obj.ATEXT:
3005 break
3006
3007 case AFLDPQ:
3008 break
3009 case AFSTPQ:
3010 break
3011 case ALDP:
3012 oprangeset(AFLDPD, t)
3013
3014 case ASTP:
3015 oprangeset(AFSTPD, t)
3016
3017 case ASTPW:
3018 oprangeset(AFSTPS, t)
3019
3020 case ALDPW:
3021 oprangeset(ALDPSW, t)
3022 oprangeset(AFLDPS, t)
3023
3024 case AERET:
3025 oprangeset(AWFE, t)
3026 oprangeset(AWFI, t)
3027 oprangeset(AYIELD, t)
3028 oprangeset(ASEV, t)
3029 oprangeset(ASEVL, t)
3030 oprangeset(ANOOP, t)
3031 oprangeset(ADRPS, t)
3032
3033 oprangeset(APACIASP, t)
3034 oprangeset(AAUTIASP, t)
3035 oprangeset(APACIBSP, t)
3036 oprangeset(AAUTIBSP, t)
3037 oprangeset(AAUTIA1716, t)
3038 oprangeset(AAUTIB1716, t)
3039
3040 case ACBZ:
3041 oprangeset(ACBZW, t)
3042 oprangeset(ACBNZ, t)
3043 oprangeset(ACBNZW, t)
3044
3045 case ATBZ:
3046 oprangeset(ATBNZ, t)
3047
3048 case AADR, AADRP:
3049 break
3050
3051 case ACLREX:
3052 break
3053
3054 case ASVC:
3055 oprangeset(AHVC, t)
3056 oprangeset(AHLT, t)
3057 oprangeset(ASMC, t)
3058 oprangeset(ABRK, t)
3059 oprangeset(ADCPS1, t)
3060 oprangeset(ADCPS2, t)
3061 oprangeset(ADCPS3, t)
3062
3063 case AFADDS:
3064 oprangeset(AFADDD, t)
3065 oprangeset(AFSUBS, t)
3066 oprangeset(AFSUBD, t)
3067 oprangeset(AFMULS, t)
3068 oprangeset(AFMULD, t)
3069 oprangeset(AFNMULS, t)
3070 oprangeset(AFNMULD, t)
3071 oprangeset(AFDIVS, t)
3072 oprangeset(AFMAXD, t)
3073 oprangeset(AFMAXS, t)
3074 oprangeset(AFMIND, t)
3075 oprangeset(AFMINS, t)
3076 oprangeset(AFMAXNMD, t)
3077 oprangeset(AFMAXNMS, t)
3078 oprangeset(AFMINNMD, t)
3079 oprangeset(AFMINNMS, t)
3080 oprangeset(AFDIVD, t)
3081
3082 case AFMSUBD:
3083 oprangeset(AFMSUBS, t)
3084 oprangeset(AFMADDS, t)
3085 oprangeset(AFMADDD, t)
3086 oprangeset(AFNMSUBS, t)
3087 oprangeset(AFNMSUBD, t)
3088 oprangeset(AFNMADDS, t)
3089 oprangeset(AFNMADDD, t)
3090
3091 case AFCVTSD:
3092 oprangeset(AFCVTDS, t)
3093 oprangeset(AFABSD, t)
3094 oprangeset(AFABSS, t)
3095 oprangeset(AFNEGD, t)
3096 oprangeset(AFNEGS, t)
3097 oprangeset(AFSQRTD, t)
3098 oprangeset(AFSQRTS, t)
3099 oprangeset(AFRINTNS, t)
3100 oprangeset(AFRINTND, t)
3101 oprangeset(AFRINTPS, t)
3102 oprangeset(AFRINTPD, t)
3103 oprangeset(AFRINTMS, t)
3104 oprangeset(AFRINTMD, t)
3105 oprangeset(AFRINTZS, t)
3106 oprangeset(AFRINTZD, t)
3107 oprangeset(AFRINTAS, t)
3108 oprangeset(AFRINTAD, t)
3109 oprangeset(AFRINTXS, t)
3110 oprangeset(AFRINTXD, t)
3111 oprangeset(AFRINTIS, t)
3112 oprangeset(AFRINTID, t)
3113 oprangeset(AFCVTDH, t)
3114 oprangeset(AFCVTHS, t)
3115 oprangeset(AFCVTHD, t)
3116 oprangeset(AFCVTSH, t)
3117
3118 case AFCMPS:
3119 oprangeset(AFCMPD, t)
3120 oprangeset(AFCMPES, t)
3121 oprangeset(AFCMPED, t)
3122
3123 case AFCCMPS:
3124 oprangeset(AFCCMPD, t)
3125 oprangeset(AFCCMPES, t)
3126 oprangeset(AFCCMPED, t)
3127
3128 case AFCSELD:
3129 oprangeset(AFCSELS, t)
3130
3131 case AFMOVQ, AFMOVD, AFMOVS,
3132 AVMOVQ, AVMOVD, AVMOVS:
3133 break
3134
3135 case AFCVTZSD:
3136 oprangeset(AFCVTZSDW, t)
3137 oprangeset(AFCVTZSS, t)
3138 oprangeset(AFCVTZSSW, t)
3139 oprangeset(AFCVTZUD, t)
3140 oprangeset(AFCVTZUDW, t)
3141 oprangeset(AFCVTZUS, t)
3142 oprangeset(AFCVTZUSW, t)
3143
3144 case ASCVTFD:
3145 oprangeset(ASCVTFS, t)
3146 oprangeset(ASCVTFWD, t)
3147 oprangeset(ASCVTFWS, t)
3148 oprangeset(AUCVTFD, t)
3149 oprangeset(AUCVTFS, t)
3150 oprangeset(AUCVTFWD, t)
3151 oprangeset(AUCVTFWS, t)
3152
3153 case ASYS:
3154 oprangeset(AAT, t)
3155 oprangeset(AIC, t)
3156
3157 case ATLBI:
3158 oprangeset(ADC, t)
3159
3160 case ASYSL, AHINT:
3161 break
3162
3163 case ADMB:
3164 oprangeset(ADSB, t)
3165 oprangeset(AISB, t)
3166
3167 case AMRS, AMSR:
3168 break
3169
3170 case ALDAR:
3171 oprangeset(ALDARW, t)
3172 oprangeset(ALDARB, t)
3173 oprangeset(ALDARH, t)
3174 fallthrough
3175
3176 case ALDXR:
3177 oprangeset(ALDXRB, t)
3178 oprangeset(ALDXRH, t)
3179 oprangeset(ALDXRW, t)
3180
3181 case ALDAXR:
3182 oprangeset(ALDAXRB, t)
3183 oprangeset(ALDAXRH, t)
3184 oprangeset(ALDAXRW, t)
3185
3186 case ALDXP:
3187 oprangeset(ALDXPW, t)
3188 oprangeset(ALDAXP, t)
3189 oprangeset(ALDAXPW, t)
3190
3191 case ASTLR:
3192 oprangeset(ASTLRB, t)
3193 oprangeset(ASTLRH, t)
3194 oprangeset(ASTLRW, t)
3195
3196 case ASTXR:
3197 oprangeset(ASTXRB, t)
3198 oprangeset(ASTXRH, t)
3199 oprangeset(ASTXRW, t)
3200
3201 case ASTLXR:
3202 oprangeset(ASTLXRB, t)
3203 oprangeset(ASTLXRH, t)
3204 oprangeset(ASTLXRW, t)
3205
3206 case ASTXP:
3207 oprangeset(ASTLXP, t)
3208 oprangeset(ASTLXPW, t)
3209 oprangeset(ASTXPW, t)
3210
3211 case AVADDP:
3212 oprangeset(AVAND, t)
3213 oprangeset(AVCMEQ, t)
3214 oprangeset(AVORR, t)
3215 oprangeset(AVEOR, t)
3216 oprangeset(AVBSL, t)
3217 oprangeset(AVBIT, t)
3218 oprangeset(AVCMTST, t)
3219 oprangeset(AVUMAX, t)
3220 oprangeset(AVUMIN, t)
3221 oprangeset(AVUZP1, t)
3222 oprangeset(AVUZP2, t)
3223 oprangeset(AVBIF, t)
3224
3225 case AVADD:
3226 oprangeset(AVSUB, t)
3227 oprangeset(AVRAX1, t)
3228
3229 case AAESD:
3230 oprangeset(AAESE, t)
3231 oprangeset(AAESMC, t)
3232 oprangeset(AAESIMC, t)
3233 oprangeset(ASHA1SU1, t)
3234 oprangeset(ASHA256SU0, t)
3235 oprangeset(ASHA512SU0, t)
3236 oprangeset(ASHA1H, t)
3237
3238 case ASHA1C:
3239 oprangeset(ASHA1P, t)
3240 oprangeset(ASHA1M, t)
3241 oprangeset(ASHA256H, t)
3242 oprangeset(ASHA256H2, t)
3243 oprangeset(ASHA512H, t)
3244 oprangeset(ASHA512H2, t)
3245
3246 case ASHA1SU0:
3247 oprangeset(ASHA256SU1, t)
3248 oprangeset(ASHA512SU1, t)
3249
3250 case AVADDV:
3251 oprangeset(AVUADDLV, t)
3252
3253 case AVFMLA:
3254 oprangeset(AVFMLS, t)
3255
3256 case AVPMULL:
3257 oprangeset(AVPMULL2, t)
3258
3259 case AVUSHR:
3260 oprangeset(AVSHL, t)
3261 oprangeset(AVSRI, t)
3262 oprangeset(AVSLI, t)
3263 oprangeset(AVUSRA, t)
3264
3265 case AVREV32:
3266 oprangeset(AVCNT, t)
3267 oprangeset(AVRBIT, t)
3268 oprangeset(AVREV64, t)
3269 oprangeset(AVREV16, t)
3270
3271 case AVZIP1:
3272 oprangeset(AVZIP2, t)
3273 oprangeset(AVTRN1, t)
3274 oprangeset(AVTRN2, t)
3275
3276 case AVUXTL:
3277 oprangeset(AVUXTL2, t)
3278
3279 case AVUSHLL:
3280 oprangeset(AVUSHLL2, t)
3281
3282 case AVLD1R:
3283 oprangeset(AVLD2, t)
3284 oprangeset(AVLD2R, t)
3285 oprangeset(AVLD3, t)
3286 oprangeset(AVLD3R, t)
3287 oprangeset(AVLD4, t)
3288 oprangeset(AVLD4R, t)
3289
3290 case AVEOR3:
3291 oprangeset(AVBCAX, t)
3292
3293 case AVUADDW:
3294 oprangeset(AVUADDW2, t)
3295
3296 case AVTBL:
3297 oprangeset(AVTBX, t)
3298
3299 case AVCNT,
3300 AVMOV,
3301 AVLD1,
3302 AVST1,
3303 AVST2,
3304 AVST3,
3305 AVST4,
3306 AVDUP,
3307 AVMOVI,
3308 APRFM,
3309 AVEXT,
3310 AVXAR:
3311 break
3312
3313 case obj.ANOP,
3314 obj.AUNDEF,
3315 obj.AFUNCDATA,
3316 obj.APCALIGN,
3317 obj.APCALIGNMAX,
3318 obj.APCDATA:
3319 break
3320 }
3321 }
3322 }
3323
3324
3325
3326
3327 func (c *ctxt7) chipfloat7(e float64) int {
3328 ei := math.Float64bits(e)
3329 l := uint32(int32(ei))
3330 h := uint32(int32(ei >> 32))
3331
3332 if l != 0 || h&0xffff != 0 {
3333 return -1
3334 }
3335 h1 := h & 0x7fc00000
3336 if h1 != 0x40000000 && h1 != 0x3fc00000 {
3337 return -1
3338 }
3339 n := 0
3340
3341
3342 if h&0x80000000 != 0 {
3343 n |= 1 << 7
3344 }
3345
3346
3347 if h1 == 0x3fc00000 {
3348 n |= 1 << 6
3349 }
3350
3351
3352 n |= int((h >> 16) & 0x3f)
3353
3354
3355 return n
3356 }
3357
3358
3359 func SYSARG5(op0 int, op1 int, Cn int, Cm int, op2 int) int {
3360 return op0<<19 | op1<<16 | Cn<<12 | Cm<<8 | op2<<5
3361 }
3362
3363 func SYSARG4(op1 int, Cn int, Cm int, op2 int) int {
3364 return SYSARG5(0, op1, Cn, Cm, op2)
3365 }
3366
3367
3368
3369 func (c *ctxt7) checkUnpredictable(p *obj.Prog, isload bool, wback bool, rn int16, rt1 int16, rt2 int16) {
3370 if wback && rn != REGSP && (rn == rt1 || rn == rt2) {
3371 c.ctxt.Diag("constrained unpredictable behavior: %v", p)
3372 }
3373 if isload && rt1 == rt2 {
3374 c.ctxt.Diag("constrained unpredictable behavior: %v", p)
3375 }
3376 }
3377
3378
3379 func (c *ctxt7) checkindex(p *obj.Prog, index, maxindex int) {
3380 if index < 0 || index > maxindex {
3381 c.ctxt.Diag("register element index out of range 0 to %d: %v", maxindex, p)
3382 }
3383 }
3384
3385
3386 func (c *ctxt7) checkoffset(p *obj.Prog, as obj.As) {
3387 var offset, list, n, expect int64
3388 switch as {
3389 case AVLD1, AVLD2, AVLD3, AVLD4, AVLD1R, AVLD2R, AVLD3R, AVLD4R:
3390 offset = p.From.Offset
3391 list = p.To.Offset
3392 case AVST1, AVST2, AVST3, AVST4:
3393 offset = p.To.Offset
3394 list = p.From.Offset
3395 default:
3396 c.ctxt.Diag("invalid operation on op %v", p.As)
3397 }
3398 opcode := (list >> 12) & 15
3399 q := (list >> 30) & 1
3400 size := (list >> 10) & 3
3401 if offset == 0 {
3402 return
3403 }
3404 switch opcode {
3405 case 0x7:
3406 n = 1
3407 case 0xa:
3408 n = 2
3409 case 0x6:
3410 n = 3
3411 case 0x2:
3412 n = 4
3413 default:
3414 c.ctxt.Diag("invalid register numbers in ARM64 register list: %v", p)
3415 }
3416
3417 switch as {
3418 case AVLD1R, AVLD2R, AVLD3R, AVLD4R:
3419 if offset != n*(1<<uint(size)) {
3420 c.ctxt.Diag("invalid post-increment offset: %v", p)
3421 }
3422 default:
3423 if !(q == 0 && offset == n*8) && !(q == 1 && offset == n*16) {
3424 c.ctxt.Diag("invalid post-increment offset: %v", p)
3425 }
3426 }
3427
3428 switch as {
3429 case AVLD1, AVST1:
3430 return
3431 case AVLD1R:
3432 expect = 1
3433 case AVLD2, AVST2, AVLD2R:
3434 expect = 2
3435 case AVLD3, AVST3, AVLD3R:
3436 expect = 3
3437 case AVLD4, AVST4, AVLD4R:
3438 expect = 4
3439 }
3440
3441 if expect != n {
3442 c.ctxt.Diag("expected %d registers, got %d: %v.", expect, n, p)
3443 }
3444 }
3445
3446
3447
3448 func (c *ctxt7) checkShiftAmount(p *obj.Prog, a *obj.Addr) {
3449 var amount int16
3450 amount = (a.Index >> 5) & 7
3451 switch p.As {
3452 case AMOVB, AMOVBU:
3453 if amount != 0 {
3454 c.ctxt.Diag("invalid index shift amount: %v", p)
3455 }
3456 case AMOVH, AMOVHU:
3457 if amount != 1 && amount != 0 {
3458 c.ctxt.Diag("invalid index shift amount: %v", p)
3459 }
3460 case AMOVW, AMOVWU, AFMOVS:
3461 if amount != 2 && amount != 0 {
3462 c.ctxt.Diag("invalid index shift amount: %v", p)
3463 }
3464 case AMOVD, AFMOVD:
3465 if amount != 3 && amount != 0 {
3466 c.ctxt.Diag("invalid index shift amount: %v", p)
3467 }
3468 default:
3469 panic("invalid operation")
3470 }
3471 }
3472
3473 func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
3474 o := c.oplook(p)
3475
3476 var os [5]uint32
3477 o1 := uint32(0)
3478 o2 := uint32(0)
3479 o3 := uint32(0)
3480 o4 := uint32(0)
3481 o5 := uint32(0)
3482 if false {
3483 fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_)
3484 }
3485 switch o.type_ {
3486 default:
3487 c.ctxt.Diag("%v: unknown asm %d", p, o.type_)
3488
3489 case 0:
3490 break
3491
3492 case 1:
3493 rt, r, rf := p.To.Reg, p.Reg, p.From.Reg
3494 if p.To.Type == obj.TYPE_NONE {
3495 rt = REGZERO
3496 }
3497 if r == obj.REG_NONE {
3498 r = rt
3499 }
3500 o1 = c.oprrr(p, p.As, rt, r, rf)
3501
3502 case 2:
3503 if p.To.Reg == REG_RSP && isADDSop(p.As) {
3504 c.ctxt.Diag("illegal destination register: %v\n", p)
3505 }
3506 o1 = c.opirr(p, p.As)
3507
3508 rt, r := p.To.Reg, p.Reg
3509 if p.To.Type == obj.TYPE_NONE {
3510 if (o1 & Sbit) == 0 {
3511 c.ctxt.Diag("ineffective ZR destination\n%v", p)
3512 }
3513 rt = REGZERO
3514 }
3515 if r == obj.REG_NONE {
3516 r = rt
3517 }
3518 v := c.regoff(&p.From)
3519 o1 = c.oaddi(p, p.As, v, rt, r)
3520
3521 case 3:
3522 rt, r := p.To.Reg, p.Reg
3523 if p.To.Type == obj.TYPE_NONE {
3524 rt = REGZERO
3525 }
3526 if p.As == AMVN || p.As == AMVNW || isNEGop(p.As) {
3527 r = REGZERO
3528 } else if r == obj.REG_NONE {
3529 r = rt
3530 }
3531 o1 = c.oprrr(p, p.As, rt, r, obj.REG_NONE)
3532
3533 amount := (p.From.Offset >> 10) & 63
3534 is64bit := o1 & (1 << 31)
3535 if is64bit == 0 && amount >= 32 {
3536 c.ctxt.Diag("shift amount out of range 0 to 31: %v", p)
3537 }
3538 shift := (p.From.Offset >> 22) & 3
3539 if (shift > 2 || shift < 0) && (isADDop(p.As) || isADDWop(p.As) || isNEGop(p.As)) {
3540 c.ctxt.Diag("unsupported shift operator: %v", p)
3541 }
3542 o1 |= uint32(p.From.Offset)
3543
3544 case 4:
3545 rt, r := p.To.Reg, o.param
3546 if r == obj.REG_NONE {
3547 r = REGZERO
3548 } else if r == REGFROM {
3549 r = p.From.Reg
3550 }
3551 if r == obj.REG_NONE {
3552 r = REGSP
3553 }
3554
3555 v := c.regoff(&p.From)
3556 a := AADD
3557 if v < 0 {
3558 a = ASUB
3559 v = -v
3560 }
3561
3562 if o.size(c.ctxt, p) == 8 {
3563
3564
3565 o1 = c.oaddi(p, a, v&0xfff000, rt, r)
3566 o2 = c.oaddi(p, a, v&0x000fff, rt, rt)
3567 break
3568 }
3569
3570 o1 = c.oaddi(p, a, v, rt, r)
3571
3572 case 5:
3573 o1 = c.opbra(p, p.As)
3574
3575 if p.To.Sym == nil {
3576 o1 |= uint32(c.brdist(p, 0, 26, 2))
3577 break
3578 }
3579
3580 c.cursym.AddRel(c.ctxt, obj.Reloc{
3581 Type: objabi.R_CALLARM64,
3582 Off: int32(c.pc),
3583 Siz: 4,
3584 Sym: p.To.Sym,
3585 Add: p.To.Offset,
3586 })
3587
3588 case 6:
3589 o1 = c.opbrr(p, p.As)
3590 o1 |= uint32(p.To.Reg&31) << 5
3591 if p.As == obj.ACALL {
3592 c.cursym.AddRel(c.ctxt, obj.Reloc{
3593 Type: objabi.R_CALLIND,
3594 Off: int32(c.pc),
3595 })
3596 }
3597
3598 case 7:
3599 o1 = c.opbra(p, p.As)
3600
3601 o1 |= uint32(c.brdist(p, 0, 19, 2) << 5)
3602
3603 case 8:
3604 rt, rf := p.To.Reg, p.Reg
3605 if rf == obj.REG_NONE {
3606 rf = rt
3607 }
3608 v := p.From.Offset
3609 switch p.As {
3610 case AASR:
3611 o1 = c.opbfm(p, ASBFM, v, 63, rf, rt)
3612
3613 case AASRW:
3614 o1 = c.opbfm(p, ASBFMW, v, 31, rf, rt)
3615
3616 case ALSL:
3617 o1 = c.opbfm(p, AUBFM, (64-v)&63, 63-v, rf, rt)
3618
3619 case ALSLW:
3620 o1 = c.opbfm(p, AUBFMW, (32-v)&31, 31-v, rf, rt)
3621
3622 case ALSR:
3623 o1 = c.opbfm(p, AUBFM, v, 63, rf, rt)
3624
3625 case ALSRW:
3626 o1 = c.opbfm(p, AUBFMW, v, 31, rf, rt)
3627
3628 case AROR:
3629 o1 = c.opextr(p, AEXTR, v, rf, rf, rt)
3630
3631 case ARORW:
3632 o1 = c.opextr(p, AEXTRW, v, rf, rf, rt)
3633
3634 default:
3635 c.ctxt.Diag("bad shift $con\n%v", p)
3636 break
3637 }
3638
3639 case 9:
3640 rt, r, rf := p.To.Reg, p.Reg, p.From.Reg
3641 if r == obj.REG_NONE {
3642 r = rt
3643 }
3644 o1 = c.oprrr(p, p.As, rt, r, rf)
3645
3646 case 10:
3647 o1 = c.opimm(p, p.As)
3648
3649 if p.From.Type != obj.TYPE_NONE {
3650 o1 |= uint32((p.From.Offset & 0xffff) << 5)
3651 }
3652
3653 case 11:
3654 c.aclass(&p.To)
3655
3656 o1 = uint32(c.instoffset)
3657 o2 = uint32(c.instoffset >> 32)
3658 if p.To.Sym != nil {
3659 c.cursym.AddRel(c.ctxt, obj.Reloc{
3660 Type: objabi.R_ADDR,
3661 Off: int32(c.pc),
3662 Siz: 8,
3663 Sym: p.To.Sym,
3664 Add: p.To.Offset,
3665 })
3666 o2 = 0
3667 o1 = o2
3668 }
3669
3670 case 12:
3671
3672
3673 num := c.omovlconst(p.As, p, &p.From, int(p.To.Reg), os[:])
3674 if num == 0 {
3675 c.ctxt.Diag("invalid constant: %v", p)
3676 }
3677 o1 = os[0]
3678 o2 = os[1]
3679 o3 = os[2]
3680 o4 = os[3]
3681
3682 case 13:
3683 if p.Reg == REGTMP {
3684 c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
3685 }
3686 if p.To.Reg == REG_RSP && isADDSop(p.As) {
3687 c.ctxt.Diag("illegal destination register: %v\n", p)
3688 }
3689 o := uint32(0)
3690 num := uint8(0)
3691 cls := int(p.From.Class)
3692 if isADDWop(p.As) {
3693 if !cmp(C_LCON, cls) {
3694 c.ctxt.Diag("illegal combination: %v", p)
3695 }
3696 num = c.omovlconst(AMOVW, p, &p.From, REGTMP, os[:])
3697 } else {
3698 num = c.omovlconst(AMOVD, p, &p.From, REGTMP, os[:])
3699 }
3700 if num == 0 {
3701 c.ctxt.Diag("invalid constant: %v", p)
3702 }
3703
3704 rt, r, rf := p.To.Reg, p.Reg, int16(REGTMP)
3705 if p.To.Type == obj.TYPE_NONE {
3706 rt = REGZERO
3707 }
3708 if r == obj.REG_NONE {
3709 r = rt
3710 }
3711 if p.To.Type != obj.TYPE_NONE && (rt == REGSP || r == REGSP) {
3712 o = c.opxrrr(p, p.As, rt, r, rf, false)
3713 o |= LSL0_64
3714 } else {
3715 o = c.oprrr(p, p.As, rt, r, rf)
3716 }
3717
3718 os[num] = o
3719 o1 = os[0]
3720 o2 = os[1]
3721 o3 = os[2]
3722 o4 = os[3]
3723 o5 = os[4]
3724
3725 case 14:
3726 if c.aclass(&p.To) == C_ADDR {
3727 c.ctxt.Diag("address constant needs DWORD\n%v", p)
3728 }
3729 o1 = uint32(c.instoffset)
3730 if p.To.Sym != nil {
3731
3732
3733 c.cursym.AddRel(c.ctxt, obj.Reloc{
3734 Type: objabi.R_ADDR,
3735 Off: int32(c.pc),
3736 Siz: 4,
3737 Sym: p.To.Sym,
3738 Add: p.To.Offset,
3739 })
3740 o1 = 0
3741 }
3742
3743 case 15:
3744 rt, r, rf, ra := p.To.Reg, p.Reg, p.From.Reg, int16(REGZERO)
3745 if r == obj.REG_NONE {
3746 r = rt
3747 }
3748 if p.From3Type() == obj.TYPE_REG {
3749 r, ra = p.GetFrom3().Reg, p.Reg
3750 if ra == obj.REG_NONE {
3751 ra = REGZERO
3752 }
3753 }
3754 o1 = c.oprrrr(p, p.As, rt, r, rf, ra)
3755
3756 case 16:
3757 rt, r, rf := p.To.Reg, p.Reg, p.From.Reg
3758 if r == obj.REG_NONE {
3759 r = rt
3760 }
3761 o1 = c.oprrr(p, p.As, REGTMP, r, rf)
3762 o2 = c.oprrrr(p, AMSUBW, rt, REGTMP, rf, r)
3763 o2 |= o1 & (1 << 31)
3764
3765 case 17:
3766 rt, r, rf := p.To.Reg, p.Reg, p.From.Reg
3767 if p.To.Type == obj.TYPE_NONE {
3768 rt = REGZERO
3769 }
3770 if r == obj.REG_NONE {
3771 r = REGZERO
3772 }
3773 o1 = c.oprrr(p, p.As, rt, r, rf)
3774
3775 case 18:
3776 cond := SpecialOperand(p.From.Offset)
3777 if cond < SPOP_EQ || cond > SPOP_NV || (cond == SPOP_AL || cond == SPOP_NV) && p.From3Type() == obj.TYPE_NONE {
3778 c.ctxt.Diag("invalid condition: %v", p)
3779 } else {
3780 cond -= SPOP_EQ
3781 }
3782
3783 rt, r, rf := p.To.Reg, p.Reg, p.Reg
3784 if p.From3Type() == obj.TYPE_NONE {
3785
3786 if r == obj.REG_NONE {
3787
3788 r, rf = REGZERO, REGZERO
3789 }
3790 cond ^= 1
3791 } else {
3792 rf = p.GetFrom3().Reg
3793 }
3794 o1 = c.oprrr(p, p.As, rt, r, rf)
3795 o1 |= uint32(cond&15) << 12
3796
3797 case 19:
3798 nzcv := int(p.To.Offset)
3799
3800 cond := SpecialOperand(p.From.Offset)
3801 if cond < SPOP_EQ || cond > SPOP_NV {
3802 c.ctxt.Diag("invalid condition\n%v", p)
3803 } else {
3804 cond -= SPOP_EQ
3805 }
3806 if p.GetFrom3().Type == obj.TYPE_REG {
3807 r, rf := p.Reg, p.GetFrom3().Reg
3808 o1 = c.oprrr(p, p.As, obj.REG_NONE, r, rf)
3809 o1 |= (uint32(cond&15) << 12) | uint32(nzcv)
3810 } else {
3811 rf := int(p.GetFrom3().Offset & 0x1F)
3812 o1 = c.opirr(p, p.As)
3813 o1 |= (uint32(rf&31) << 16) | (uint32(cond&15) << 12) | (uint32(p.Reg&31) << 5) | uint32(nzcv)
3814 }
3815
3816 case 20:
3817 v := c.regoff(&p.To)
3818 sz := int32(1 << uint(movesize(p.As)))
3819
3820 rt, rf := p.To.Reg, p.From.Reg
3821 if rt == obj.REG_NONE {
3822 rt = o.param
3823 }
3824 if v < 0 || v%sz != 0 {
3825 o1 = c.olsr9s(p, c.opstr(p, p.As), v, rt, rf)
3826 } else {
3827 v = int32(c.offsetshift(p, int64(v), int(o.a4)))
3828 o1 = c.olsr12u(p, c.opstr(p, p.As), v, rt, rf)
3829 }
3830
3831 case 21:
3832 v := c.regoff(&p.From)
3833 sz := int32(1 << uint(movesize(p.As)))
3834
3835 rt, rf := p.To.Reg, p.From.Reg
3836 if rf == obj.REG_NONE {
3837 rf = o.param
3838 }
3839 if v < 0 || v%sz != 0 {
3840 o1 = c.olsr9s(p, c.opldr(p, p.As), v, rf, rt)
3841 } else {
3842 v = int32(c.offsetshift(p, int64(v), int(o.a1)))
3843 o1 = c.olsr12u(p, c.opldr(p, p.As), v, rf, rt)
3844 }
3845
3846 case 22:
3847 if p.From.Reg != REGSP && p.From.Reg == p.To.Reg {
3848 c.ctxt.Diag("constrained unpredictable behavior: %v", p)
3849 }
3850
3851 v := int32(p.From.Offset)
3852
3853 if v < -256 || v > 255 {
3854 c.ctxt.Diag("offset out of range [-256,255]: %v", p)
3855 }
3856 o1 = c.opldr(p, p.As)
3857 if o.scond == C_XPOST {
3858 o1 |= 1 << 10
3859 } else {
3860 o1 |= 3 << 10
3861 }
3862 o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.From.Reg&31) << 5) | uint32(p.To.Reg&31)
3863
3864 case 23:
3865 if p.To.Reg != REGSP && p.From.Reg == p.To.Reg {
3866 c.ctxt.Diag("constrained unpredictable behavior: %v", p)
3867 }
3868
3869 v := int32(p.To.Offset)
3870
3871 if v < -256 || v > 255 {
3872 c.ctxt.Diag("offset out of range [-256,255]: %v", p)
3873 }
3874 o1 = c.opstr(p, p.As)
3875 if o.scond == C_XPOST {
3876 o1 |= 1 << 10
3877 } else {
3878 o1 |= 3 << 10
3879 }
3880 o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.To.Reg&31) << 5) | uint32(p.From.Reg&31)
3881
3882 case 24:
3883 rt, r, rf := p.To.Reg, int16(REGZERO), p.From.Reg
3884 if rt == REGSP || rf == REGSP {
3885 if p.As == AMVN || p.As == AMVNW {
3886 c.ctxt.Diag("illegal SP reference\n%v", p)
3887 }
3888 o1 = c.opirr(p, p.As)
3889 o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
3890 } else {
3891 o1 = c.oprrr(p, p.As, rt, r, rf)
3892 }
3893
3894 case 25:
3895 rt, r, rf := p.To.Reg, int16(REGZERO), p.From.Reg
3896 if rf == obj.REG_NONE {
3897 rf = rt
3898 }
3899 o1 = c.oprrr(p, p.As, rt, r, rf)
3900
3901 case 26:
3902 rt, rf := p.To.Reg, p.From.Reg
3903 af := (rf >> 5) & 15
3904 at := (rt >> 5) & 15
3905 cf := c.aclass(&p.From)
3906 var sz int16
3907 switch p.As {
3908 case AAESD, AAESE, AAESIMC, AAESMC:
3909 sz = ARNG_16B
3910 case ASHA1SU1, ASHA256SU0:
3911 sz = ARNG_4S
3912 case ASHA512SU0:
3913 sz = ARNG_2D
3914 }
3915
3916 if cf == C_ARNG {
3917 if p.As == ASHA1H {
3918 c.ctxt.Diag("invalid operands: %v", p)
3919 } else {
3920 if af != sz || af != at {
3921 c.ctxt.Diag("invalid arrangement: %v", p)
3922 }
3923 }
3924 }
3925 o1 = c.oprrr(p, p.As, rt, rf, obj.REG_NONE)
3926
3927 case 27:
3928 if p.To.Reg == REG_RSP && isADDSop(p.As) {
3929 c.ctxt.Diag("illegal destination register: %v\n", p)
3930 }
3931 rt, r, rf := p.To.Reg, p.Reg, p.From.Reg
3932 if p.To.Type == obj.TYPE_NONE {
3933 rt = REGZERO
3934 }
3935 if r == obj.REG_NONE {
3936 r = rt
3937 }
3938 if (p.From.Reg-obj.RBaseARM64)®_EXT != 0 ||
3939 (p.From.Reg >= REG_LSL && p.From.Reg < REG_ARNG) {
3940 amount := (p.From.Reg >> 5) & 7
3941 if amount > 4 {
3942 c.ctxt.Diag("shift amount out of range 0 to 4: %v", p)
3943 }
3944 o1 = c.opxrrr(p, p.As, rt, r, obj.REG_NONE, true)
3945 o1 |= c.encRegShiftOrExt(p, &p.From, p.From.Reg)
3946 } else {
3947 o1 = c.opxrrr(p, p.As, rt, r, rf, false)
3948 }
3949
3950 case 28:
3951 if p.Reg == REGTMP {
3952 c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
3953 }
3954 o := uint32(0)
3955 num := uint8(0)
3956 cls := int(p.From.Class)
3957 if isANDWop(p.As) {
3958 if !cmp(C_LCON, cls) {
3959 c.ctxt.Diag("illegal combination: %v", p)
3960 }
3961 num = c.omovlconst(AMOVW, p, &p.From, REGTMP, os[:])
3962 } else {
3963 num = c.omovlconst(AMOVD, p, &p.From, REGTMP, os[:])
3964 }
3965
3966 if num == 0 {
3967 c.ctxt.Diag("invalid constant: %v", p)
3968 }
3969 rt, r, rf := p.To.Reg, p.Reg, int16(REGTMP)
3970 if p.To.Type == obj.TYPE_NONE {
3971 rt = REGZERO
3972 }
3973 if r == obj.REG_NONE {
3974 r = rt
3975 }
3976 o = c.oprrr(p, p.As, rt, r, rf)
3977
3978 os[num] = o
3979 o1 = os[0]
3980 o2 = os[1]
3981 o3 = os[2]
3982 o4 = os[3]
3983 o5 = os[4]
3984
3985 case 29:
3986 fc := c.aclass(&p.From)
3987 tc := c.aclass(&p.To)
3988 if (p.As == AFMOVD || p.As == AFMOVS) && (fc == C_REG || fc == C_ZREG || tc == C_REG || tc == C_ZREG) {
3989
3990 o1 = FPCVTI(0, 0, 0, 0, 6)
3991 if p.As == AFMOVD {
3992 o1 |= 1<<31 | 1<<22
3993 }
3994 if fc == C_REG || fc == C_ZREG {
3995 o1 |= 1 << 16
3996 }
3997 o1 |= uint32(p.From.Reg&31)<<5 | uint32(p.To.Reg&31)
3998 } else {
3999 o1 = c.oprrr(p, p.As, p.To.Reg, p.From.Reg, obj.REG_NONE)
4000 }
4001
4002 case 30:
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012 s := movesize(o.as)
4013 if s < 0 {
4014 c.ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p)
4015 }
4016
4017 rt, rf := p.To.Reg, p.From.Reg
4018 if rt == obj.REG_NONE {
4019 rt = o.param
4020 }
4021
4022 v := c.regoff(&p.To)
4023 if v >= -256 && v <= 256 {
4024 c.ctxt.Diag("%v: bad type for offset %d (should be 9 bit signed immediate store)", p, v)
4025 }
4026 if v >= 0 && v <= 4095 && v&((1<<int32(s))-1) == 0 {
4027 c.ctxt.Diag("%v: bad type for offset %d (should be 12 bit unsigned immediate store)", p, v)
4028 }
4029
4030
4031 if v >= -4095 && v <= 4095 {
4032 o1 = c.oaddi12(p, v, REGTMP, rt)
4033 o2 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, rf)
4034 break
4035 }
4036
4037 hi, lo, err := splitImm24uScaled(v, s)
4038 if err != nil {
4039 goto storeusepool
4040 }
4041 if p.Pool != nil {
4042 c.ctxt.Diag("%v: unused constant in pool (%v)\n", p, v)
4043 }
4044 o1 = c.oaddi(p, AADD, hi, REGTMP, rt)
4045 o2 = c.olsr12u(p, c.opstr(p, p.As), lo, REGTMP, rf)
4046 break
4047
4048 storeusepool:
4049 if p.Pool == nil {
4050 c.ctxt.Diag("%v: constant is not in pool", p)
4051 }
4052 if rt == REGTMP || rf == REGTMP {
4053 c.ctxt.Diag("REGTMP used in large offset store: %v", p)
4054 }
4055 o1 = c.omovlit(AMOVD, p, &p.To, REGTMP)
4056 o2 = c.opstrr(p, p.As, rf, rt, REGTMP, false)
4057
4058 case 31:
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068 s := movesize(o.as)
4069 if s < 0 {
4070 c.ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p)
4071 }
4072
4073 rt, rf := p.To.Reg, p.From.Reg
4074 if rf == obj.REG_NONE {
4075 rf = o.param
4076 }
4077
4078 v := c.regoff(&p.From)
4079 if v >= -256 && v <= 256 {
4080 c.ctxt.Diag("%v: bad type for offset %d (should be 9 bit signed immediate load)", p, v)
4081 }
4082 if v >= 0 && v <= 4095 && v&((1<<int32(s))-1) == 0 {
4083 c.ctxt.Diag("%v: bad type for offset %d (should be 12 bit unsigned immediate load)", p, v)
4084 }
4085
4086
4087 if v >= -4095 && v <= 4095 {
4088 o1 = c.oaddi12(p, v, REGTMP, rf)
4089 o2 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, rt)
4090 break
4091 }
4092
4093 hi, lo, err := splitImm24uScaled(v, s)
4094 if err != nil {
4095 goto loadusepool
4096 }
4097 if p.Pool != nil {
4098 c.ctxt.Diag("%v: unused constant in pool (%v)\n", p, v)
4099 }
4100 o1 = c.oaddi(p, AADD, hi, REGTMP, rf)
4101 o2 = c.olsr12u(p, c.opldr(p, p.As), lo, REGTMP, rt)
4102 break
4103
4104 loadusepool:
4105 if p.Pool == nil {
4106 c.ctxt.Diag("%v: constant is not in pool", p)
4107 }
4108 if rt == REGTMP || rf == REGTMP {
4109 c.ctxt.Diag("REGTMP used in large offset load: %v", p)
4110 }
4111 o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
4112 o2 = c.opldrr(p, p.As, rt, rf, REGTMP, false)
4113
4114 case 32:
4115 o1 = c.omovconst(p.As, p, &p.From, int(p.To.Reg))
4116
4117 case 33:
4118 o1 = c.opirr(p, p.As)
4119
4120 d := p.From.Offset
4121 if d == 0 {
4122 c.ctxt.Diag("zero shifts cannot be handled correctly: %v", p)
4123 }
4124 s := movcon(d)
4125 if s < 0 || s >= 64 {
4126 c.ctxt.Diag("bad constant for MOVK: %#x\n%v", uint64(d), p)
4127 }
4128 if (o1&S64) == 0 && s >= 32 {
4129 c.ctxt.Diag("illegal bit position\n%v", p)
4130 }
4131 if ((uint64(d) >> uint(s)) >> 16) != 0 {
4132 c.ctxt.Diag("requires uimm16\n%v", p)
4133 }
4134 rt := int(p.To.Reg)
4135
4136 o1 |= uint32((((d >> uint(s)) & 0xFFFF) << 5) | int64((uint32(s>>4)&3)<<21) | int64(rt&31))
4137
4138 case 34:
4139 rt, r, rf := p.To.Reg, p.From.Reg, int16(REGTMP)
4140 if r == obj.REG_NONE {
4141 r = o.param
4142 }
4143 o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
4144 o2 = c.opxrrr(p, AADD, rt, r, rf, false)
4145 o2 |= LSL0_64
4146
4147 case 35:
4148 o1 = c.oprrr(p, AMRS, p.To.Reg, obj.REG_NONE, obj.REG_NONE)
4149
4150
4151 _, v, accessFlags := SysRegEnc(p.From.Reg)
4152 if v == 0 {
4153 c.ctxt.Diag("illegal system register:\n%v", p)
4154 }
4155 if (o1 & (v &^ (3 << 19))) != 0 {
4156 c.ctxt.Diag("MRS register value overlap\n%v", p)
4157 }
4158 if accessFlags&SR_READ == 0 {
4159 c.ctxt.Diag("system register is not readable: %v", p)
4160 }
4161 o1 |= v
4162
4163 case 36:
4164 o1 = c.oprrr(p, AMSR, p.From.Reg, obj.REG_NONE, obj.REG_NONE)
4165
4166
4167 _, v, accessFlags := SysRegEnc(p.To.Reg)
4168 if v == 0 {
4169 c.ctxt.Diag("illegal system register:\n%v", p)
4170 }
4171 if (o1 & (v &^ (3 << 19))) != 0 {
4172 c.ctxt.Diag("MSR register value overlap\n%v", p)
4173 }
4174 if accessFlags&SR_WRITE == 0 {
4175 c.ctxt.Diag("system register is not writable: %v", p)
4176 }
4177 o1 |= v
4178
4179 case 37:
4180 if (uint64(p.From.Offset) &^ uint64(0xF)) != 0 {
4181 c.ctxt.Diag("illegal immediate for PSTATE field\n%v", p)
4182 }
4183 o1 = c.opirr(p, AMSR)
4184 o1 |= uint32((p.From.Offset & 0xF) << 8)
4185 v := uint32(0)
4186
4187 if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_SPSel {
4188 v = 0<<16 | 4<<12 | 5<<5
4189 } else if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_DIT {
4190
4191 v = 3<<16 | 2<<5
4192 } else if p.To.Type == obj.TYPE_SPECIAL {
4193 opd := SpecialOperand(p.To.Offset)
4194 for _, pf := range pstatefield {
4195 if pf.opd == opd {
4196 v = pf.enc
4197 break
4198 }
4199 }
4200 }
4201
4202 if v == 0 {
4203 c.ctxt.Diag("illegal PSTATE field for immediate move\n%v", p)
4204 }
4205 o1 |= v
4206
4207 case 38:
4208 o1 = c.opimm(p, p.As)
4209
4210 if p.To.Type == obj.TYPE_NONE {
4211 o1 |= 0xF << 8
4212 } else {
4213 o1 |= uint32((p.To.Offset & 0xF) << 8)
4214 }
4215
4216 case 39:
4217 o1 = c.opirr(p, p.As)
4218
4219 o1 |= uint32(p.From.Reg & 31)
4220 o1 |= uint32(c.brdist(p, 0, 19, 2) << 5)
4221
4222 case 40:
4223 o1 = c.opirr(p, p.As)
4224
4225 v := int32(p.From.Offset)
4226 if v < 0 || v > 63 {
4227 c.ctxt.Diag("illegal bit number\n%v", p)
4228 }
4229 o1 |= ((uint32(v) & 0x20) << (31 - 5)) | ((uint32(v) & 0x1F) << 19)
4230 o1 |= uint32(c.brdist(p, 0, 14, 2) << 5)
4231 o1 |= uint32(p.Reg & 31)
4232
4233 case 41:
4234 o1 = c.op0(p, p.As)
4235
4236 case 42:
4237 o1 = c.opbfm(p, p.As, p.From.Offset, p.GetFrom3().Offset, p.Reg, p.To.Reg)
4238
4239 case 43:
4240 rt, rf := p.To.Reg, p.Reg
4241 if rf == obj.REG_NONE {
4242 rf = rt
4243 }
4244 r, s := p.From.Offset, p.GetFrom3().Offset
4245 switch p.As {
4246 case ABFI:
4247 if r != 0 {
4248 r = 64 - r
4249 }
4250 o1 = c.opbfm(p, ABFM, r, s-1, rf, rt)
4251
4252 case ABFIW:
4253 if r != 0 {
4254 r = 32 - r
4255 }
4256 o1 = c.opbfm(p, ABFMW, r, s-1, rf, rt)
4257
4258 case ABFXIL:
4259 o1 = c.opbfm(p, ABFM, r, r+s-1, rf, rt)
4260
4261 case ABFXILW:
4262 o1 = c.opbfm(p, ABFMW, r, r+s-1, rf, rt)
4263
4264 case ASBFIZ:
4265 if r != 0 {
4266 r = 64 - r
4267 }
4268 o1 = c.opbfm(p, ASBFM, r, s-1, rf, rt)
4269
4270 case ASBFIZW:
4271 if r != 0 {
4272 r = 32 - r
4273 }
4274 o1 = c.opbfm(p, ASBFMW, r, s-1, rf, rt)
4275
4276 case ASBFX:
4277 o1 = c.opbfm(p, ASBFM, r, r+s-1, rf, rt)
4278
4279 case ASBFXW:
4280 o1 = c.opbfm(p, ASBFMW, r, r+s-1, rf, rt)
4281
4282 case AUBFIZ:
4283 if r != 0 {
4284 r = 64 - r
4285 }
4286 o1 = c.opbfm(p, AUBFM, r, s-1, rf, rt)
4287
4288 case AUBFIZW:
4289 if r != 0 {
4290 r = 32 - r
4291 }
4292 o1 = c.opbfm(p, AUBFMW, r, s-1, rf, rt)
4293
4294 case AUBFX:
4295 o1 = c.opbfm(p, AUBFM, r, r+s-1, rf, rt)
4296
4297 case AUBFXW:
4298 o1 = c.opbfm(p, AUBFMW, r, r+s-1, rf, rt)
4299
4300 default:
4301 c.ctxt.Diag("bad bfm alias\n%v", p)
4302 break
4303 }
4304
4305 case 44:
4306 o1 = c.opextr(p, p.As, p.From.Offset, p.GetFrom3().Reg, p.Reg, p.To.Reg)
4307
4308 case 45:
4309 as := p.As
4310 rt, rf := p.To.Reg, p.From.Reg
4311 if rf == REGZERO {
4312 as = AMOVWU
4313 }
4314 switch as {
4315 case AMOVB, ASXTB:
4316 o1 = c.opbfm(p, ASBFM, 0, 7, rf, rt)
4317
4318 case AMOVH, ASXTH:
4319 o1 = c.opbfm(p, ASBFM, 0, 15, rf, rt)
4320
4321 case AMOVW, ASXTW:
4322 o1 = c.opbfm(p, ASBFM, 0, 31, rf, rt)
4323
4324 case AMOVBU, AUXTB:
4325 o1 = c.opbfm(p, AUBFM, 0, 7, rf, rt)
4326
4327 case AMOVHU, AUXTH:
4328 o1 = c.opbfm(p, AUBFM, 0, 15, rf, rt)
4329
4330 case AMOVWU:
4331 o1 = c.oprrr(p, as, p.To.Reg, REGZERO, p.From.Reg)
4332
4333 case AUXTW:
4334 o1 = c.opbfm(p, AUBFM, 0, 31, rf, rt)
4335
4336 case ASXTBW:
4337 o1 = c.opbfm(p, ASBFMW, 0, 7, rf, rt)
4338
4339 case ASXTHW:
4340 o1 = c.opbfm(p, ASBFMW, 0, 15, rf, rt)
4341
4342 case AUXTBW:
4343 o1 = c.opbfm(p, AUBFMW, 0, 7, rf, rt)
4344
4345 case AUXTHW:
4346 o1 = c.opbfm(p, AUBFMW, 0, 15, rf, rt)
4347
4348 default:
4349 c.ctxt.Diag("bad sxt %v", as)
4350 break
4351 }
4352
4353 case 46:
4354 o1 = c.opbit(p, p.As)
4355
4356 o1 |= uint32(p.From.Reg&31) << 5
4357 o1 |= uint32(p.To.Reg & 31)
4358
4359 case 47:
4360 rs := p.From.Reg
4361 rt := p.RegTo2
4362 rb := p.To.Reg
4363
4364
4365 if rt == REG_RSP {
4366 c.ctxt.Diag("illegal destination register: %v\n", p)
4367 }
4368
4369 o1 = atomicLDADD[p.As] | atomicSWP[p.As]
4370 o1 |= uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
4371
4372 case 48:
4373
4374
4375 op := c.opirr(p, p.As)
4376 if op&Sbit != 0 {
4377 c.ctxt.Diag("can not break addition/subtraction when S bit is set (%v)", p)
4378 }
4379 rt, r := p.To.Reg, p.Reg
4380 if r == obj.REG_NONE {
4381 r = rt
4382 }
4383 o1 = c.oaddi(p, p.As, c.regoff(&p.From)&0x000fff, rt, r)
4384 o2 = c.oaddi(p, p.As, c.regoff(&p.From)&0xfff000, rt, rt)
4385
4386 case 49:
4387 rt, r, rf := p.To.Reg, p.Reg, p.From.Reg
4388 cf := c.aclass(&p.From)
4389 af := (rf >> 5) & 15
4390 sz := ARNG_4S
4391 if p.As == ASHA512H || p.As == ASHA512H2 {
4392 sz = ARNG_2D
4393 }
4394 if cf == C_ARNG && af != int16(sz) {
4395 c.ctxt.Diag("invalid arrangement: %v", p)
4396 }
4397 o1 = c.oprrr(p, p.As, rt, r, rf)
4398
4399 case 50:
4400 o1 = c.opirr(p, p.As)
4401
4402 if (p.From.Offset &^ int64(SYSARG4(0x7, 0xF, 0xF, 0x7))) != 0 {
4403 c.ctxt.Diag("illegal SYS argument\n%v", p)
4404 }
4405 o1 |= uint32(p.From.Offset)
4406 if p.To.Type == obj.TYPE_REG {
4407 o1 |= uint32(p.To.Reg & 31)
4408 } else {
4409 o1 |= 0x1F
4410 }
4411
4412 case 51:
4413 o1 = c.opirr(p, p.As)
4414
4415 if p.From.Type == obj.TYPE_CONST {
4416 o1 |= uint32((p.From.Offset & 0xF) << 8)
4417 }
4418
4419 case 52:
4420 o1 = c.opirr(p, p.As)
4421
4422 o1 |= uint32((p.From.Offset & 0x7F) << 5)
4423
4424 case 53:
4425 a := p.As
4426 rt := int(p.To.Reg)
4427 if p.To.Type == obj.TYPE_NONE {
4428 rt = REGZERO
4429 }
4430 r := int(p.Reg)
4431 if r == obj.REG_NONE {
4432 r = rt
4433 }
4434 if r == REG_RSP {
4435 c.ctxt.Diag("illegal source register: %v", p)
4436 break
4437 }
4438 mode := 64
4439 v := uint64(p.From.Offset)
4440 switch p.As {
4441 case AANDW, AORRW, AEORW, AANDSW, ATSTW:
4442 mode = 32
4443 case ABIC, AORN, AEON, ABICS:
4444 v = ^v
4445 case ABICW, AORNW, AEONW, ABICSW:
4446 v = ^v
4447 mode = 32
4448 }
4449 o1 = c.opirr(p, a)
4450 o1 |= bitconEncode(v, mode) | uint32(r&31)<<5 | uint32(rt&31)
4451
4452 case 54:
4453 rt, r, rf := p.To.Reg, p.Reg, p.From.Reg
4454 o1 = c.oprrr(p, p.As, obj.REG_NONE, obj.REG_NONE, obj.REG_NONE)
4455 if (o1&(0x1F<<24)) == (0x1E<<24) && (o1&(1<<11)) == 0 {
4456 r, rf = rf, obj.REG_NONE
4457 } else if r == obj.REG_NONE {
4458 r = rt
4459 }
4460 o1 = c.oprrr(p, p.As, rt, r, rf)
4461
4462 case 55:
4463 var rf int
4464 o1 = 0xf<<25 | 1<<21 | 1<<12
4465 rf = c.chipfloat7(p.From.Val.(float64))
4466 if rf < 0 {
4467 c.ctxt.Diag("invalid floating-point immediate\n%v", p)
4468 }
4469 if p.As == AFMOVD {
4470 o1 |= 1 << 22
4471 }
4472 o1 |= (uint32(rf&0xff) << 13) | uint32(p.To.Reg&31)
4473
4474 case 56:
4475 r, rf := p.Reg, p.From.Reg
4476 if p.From.Type == obj.TYPE_FCONST {
4477 o1 |= 8
4478 rf = obj.REG_NONE
4479 }
4480 o1 |= c.oprrr(p, p.As, obj.REG_NONE, r, rf)
4481
4482 case 57:
4483 cond := SpecialOperand(p.From.Offset)
4484 if cond < SPOP_EQ || cond > SPOP_NV {
4485 c.ctxt.Diag("invalid condition\n%v", p)
4486 } else {
4487 cond -= SPOP_EQ
4488 }
4489
4490 nzcv := int(p.To.Offset)
4491 if nzcv&^0xF != 0 {
4492 c.ctxt.Diag("implausible condition\n%v", p)
4493 }
4494
4495 if p.GetFrom3() == nil || p.GetFrom3().Reg < REG_F0 || p.GetFrom3().Reg > REG_F31 {
4496 c.ctxt.Diag("illegal FCCMP\n%v", p)
4497 break
4498 }
4499 o1 = c.oprrr(p, p.As, obj.REG_NONE, p.GetFrom3().Reg, p.Reg)
4500 o1 |= uint32(cond&15)<<12 | uint32(nzcv)
4501
4502 case 58:
4503 o1 = c.opload(p, p.As)
4504
4505 o1 |= 0x1F << 16
4506 o1 |= uint32(p.From.Reg&31) << 5
4507 if p.As == ALDXP || p.As == ALDXPW || p.As == ALDAXP || p.As == ALDAXPW {
4508 if int(p.To.Reg) == int(p.To.Offset) {
4509 c.ctxt.Diag("constrained unpredictable behavior: %v", p)
4510 }
4511 o1 |= uint32(p.To.Offset&31) << 10
4512 } else {
4513 o1 |= 0x1F << 10
4514 }
4515 o1 |= uint32(p.To.Reg & 31)
4516
4517 case 59:
4518 s := p.RegTo2
4519 n := p.To.Reg
4520 t := p.From.Reg
4521 if isSTLXRop(p.As) {
4522 if s == t || (s == n && n != REGSP) {
4523 c.ctxt.Diag("constrained unpredictable behavior: %v", p)
4524 }
4525 } else if isSTXPop(p.As) {
4526 t2 := int16(p.From.Offset)
4527 if (s == t || s == t2) || (s == n && n != REGSP) {
4528 c.ctxt.Diag("constrained unpredictable behavior: %v", p)
4529 }
4530 }
4531 if s == REG_RSP {
4532 c.ctxt.Diag("illegal destination register: %v\n", p)
4533 }
4534 o1 = c.opstore(p, p.As)
4535
4536 if p.RegTo2 != obj.REG_NONE {
4537 o1 |= uint32(p.RegTo2&31) << 16
4538 } else {
4539 o1 |= 0x1F << 16
4540 }
4541 if isSTXPop(p.As) {
4542 o1 |= uint32(p.From.Offset&31) << 10
4543 }
4544 o1 |= uint32(p.To.Reg&31)<<5 | uint32(p.From.Reg&31)
4545
4546 case 60:
4547 d := c.brdist(p, 12, 21, 0)
4548
4549 o1 = ADR(1, uint32(d), uint32(p.To.Reg))
4550
4551 case 61:
4552 d := c.brdist(p, 0, 21, 0)
4553
4554 o1 = ADR(0, uint32(d), uint32(p.To.Reg))
4555
4556 case 62:
4557 if p.Reg == REGTMP {
4558 c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
4559 }
4560 if p.To.Reg == REG_RSP && isADDSop(p.As) {
4561 c.ctxt.Diag("illegal destination register: %v\n", p)
4562 }
4563 lsl0 := LSL0_64
4564 if isADDWop(p.As) || isANDWop(p.As) {
4565 o1 = c.omovconst(AMOVW, p, &p.From, REGTMP)
4566 lsl0 = LSL0_32
4567 } else {
4568 o1 = c.omovconst(AMOVD, p, &p.From, REGTMP)
4569 }
4570
4571 rt, r, rf := p.To.Reg, p.Reg, int16(REGTMP)
4572 if p.To.Type == obj.TYPE_NONE {
4573 rt = REGZERO
4574 }
4575 if r == obj.REG_NONE {
4576 r = rt
4577 }
4578 if rt == REGSP || r == REGSP {
4579 o2 = c.opxrrr(p, p.As, rt, r, rf, false)
4580 o2 |= uint32(lsl0)
4581 } else {
4582 o2 = c.oprrr(p, p.As, rt, r, rf)
4583 }
4584
4585 case 63:
4586 rt, r, rf := p.To.Reg, p.Reg, p.From.Reg
4587 af := (rf >> 5) & 15
4588 at := (rt >> 5) & 15
4589 ar := (r >> 5) & 15
4590 sz := ARNG_4S
4591 if p.As == ASHA512SU1 {
4592 sz = ARNG_2D
4593 }
4594 if af != at || af != ar || af != int16(sz) {
4595 c.ctxt.Diag("invalid arrangement: %v", p)
4596 }
4597 o1 |= c.oprrr(p, p.As, rt, r, rf)
4598
4599
4600 case 64:
4601 if p.From.Reg == REGTMP {
4602 c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
4603 }
4604 o1 = ADR(1, 0, REGTMP)
4605 var typ objabi.RelocType
4606
4607 if o.size(c.ctxt, p) != 8 {
4608 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
4609 o3 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg)
4610 typ = objabi.R_ADDRARM64
4611 } else {
4612 o2 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg)
4613 typ = c.addrRelocType(p)
4614 }
4615 c.cursym.AddRel(c.ctxt, obj.Reloc{
4616 Type: typ,
4617 Off: int32(c.pc),
4618 Siz: 8,
4619 Sym: p.To.Sym,
4620 Add: p.To.Offset,
4621 })
4622
4623 case 65:
4624 o1 = ADR(1, 0, REGTMP)
4625 var typ objabi.RelocType
4626
4627 if o.size(c.ctxt, p) != 8 {
4628 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
4629 o3 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg)
4630 typ = objabi.R_ADDRARM64
4631 } else {
4632 o2 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg)
4633 typ = c.addrRelocType(p)
4634 }
4635 c.cursym.AddRel(c.ctxt, obj.Reloc{
4636 Type: typ,
4637 Off: int32(c.pc),
4638 Siz: 8,
4639 Sym: p.From.Sym,
4640 Add: p.From.Offset,
4641 })
4642
4643 case 66:
4644 rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset)
4645 if rf == obj.REG_NONE {
4646 rf = o.param
4647 }
4648 if rf == obj.REG_NONE {
4649 c.ctxt.Diag("invalid ldp source: %v\n", p)
4650 }
4651 v := c.regoff(&p.From)
4652 o1 = c.opldpstp(p, o, v, rf, rt1, rt2, 1)
4653
4654 case 67:
4655 rt, rf1, rf2 := p.To.Reg, p.From.Reg, int16(p.From.Offset)
4656 if rt == obj.REG_NONE {
4657 rt = o.param
4658 }
4659 if rt == obj.REG_NONE {
4660 c.ctxt.Diag("invalid stp destination: %v\n", p)
4661 }
4662 v := c.regoff(&p.To)
4663 o1 = c.opldpstp(p, o, v, rt, rf1, rf2, 0)
4664
4665 case 68:
4666
4667
4668 if p.As == AMOVW {
4669 c.ctxt.Diag("invalid load of 32-bit address: %v", p)
4670 }
4671 o1 = ADR(1, 0, uint32(p.To.Reg))
4672 o2 = c.opirr(p, AADD) | uint32(p.To.Reg&31)<<5 | uint32(p.To.Reg&31)
4673 c.cursym.AddRel(c.ctxt, obj.Reloc{
4674 Type: objabi.R_ADDRARM64,
4675 Off: int32(c.pc),
4676 Siz: 8,
4677 Sym: p.From.Sym,
4678 Add: p.From.Offset,
4679 })
4680
4681 case 69:
4682 o1 = c.opirr(p, AMOVZ)
4683 o1 |= uint32(p.To.Reg & 31)
4684 c.cursym.AddRel(c.ctxt, obj.Reloc{
4685 Type: objabi.R_ARM64_TLS_LE,
4686 Off: int32(c.pc),
4687 Siz: 4,
4688 Sym: p.From.Sym,
4689 })
4690 if p.From.Offset != 0 {
4691 c.ctxt.Diag("invalid offset on MOVW $tlsvar")
4692 }
4693
4694 case 70:
4695 o1 = ADR(1, 0, REGTMP)
4696 o2 = c.olsr12u(p, c.opldr(p, AMOVD), 0, REGTMP, p.To.Reg)
4697 c.cursym.AddRel(c.ctxt, obj.Reloc{
4698 Type: objabi.R_ARM64_TLS_IE,
4699 Off: int32(c.pc),
4700 Siz: 8,
4701 Sym: p.From.Sym,
4702 })
4703 if p.From.Offset != 0 {
4704 c.ctxt.Diag("invalid offset on MOVW $tlsvar")
4705 }
4706
4707 case 71:
4708 o1 = ADR(1, 0, REGTMP)
4709 o2 = c.olsr12u(p, c.opldr(p, AMOVD), 0, REGTMP, p.To.Reg)
4710 c.cursym.AddRel(c.ctxt, obj.Reloc{
4711 Type: objabi.R_ARM64_GOTPCREL,
4712 Off: int32(c.pc),
4713 Siz: 8,
4714 Sym: p.From.Sym,
4715 })
4716
4717 case 72:
4718 af := int((p.From.Reg >> 5) & 15)
4719 af3 := int((p.Reg >> 5) & 15)
4720 at := int((p.To.Reg >> 5) & 15)
4721 if af != af3 || af != at {
4722 c.ctxt.Diag("operand mismatch: %v", p)
4723 break
4724 }
4725
4726 Q := 0
4727 size := 0
4728 switch af {
4729 case ARNG_16B:
4730 Q = 1
4731 size = 0
4732 case ARNG_2D:
4733 Q = 1
4734 size = 3
4735 case ARNG_2S:
4736 Q = 0
4737 size = 2
4738 case ARNG_4H:
4739 Q = 0
4740 size = 1
4741 case ARNG_4S:
4742 Q = 1
4743 size = 2
4744 case ARNG_8B:
4745 Q = 0
4746 size = 0
4747 case ARNG_8H:
4748 Q = 1
4749 size = 1
4750 default:
4751 c.ctxt.Diag("invalid arrangement: %v", p)
4752 }
4753
4754 switch p.As {
4755 case AVORR, AVAND, AVEOR, AVBIT, AVBSL, AVBIF:
4756 if af != ARNG_16B && af != ARNG_8B {
4757 c.ctxt.Diag("invalid arrangement: %v", p)
4758 }
4759 case AVFMLA, AVFMLS:
4760 if af != ARNG_2D && af != ARNG_2S && af != ARNG_4S {
4761 c.ctxt.Diag("invalid arrangement: %v", p)
4762 }
4763 case AVUMAX, AVUMIN:
4764 if af == ARNG_2D {
4765 c.ctxt.Diag("invalid arrangement: %v", p)
4766 }
4767 }
4768 switch p.As {
4769 case AVAND, AVEOR:
4770 size = 0
4771 case AVBSL:
4772 size = 1
4773 case AVORR, AVBIT, AVBIF:
4774 size = 2
4775 case AVFMLA, AVFMLS:
4776 if af == ARNG_2D {
4777 size = 1
4778 } else {
4779 size = 0
4780 }
4781 case AVRAX1:
4782 if af != ARNG_2D {
4783 c.ctxt.Diag("invalid arrangement: %v", p)
4784 }
4785 size = 0
4786 Q = 0
4787 }
4788
4789 o1 = c.oprrr(p, p.As, p.To.Reg, p.Reg, p.From.Reg)
4790 o1 |= uint32(Q&1)<<30 | uint32(size&3)<<22
4791
4792 case 73:
4793 rf := int(p.From.Reg)
4794 rt := int(p.To.Reg)
4795 imm5 := 0
4796 o1 = 7<<25 | 0xf<<10
4797 index := int(p.From.Index)
4798 switch (p.From.Reg >> 5) & 15 {
4799 case ARNG_B:
4800 c.checkindex(p, index, 15)
4801 imm5 |= 1
4802 imm5 |= index << 1
4803 case ARNG_H:
4804 c.checkindex(p, index, 7)
4805 imm5 |= 2
4806 imm5 |= index << 2
4807 case ARNG_S:
4808 c.checkindex(p, index, 3)
4809 imm5 |= 4
4810 imm5 |= index << 3
4811 case ARNG_D:
4812 c.checkindex(p, index, 1)
4813 imm5 |= 8
4814 imm5 |= index << 4
4815 o1 |= 1 << 30
4816 default:
4817 c.ctxt.Diag("invalid arrangement: %v", p)
4818 }
4819 o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
4820
4821 case 74:
4822
4823
4824 rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset)
4825 if rf == obj.REG_NONE {
4826 rf = o.param
4827 }
4828 if rf == obj.REG_NONE {
4829 c.ctxt.Diag("invalid ldp source: %v", p)
4830 }
4831 v := c.regoff(&p.From)
4832 o1 = c.oaddi12(p, v, REGTMP, rf)
4833 o2 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1)
4834
4835 case 75:
4836
4837
4838
4839
4840
4841
4842
4843
4844 rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset)
4845 if rf == REGTMP {
4846 c.ctxt.Diag("REGTMP used in large offset load: %v", p)
4847 }
4848 if rf == obj.REG_NONE {
4849 rf = o.param
4850 }
4851 if rf == obj.REG_NONE {
4852 c.ctxt.Diag("invalid ldp source: %v", p)
4853 }
4854
4855 v := c.regoff(&p.From)
4856 if v >= -4095 && v <= 4095 {
4857 c.ctxt.Diag("%v: bad type for offset %d (should be add/sub+ldp)", p, v)
4858 }
4859
4860 hi, lo, err := splitImm24uScaled(v, 0)
4861 if err != nil {
4862 goto loadpairusepool
4863 }
4864 if p.Pool != nil {
4865 c.ctxt.Diag("%v: unused constant in pool (%v)\n", p, v)
4866 }
4867 o1 = c.oaddi(p, AADD, lo, REGTMP, rf)
4868 o2 = c.oaddi(p, AADD, hi, REGTMP, REGTMP)
4869 o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1)
4870 break
4871
4872 loadpairusepool:
4873 if p.Pool == nil {
4874 c.ctxt.Diag("%v: constant is not in pool", p)
4875 }
4876 if rf == REGTMP || p.From.Reg == REGTMP {
4877 c.ctxt.Diag("REGTMP used in large offset load: %v", p)
4878 }
4879 o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
4880 o2 = c.opxrrr(p, AADD, REGTMP, rf, REGTMP, false)
4881 o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1)
4882
4883 case 76:
4884
4885
4886 rt, rf1, rf2 := p.To.Reg, p.From.Reg, int16(p.From.Offset)
4887 if rf1 == REGTMP || rf2 == REGTMP {
4888 c.ctxt.Diag("cannot use REGTMP as source: %v", p)
4889 }
4890 if rt == obj.REG_NONE {
4891 rt = o.param
4892 }
4893 if rt == obj.REG_NONE {
4894 c.ctxt.Diag("invalid stp destination: %v", p)
4895 }
4896 v := c.regoff(&p.To)
4897 o1 = c.oaddi12(p, v, REGTMP, rt)
4898 o2 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0)
4899
4900 case 77:
4901
4902
4903
4904
4905
4906
4907
4908
4909 rt, rf1, rf2 := p.To.Reg, p.From.Reg, int16(p.From.Offset)
4910 if rt == REGTMP || rf1 == REGTMP || rf2 == REGTMP {
4911 c.ctxt.Diag("REGTMP used in large offset store: %v", p)
4912 }
4913 if rt == obj.REG_NONE {
4914 rt = o.param
4915 }
4916 if rt == obj.REG_NONE {
4917 c.ctxt.Diag("invalid stp destination: %v", p)
4918 }
4919
4920 v := c.regoff(&p.To)
4921 if v >= -4095 && v <= 4095 {
4922 c.ctxt.Diag("%v: bad type for offset %d (should be add/sub+stp)", p, v)
4923 }
4924
4925 hi, lo, err := splitImm24uScaled(v, 0)
4926 if err != nil {
4927 goto storepairusepool
4928 }
4929 if p.Pool != nil {
4930 c.ctxt.Diag("%v: unused constant in pool (%v)\n", p, v)
4931 }
4932 o1 = c.oaddi(p, AADD, lo, REGTMP, rt)
4933 o2 = c.oaddi(p, AADD, hi, REGTMP, REGTMP)
4934 o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0)
4935 break
4936
4937 storepairusepool:
4938 if p.Pool == nil {
4939 c.ctxt.Diag("%v: constant is not in pool", p)
4940 }
4941 if rt == REGTMP || p.From.Reg == REGTMP {
4942 c.ctxt.Diag("REGTMP used in large offset store: %v", p)
4943 }
4944 o1 = c.omovlit(AMOVD, p, &p.To, REGTMP)
4945 o2 = c.opxrrr(p, AADD, REGTMP, rt, REGTMP, false)
4946 o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0)
4947
4948 case 78:
4949 rf := int(p.From.Reg)
4950 rt := int(p.To.Reg)
4951 imm5 := 0
4952 o1 = 1<<30 | 7<<25 | 7<<10
4953 index := int(p.To.Index)
4954 switch (p.To.Reg >> 5) & 15 {
4955 case ARNG_B:
4956 c.checkindex(p, index, 15)
4957 imm5 |= 1
4958 imm5 |= index << 1
4959 case ARNG_H:
4960 c.checkindex(p, index, 7)
4961 imm5 |= 2
4962 imm5 |= index << 2
4963 case ARNG_S:
4964 c.checkindex(p, index, 3)
4965 imm5 |= 4
4966 imm5 |= index << 3
4967 case ARNG_D:
4968 c.checkindex(p, index, 1)
4969 imm5 |= 8
4970 imm5 |= index << 4
4971 default:
4972 c.ctxt.Diag("invalid arrangement: %v", p)
4973 }
4974 o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
4975
4976 case 79:
4977 rf := int(p.From.Reg)
4978 rt := int(p.To.Reg)
4979 o1 = 7<<25 | 1<<10
4980 var imm5, Q int
4981 index := int(p.From.Index)
4982 switch (p.To.Reg >> 5) & 15 {
4983 case ARNG_16B:
4984 c.checkindex(p, index, 15)
4985 Q = 1
4986 imm5 = 1
4987 imm5 |= index << 1
4988 case ARNG_2D:
4989 c.checkindex(p, index, 1)
4990 Q = 1
4991 imm5 = 8
4992 imm5 |= index << 4
4993 case ARNG_2S:
4994 c.checkindex(p, index, 3)
4995 Q = 0
4996 imm5 = 4
4997 imm5 |= index << 3
4998 case ARNG_4H:
4999 c.checkindex(p, index, 7)
5000 Q = 0
5001 imm5 = 2
5002 imm5 |= index << 2
5003 case ARNG_4S:
5004 c.checkindex(p, index, 3)
5005 Q = 1
5006 imm5 = 4
5007 imm5 |= index << 3
5008 case ARNG_8B:
5009 c.checkindex(p, index, 15)
5010 Q = 0
5011 imm5 = 1
5012 imm5 |= index << 1
5013 case ARNG_8H:
5014 c.checkindex(p, index, 7)
5015 Q = 1
5016 imm5 = 2
5017 imm5 |= index << 2
5018 default:
5019 c.ctxt.Diag("invalid arrangement: %v", p)
5020 }
5021 o1 |= (uint32(Q&1) << 30) | (uint32(imm5&0x1f) << 16)
5022 o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
5023
5024 case 80:
5025 rf := int(p.From.Reg)
5026 rt := int(p.To.Reg)
5027 imm5 := 0
5028 index := int(p.From.Index)
5029 switch p.As {
5030 case AVMOV, AVDUP:
5031 o1 = 1<<30 | 15<<25 | 1<<10
5032 switch (p.From.Reg >> 5) & 15 {
5033 case ARNG_B:
5034 c.checkindex(p, index, 15)
5035 imm5 |= 1
5036 imm5 |= index << 1
5037 case ARNG_H:
5038 c.checkindex(p, index, 7)
5039 imm5 |= 2
5040 imm5 |= index << 2
5041 case ARNG_S:
5042 c.checkindex(p, index, 3)
5043 imm5 |= 4
5044 imm5 |= index << 3
5045 case ARNG_D:
5046 c.checkindex(p, index, 1)
5047 imm5 |= 8
5048 imm5 |= index << 4
5049 default:
5050 c.ctxt.Diag("invalid arrangement: %v", p)
5051 }
5052 default:
5053 c.ctxt.Diag("unsupported op %v", p.As)
5054 }
5055 o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
5056
5057 case 81:
5058 c.checkoffset(p, p.As)
5059 rn := p.From.Reg
5060 o1 = c.oprrr(p, p.As, obj.REG_NONE, rn, obj.REG_NONE)
5061 if o.scond == C_XPOST {
5062 o1 |= 1 << 23
5063 if p.From.Index == 0 {
5064
5065 o1 |= 0x1f << 16
5066 } else {
5067
5068 if isRegShiftOrExt(&p.From) {
5069 c.ctxt.Diag("invalid extended register op: %v\n", p)
5070 }
5071 o1 |= uint32(p.From.Index&0x1f) << 16
5072 }
5073 }
5074 o1 |= uint32(p.To.Offset)
5075
5076
5077 o1 = c.maskOpvldvst(p, o1)
5078
5079 case 82:
5080 rf := int(p.From.Reg)
5081 rt := int(p.To.Reg)
5082 o1 = 7<<25 | 3<<10
5083 var imm5, Q uint32
5084 switch (p.To.Reg >> 5) & 15 {
5085 case ARNG_16B:
5086 Q = 1
5087 imm5 = 1
5088 case ARNG_2D:
5089 Q = 1
5090 imm5 = 8
5091 case ARNG_2S:
5092 Q = 0
5093 imm5 = 4
5094 case ARNG_4H:
5095 Q = 0
5096 imm5 = 2
5097 case ARNG_4S:
5098 Q = 1
5099 imm5 = 4
5100 case ARNG_8B:
5101 Q = 0
5102 imm5 = 1
5103 case ARNG_8H:
5104 Q = 1
5105 imm5 = 2
5106 default:
5107 c.ctxt.Diag("invalid arrangement: %v\n", p)
5108 }
5109 o1 |= (Q & 1 << 30) | (imm5 & 0x1f << 16)
5110 o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
5111
5112 case 83:
5113 af := int((p.From.Reg >> 5) & 15)
5114 at := int((p.To.Reg >> 5) & 15)
5115 if af != at {
5116 c.ctxt.Diag("invalid arrangement: %v\n", p)
5117 }
5118
5119 var Q, size uint32
5120 switch af {
5121 case ARNG_8B:
5122 Q = 0
5123 size = 0
5124 case ARNG_16B:
5125 Q = 1
5126 size = 0
5127 case ARNG_4H:
5128 Q = 0
5129 size = 1
5130 case ARNG_8H:
5131 Q = 1
5132 size = 1
5133 case ARNG_2S:
5134 Q = 0
5135 size = 2
5136 case ARNG_4S:
5137 Q = 1
5138 size = 2
5139 default:
5140 c.ctxt.Diag("invalid arrangement: %v\n", p)
5141 }
5142
5143 if (p.As == AVMOV || p.As == AVRBIT || p.As == AVCNT) && (af != ARNG_16B && af != ARNG_8B) {
5144 c.ctxt.Diag("invalid arrangement: %v", p)
5145 }
5146
5147 if p.As == AVREV32 && (af == ARNG_2S || af == ARNG_4S) {
5148 c.ctxt.Diag("invalid arrangement: %v", p)
5149 }
5150
5151 if p.As == AVREV16 && af != ARNG_8B && af != ARNG_16B {
5152 c.ctxt.Diag("invalid arrangement: %v", p)
5153 }
5154
5155 if p.As == AVRBIT {
5156 size = 1
5157 }
5158
5159 rt, r, rf := p.To.Reg, int16(obj.REG_NONE), p.From.Reg
5160 if p.As == AVMOV {
5161 r = rf
5162 }
5163 o1 = c.oprrr(p, p.As, rt, rf, r)
5164 o1 |= (Q&1)<<30 | (size&3)<<22
5165
5166 case 84:
5167 c.checkoffset(p, p.As)
5168 r := int(p.To.Reg)
5169 o1 = 3 << 26
5170 if o.scond == C_XPOST {
5171 o1 |= 1 << 23
5172 if p.To.Index == 0 {
5173
5174 o1 |= 0x1f << 16
5175 } else {
5176
5177 if isRegShiftOrExt(&p.To) {
5178 c.ctxt.Diag("invalid extended register: %v\n", p)
5179 }
5180 o1 |= uint32(p.To.Index&31) << 16
5181 }
5182 }
5183 o1 |= uint32(p.From.Offset)
5184
5185
5186 o1 = c.maskOpvldvst(p, o1)
5187 o1 |= uint32(r&31) << 5
5188
5189 case 85:
5190 af := int((p.From.Reg >> 5) & 15)
5191 Q := 0
5192 size := 0
5193 switch af {
5194 case ARNG_8B:
5195 Q = 0
5196 size = 0
5197 case ARNG_16B:
5198 Q = 1
5199 size = 0
5200 case ARNG_4H:
5201 Q = 0
5202 size = 1
5203 case ARNG_8H:
5204 Q = 1
5205 size = 1
5206 case ARNG_4S:
5207 Q = 1
5208 size = 2
5209 default:
5210 c.ctxt.Diag("invalid arrangement: %v\n", p)
5211 }
5212 o1 = c.oprrr(p, p.As, p.To.Reg, p.From.Reg, obj.REG_NONE)
5213 o1 |= uint32(Q&1)<<30 | uint32(size&3)<<22
5214
5215 case 86:
5216 at := int((p.To.Reg >> 5) & 15)
5217 r := int(p.From.Offset)
5218 if r > 255 || r < 0 {
5219 c.ctxt.Diag("immediate constant out of range: %v\n", p)
5220 }
5221 rt := int((p.To.Reg) & 31)
5222 Q := 0
5223 switch at {
5224 case ARNG_8B:
5225 Q = 0
5226 case ARNG_16B:
5227 Q = 1
5228 default:
5229 c.ctxt.Diag("invalid arrangement: %v\n", p)
5230 }
5231 o1 = 0xf<<24 | 0xe<<12 | 1<<10
5232 o1 |= (uint32(Q&1) << 30) | (uint32((r>>5)&7) << 16) | (uint32(r&0x1f) << 5) | uint32(rt&31)
5233
5234 case 87:
5235 rf1, rf2 := p.From.Reg, int16(p.From.Offset)
5236 if rf1 == REGTMP || rf2 == REGTMP {
5237 c.ctxt.Diag("cannot use REGTMP as source: %v", p)
5238 }
5239 o1 = ADR(1, 0, REGTMP)
5240 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
5241 c.cursym.AddRel(c.ctxt, obj.Reloc{
5242 Type: objabi.R_ADDRARM64,
5243 Off: int32(c.pc),
5244 Siz: 8,
5245 Sym: p.To.Sym,
5246 Add: p.To.Offset,
5247 })
5248 o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0)
5249
5250 case 88:
5251 rt1, rt2 := p.To.Reg, int16(p.To.Offset)
5252 o1 = ADR(1, 0, REGTMP)
5253 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
5254 c.cursym.AddRel(c.ctxt, obj.Reloc{
5255 Type: objabi.R_ADDRARM64,
5256 Off: int32(c.pc),
5257 Siz: 8,
5258 Sym: p.From.Sym,
5259 Add: p.From.Offset,
5260 })
5261 o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1)
5262
5263 case 89:
5264 switch p.As {
5265 case AVADD:
5266 o1 = 5<<28 | 7<<25 | 7<<21 | 1<<15 | 1<<10
5267
5268 case AVSUB:
5269 o1 = 7<<28 | 7<<25 | 7<<21 | 1<<15 | 1<<10
5270
5271 default:
5272 c.ctxt.Diag("bad opcode: %v\n", p)
5273 break
5274 }
5275
5276 rf := int(p.From.Reg)
5277 rt := int(p.To.Reg)
5278 r := int(p.Reg)
5279 if r == obj.REG_NONE {
5280 r = rt
5281 }
5282 o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
5283
5284
5285
5286
5287
5288
5289 case 90:
5290 o1 = 0x0
5291
5292 case 91:
5293 imm := uint32(p.From.Offset)
5294 r := p.From.Reg
5295 var v uint32
5296 var ok bool
5297 if p.To.Type == obj.TYPE_CONST {
5298 v = uint32(p.To.Offset)
5299 ok = v <= 31
5300 } else {
5301 v, ok = prfopfield[SpecialOperand(p.To.Offset)]
5302 }
5303 if !ok {
5304 c.ctxt.Diag("illegal prefetch operation:\n%v", p)
5305 }
5306
5307 o1 = c.opirr(p, p.As)
5308 o1 |= (uint32(r&31) << 5) | ((imm >> 3) & 0xfff << 10) | (v & 31)
5309
5310 case 92:
5311 rf := int(p.From.Reg)
5312 rt := int(p.To.Reg)
5313 imm4 := 0
5314 imm5 := 0
5315 o1 = 3<<29 | 7<<25 | 1<<10
5316 index1 := int(p.To.Index)
5317 index2 := int(p.From.Index)
5318 if ((p.To.Reg >> 5) & 15) != ((p.From.Reg >> 5) & 15) {
5319 c.ctxt.Diag("operand mismatch: %v", p)
5320 }
5321 switch (p.To.Reg >> 5) & 15 {
5322 case ARNG_B:
5323 c.checkindex(p, index1, 15)
5324 c.checkindex(p, index2, 15)
5325 imm5 |= 1
5326 imm5 |= index1 << 1
5327 imm4 |= index2
5328 case ARNG_H:
5329 c.checkindex(p, index1, 7)
5330 c.checkindex(p, index2, 7)
5331 imm5 |= 2
5332 imm5 |= index1 << 2
5333 imm4 |= index2 << 1
5334 case ARNG_S:
5335 c.checkindex(p, index1, 3)
5336 c.checkindex(p, index2, 3)
5337 imm5 |= 4
5338 imm5 |= index1 << 3
5339 imm4 |= index2 << 2
5340 case ARNG_D:
5341 c.checkindex(p, index1, 1)
5342 c.checkindex(p, index2, 1)
5343 imm5 |= 8
5344 imm5 |= index1 << 4
5345 imm4 |= index2 << 3
5346 default:
5347 c.ctxt.Diag("invalid arrangement: %v", p)
5348 }
5349 o1 |= (uint32(imm5&0x1f) << 16) | (uint32(imm4&0xf) << 11) | (uint32(rf&31) << 5) | uint32(rt&31)
5350
5351 case 93:
5352 af := uint8((p.From.Reg >> 5) & 15)
5353 at := uint8((p.To.Reg >> 5) & 15)
5354 a := uint8((p.Reg >> 5) & 15)
5355 if af != a {
5356 c.ctxt.Diag("invalid arrangement: %v", p)
5357 }
5358
5359 var Q, size uint32
5360 if p.As == AVPMULL2 {
5361 Q = 1
5362 }
5363 switch pack(Q, at, af) {
5364 case pack(0, ARNG_8H, ARNG_8B), pack(1, ARNG_8H, ARNG_16B):
5365 size = 0
5366 case pack(0, ARNG_1Q, ARNG_1D), pack(1, ARNG_1Q, ARNG_2D):
5367 size = 3
5368 default:
5369 c.ctxt.Diag("operand mismatch: %v\n", p)
5370 }
5371
5372 o1 = c.oprrr(p, p.As, p.To.Reg, p.Reg, p.From.Reg)
5373 o1 |= (Q&1)<<30 | (size&3)<<22
5374
5375 case 94:
5376 af := int(((p.GetFrom3().Reg) >> 5) & 15)
5377 at := int((p.To.Reg >> 5) & 15)
5378 a := int((p.Reg >> 5) & 15)
5379 index := int(p.From.Offset)
5380
5381 if af != a || af != at {
5382 c.ctxt.Diag("invalid arrangement: %v", p)
5383 break
5384 }
5385
5386 var Q uint32
5387 var b int
5388 if af == ARNG_8B {
5389 Q = 0
5390 b = 7
5391 } else if af == ARNG_16B {
5392 Q = 1
5393 b = 15
5394 } else {
5395 c.ctxt.Diag("invalid arrangement, should be B8 or B16: %v", p)
5396 break
5397 }
5398
5399 if index < 0 || index > b {
5400 c.ctxt.Diag("illegal offset: %v", p)
5401 }
5402
5403 o1 = c.opirr(p, p.As)
5404 rf := int((p.GetFrom3().Reg) & 31)
5405 rt := int((p.To.Reg) & 31)
5406 r := int((p.Reg) & 31)
5407
5408 o1 |= ((Q & 1) << 30) | (uint32(r&31) << 16) | (uint32(index&15) << 11) | (uint32(rf&31) << 5) | uint32(rt&31)
5409
5410 case 95:
5411 at := int((p.To.Reg >> 5) & 15)
5412 af := int((p.Reg >> 5) & 15)
5413 shift := int(p.From.Offset)
5414
5415 if af != at {
5416 c.ctxt.Diag("invalid arrangement on op Vn.<T>, Vd.<T>: %v", p)
5417 }
5418
5419 var Q uint32
5420 var imax, esize int
5421
5422 switch af {
5423 case ARNG_8B, ARNG_4H, ARNG_2S:
5424 Q = 0
5425 case ARNG_16B, ARNG_8H, ARNG_4S, ARNG_2D:
5426 Q = 1
5427 default:
5428 c.ctxt.Diag("invalid arrangement on op Vn.<T>, Vd.<T>: %v", p)
5429 }
5430
5431 switch af {
5432 case ARNG_8B, ARNG_16B:
5433 imax = 15
5434 esize = 8
5435 case ARNG_4H, ARNG_8H:
5436 imax = 31
5437 esize = 16
5438 case ARNG_2S, ARNG_4S:
5439 imax = 63
5440 esize = 32
5441 case ARNG_2D:
5442 imax = 127
5443 esize = 64
5444 }
5445
5446 imm := 0
5447 switch p.As {
5448 case AVUSHR, AVSRI, AVUSRA:
5449 imm = esize*2 - shift
5450 if imm < esize || imm > imax {
5451 c.ctxt.Diag("shift out of range: %v", p)
5452 }
5453 case AVSHL, AVSLI:
5454 imm = esize + shift
5455 if imm > imax {
5456 c.ctxt.Diag("shift out of range: %v", p)
5457 }
5458 default:
5459 c.ctxt.Diag("invalid instruction %v\n", p)
5460 }
5461
5462 o1 = c.opirr(p, p.As)
5463 rt := int((p.To.Reg) & 31)
5464 rf := int((p.Reg) & 31)
5465
5466 o1 |= ((Q & 1) << 30) | (uint32(imm&0x7f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
5467
5468 case 96:
5469 af := int((p.From.Reg >> 5) & 15)
5470 rt := int((p.From.Reg) & 31)
5471 rf := int((p.To.Reg) & 31)
5472 r := int(p.To.Index & 31)
5473 index := int(p.From.Index)
5474 offset := c.regoff(&p.To)
5475
5476 if o.scond == C_XPOST {
5477 if (p.To.Index != 0) && (offset != 0) {
5478 c.ctxt.Diag("invalid offset: %v", p)
5479 }
5480 if p.To.Index == 0 && offset == 0 {
5481 c.ctxt.Diag("invalid offset: %v", p)
5482 }
5483 }
5484
5485 if offset != 0 {
5486 r = 31
5487 }
5488
5489 var Q, S, size int
5490 var opcode uint32
5491 switch af {
5492 case ARNG_B:
5493 c.checkindex(p, index, 15)
5494 if o.scond == C_XPOST && offset != 0 && offset != 1 {
5495 c.ctxt.Diag("invalid offset: %v", p)
5496 }
5497 Q = index >> 3
5498 S = (index >> 2) & 1
5499 size = index & 3
5500 opcode = 0
5501 case ARNG_H:
5502 c.checkindex(p, index, 7)
5503 if o.scond == C_XPOST && offset != 0 && offset != 2 {
5504 c.ctxt.Diag("invalid offset: %v", p)
5505 }
5506 Q = index >> 2
5507 S = (index >> 1) & 1
5508 size = (index & 1) << 1
5509 opcode = 2
5510 case ARNG_S:
5511 c.checkindex(p, index, 3)
5512 if o.scond == C_XPOST && offset != 0 && offset != 4 {
5513 c.ctxt.Diag("invalid offset: %v", p)
5514 }
5515 Q = index >> 1
5516 S = index & 1
5517 size = 0
5518 opcode = 4
5519 case ARNG_D:
5520 c.checkindex(p, index, 1)
5521 if o.scond == C_XPOST && offset != 0 && offset != 8 {
5522 c.ctxt.Diag("invalid offset: %v", p)
5523 }
5524 Q = index
5525 S = 0
5526 size = 1
5527 opcode = 4
5528 default:
5529 c.ctxt.Diag("invalid arrangement: %v", p)
5530 }
5531
5532 if o.scond == C_XPOST {
5533 o1 |= 27 << 23
5534 } else {
5535 o1 |= 26 << 23
5536 }
5537
5538 o1 |= (uint32(Q&1) << 30) | (uint32(r&31) << 16) | ((opcode & 7) << 13) | (uint32(S&1) << 12) | (uint32(size&3) << 10) | (uint32(rf&31) << 5) | uint32(rt&31)
5539
5540 case 97:
5541 at := int((p.To.Reg >> 5) & 15)
5542 rt := int((p.To.Reg) & 31)
5543 rf := int((p.From.Reg) & 31)
5544 r := int(p.From.Index & 31)
5545 index := int(p.To.Index)
5546 offset := c.regoff(&p.From)
5547
5548 if o.scond == C_XPOST {
5549 if (p.From.Index != 0) && (offset != 0) {
5550 c.ctxt.Diag("invalid offset: %v", p)
5551 }
5552 if p.From.Index == 0 && offset == 0 {
5553 c.ctxt.Diag("invalid offset: %v", p)
5554 }
5555 }
5556
5557 if offset != 0 {
5558 r = 31
5559 }
5560
5561 Q := 0
5562 S := 0
5563 size := 0
5564 var opcode uint32
5565 switch at {
5566 case ARNG_B:
5567 c.checkindex(p, index, 15)
5568 if o.scond == C_XPOST && offset != 0 && offset != 1 {
5569 c.ctxt.Diag("invalid offset: %v", p)
5570 }
5571 Q = index >> 3
5572 S = (index >> 2) & 1
5573 size = index & 3
5574 opcode = 0
5575 case ARNG_H:
5576 c.checkindex(p, index, 7)
5577 if o.scond == C_XPOST && offset != 0 && offset != 2 {
5578 c.ctxt.Diag("invalid offset: %v", p)
5579 }
5580 Q = index >> 2
5581 S = (index >> 1) & 1
5582 size = (index & 1) << 1
5583 opcode = 2
5584 case ARNG_S:
5585 c.checkindex(p, index, 3)
5586 if o.scond == C_XPOST && offset != 0 && offset != 4 {
5587 c.ctxt.Diag("invalid offset: %v", p)
5588 }
5589 Q = index >> 1
5590 S = index & 1
5591 size = 0
5592 opcode = 4
5593 case ARNG_D:
5594 c.checkindex(p, index, 1)
5595 if o.scond == C_XPOST && offset != 0 && offset != 8 {
5596 c.ctxt.Diag("invalid offset: %v", p)
5597 }
5598 Q = index
5599 S = 0
5600 size = 1
5601 opcode = 4
5602 default:
5603 c.ctxt.Diag("invalid arrangement: %v", p)
5604 }
5605
5606 if o.scond == C_XPOST {
5607 o1 |= 110 << 21
5608 } else {
5609 o1 |= 106 << 21
5610 }
5611
5612 o1 |= (uint32(Q&1) << 30) | (uint32(r&31) << 16) | ((opcode & 7) << 13) | (uint32(S&1) << 12) | (uint32(size&3) << 10) | (uint32(rf&31) << 5) | uint32(rt&31)
5613
5614 case 98:
5615 rt, rf := p.To.Reg, p.From.Reg
5616 if isRegShiftOrExt(&p.From) {
5617
5618 c.checkShiftAmount(p, &p.From)
5619
5620 o1 = c.opldrr(p, p.As, rt, rf, obj.REG_NONE, true)
5621 o1 |= c.encRegShiftOrExt(p, &p.From, p.From.Index)
5622 } else {
5623
5624 o1 = c.opldrr(p, p.As, rt, rf, obj.REG_NONE, false)
5625 o1 |= uint32(p.From.Index&31) << 16
5626 }
5627
5628 case 99:
5629 rt, rf := p.To.Reg, p.From.Reg
5630 if isRegShiftOrExt(&p.To) {
5631
5632 c.checkShiftAmount(p, &p.To)
5633
5634 o1 = c.opstrr(p, p.As, rf, rt, obj.REG_NONE, true)
5635 o1 |= c.encRegShiftOrExt(p, &p.To, p.To.Index)
5636 } else {
5637
5638 o1 = c.opstrr(p, p.As, rf, rt, obj.REG_NONE, false)
5639 o1 |= uint32(p.To.Index&31) << 16
5640 }
5641
5642 case 100:
5643 af := int((p.From.Reg >> 5) & 15)
5644 at := int((p.To.Reg >> 5) & 15)
5645 if af != at {
5646 c.ctxt.Diag("invalid arrangement: %v\n", p)
5647 }
5648 var q, len uint32
5649 switch af {
5650 case ARNG_8B:
5651 q = 0
5652 case ARNG_16B:
5653 q = 1
5654 default:
5655 c.ctxt.Diag("invalid arrangement: %v", p)
5656 }
5657 rf := int(p.From.Reg)
5658 rt := int(p.To.Reg)
5659 offset := int(p.GetFrom3().Offset)
5660 opcode := (offset >> 12) & 15
5661 switch opcode {
5662 case 0x7:
5663 len = 0
5664 case 0xa:
5665 len = 1
5666 case 0x6:
5667 len = 2
5668 case 0x2:
5669 len = 3
5670 default:
5671 c.ctxt.Diag("invalid register numbers in ARM64 register list: %v", p)
5672 }
5673 var op uint32
5674 switch p.As {
5675 case AVTBL:
5676 op = 0
5677 case AVTBX:
5678 op = 1
5679 }
5680 o1 = q<<30 | 0xe<<24 | len<<13 | op<<12
5681 o1 |= (uint32(rf&31) << 16) | uint32(offset&31)<<5 | uint32(rt&31)
5682
5683 case 102:
5684 o1 = c.opirr(p, p.As)
5685 rf := p.Reg
5686 af := uint8((p.Reg >> 5) & 15)
5687 at := uint8((p.To.Reg >> 5) & 15)
5688 shift := int(p.From.Offset)
5689 if p.As == AVUXTL || p.As == AVUXTL2 {
5690 rf = p.From.Reg
5691 af = uint8((p.From.Reg >> 5) & 15)
5692 shift = 0
5693 }
5694
5695 Q := (o1 >> 30) & 1
5696 var immh, width uint8
5697 switch pack(Q, af, at) {
5698 case pack(0, ARNG_8B, ARNG_8H):
5699 immh, width = 1, 8
5700 case pack(1, ARNG_16B, ARNG_8H):
5701 immh, width = 1, 8
5702 case pack(0, ARNG_4H, ARNG_4S):
5703 immh, width = 2, 16
5704 case pack(1, ARNG_8H, ARNG_4S):
5705 immh, width = 2, 16
5706 case pack(0, ARNG_2S, ARNG_2D):
5707 immh, width = 4, 32
5708 case pack(1, ARNG_4S, ARNG_2D):
5709 immh, width = 4, 32
5710 default:
5711 c.ctxt.Diag("operand mismatch: %v\n", p)
5712 }
5713 if !(0 <= shift && shift <= int(width-1)) {
5714 c.ctxt.Diag("shift amount out of range: %v\n", p)
5715 }
5716 o1 |= uint32(immh)<<19 | uint32(shift)<<16 | uint32(rf&31)<<5 | uint32(p.To.Reg&31)
5717
5718 case 103:
5719 ta := (p.From.Reg >> 5) & 15
5720 tm := (p.Reg >> 5) & 15
5721 td := (p.To.Reg >> 5) & 15
5722 tn := ((p.GetFrom3().Reg) >> 5) & 15
5723
5724 if ta != tm || ta != tn || ta != td || ta != ARNG_16B {
5725 c.ctxt.Diag("invalid arrangement: %v", p)
5726 break
5727 }
5728
5729 o1 = c.oprrrr(p, p.As, p.To.Reg, p.GetFrom3().Reg, p.Reg, p.From.Reg)
5730
5731 case 104:
5732 af := ((p.GetFrom3().Reg) >> 5) & 15
5733 at := (p.To.Reg >> 5) & 15
5734 a := (p.Reg >> 5) & 15
5735 index := int(p.From.Offset)
5736
5737 if af != a || af != at {
5738 c.ctxt.Diag("invalid arrangement: %v", p)
5739 break
5740 }
5741
5742 if af != ARNG_2D {
5743 c.ctxt.Diag("invalid arrangement, should be D2: %v", p)
5744 break
5745 }
5746
5747 if index < 0 || index > 63 {
5748 c.ctxt.Diag("illegal offset: %v", p)
5749 }
5750
5751 o1 = c.opirr(p, p.As)
5752 rf := (p.GetFrom3().Reg) & 31
5753 rt := (p.To.Reg) & 31
5754 r := (p.Reg) & 31
5755
5756 o1 |= (uint32(r&31) << 16) | (uint32(index&63) << 10) | (uint32(rf&31) << 5) | uint32(rt&31)
5757
5758 case 105:
5759 af := uint8((p.From.Reg >> 5) & 15)
5760 at := uint8((p.To.Reg >> 5) & 15)
5761 a := uint8((p.Reg >> 5) & 15)
5762 if at != a {
5763 c.ctxt.Diag("invalid arrangement: %v", p)
5764 break
5765 }
5766
5767 var Q, size uint32
5768 if p.As == AVUADDW2 {
5769 Q = 1
5770 }
5771 switch pack(Q, at, af) {
5772 case pack(0, ARNG_8H, ARNG_8B), pack(1, ARNG_8H, ARNG_16B):
5773 size = 0
5774 case pack(0, ARNG_4S, ARNG_4H), pack(1, ARNG_4S, ARNG_8H):
5775 size = 1
5776 case pack(0, ARNG_2D, ARNG_2S), pack(1, ARNG_2D, ARNG_4S):
5777 size = 2
5778 default:
5779 c.ctxt.Diag("operand mismatch: %v\n", p)
5780 }
5781
5782 o1 = c.oprrr(p, p.As, p.To.Reg, p.Reg, p.From.Reg)
5783 o1 |= (Q&1)<<30 | (size&3)<<22
5784
5785 case 106:
5786 rs := p.From.Reg
5787 rt := p.GetTo2().Reg
5788 rb := p.To.Reg
5789 rs1 := int16(p.From.Offset)
5790 rt1 := int16(p.GetTo2().Offset)
5791
5792 enc, ok := atomicCASP[p.As]
5793 if !ok {
5794 c.ctxt.Diag("invalid CASP-like atomic instructions: %v\n", p)
5795 }
5796
5797 switch {
5798 case rs&1 != 0:
5799 c.ctxt.Diag("source register pair must start from even register: %v\n", p)
5800 break
5801 case rt&1 != 0:
5802 c.ctxt.Diag("destination register pair must start from even register: %v\n", p)
5803 break
5804 case rs != rs1-1:
5805 c.ctxt.Diag("source register pair must be contiguous: %v\n", p)
5806 break
5807 case rt != rt1-1:
5808 c.ctxt.Diag("destination register pair must be contiguous: %v\n", p)
5809 break
5810 }
5811
5812 if rt == REG_RSP {
5813 c.ctxt.Diag("illegal destination register: %v\n", p)
5814 }
5815 o1 |= enc | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
5816
5817 case 107:
5818 op, ok := sysInstFields[SpecialOperand(p.From.Offset)]
5819 if !ok || (p.As == ATLBI && op.cn != 8) || (p.As == ADC && op.cn != 7) {
5820 c.ctxt.Diag("illegal argument: %v\n", p)
5821 break
5822 }
5823 o1 = c.opirr(p, p.As)
5824 if op.hasOperand2 {
5825 if p.To.Reg == obj.REG_NONE {
5826 c.ctxt.Diag("missing register at operand 2: %v\n", p)
5827 }
5828 o1 |= uint32(p.To.Reg & 0x1F)
5829 } else {
5830 if p.To.Reg != obj.REG_NONE || p.Reg != obj.REG_NONE {
5831 c.ctxt.Diag("extraneous register at operand 2: %v\n", p)
5832 }
5833 o1 |= uint32(0x1F)
5834 }
5835 o1 |= uint32(SYSARG4(int(op.op1), int(op.cn), int(op.cm), int(op.op2)))
5836
5837 case 108:
5838 o1 = SYSHINT(32)
5839 if p.From.Type != obj.TYPE_SPECIAL {
5840 c.ctxt.Diag("missing operand: %v\n", p)
5841 break
5842 }
5843 switch SpecialOperand(p.From.Offset) {
5844 case SPOP_C:
5845 o1 |= 1 << 6
5846 case SPOP_J:
5847 o1 |= 2 << 6
5848 case SPOP_JC:
5849 o1 |= 3 << 6
5850 default:
5851 c.ctxt.Diag("illegal argument: %v\n", p)
5852 break
5853 }
5854 }
5855 out[0] = o1
5856 out[1] = o2
5857 out[2] = o3
5858 out[3] = o4
5859 out[4] = o5
5860
5861 return o.size(c.ctxt, p) / 4
5862 }
5863
5864 func (c *ctxt7) addrRelocType(p *obj.Prog) objabi.RelocType {
5865 switch movesize(p.As) {
5866 case 0:
5867 return objabi.R_ARM64_PCREL_LDST8
5868 case 1:
5869 return objabi.R_ARM64_PCREL_LDST16
5870 case 2:
5871 return objabi.R_ARM64_PCREL_LDST32
5872 case 3:
5873 return objabi.R_ARM64_PCREL_LDST64
5874 default:
5875 c.ctxt.Diag("use R_ADDRARM64 relocation type for: %v\n", p)
5876 }
5877 return -1
5878 }
5879
5880
5886 func (c *ctxt7) oprrr(p *obj.Prog, a obj.As, rd, rn, rm int16) uint32 {
5887 var op uint32
5888
5889 switch a {
5890 case AADC:
5891 op = S64 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10
5892
5893 case AADCW:
5894 op = S32 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10
5895
5896 case AADCS:
5897 op = S64 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10
5898
5899 case AADCSW:
5900 op = S32 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10
5901
5902 case ANGC, ASBC:
5903 op = S64 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10
5904
5905 case ANGCS, ASBCS:
5906 op = S64 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10
5907
5908 case ANGCW, ASBCW:
5909 op = S32 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10
5910
5911 case ANGCSW, ASBCSW:
5912 op = S32 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10
5913
5914 case AADD:
5915 op = S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
5916
5917 case AADDW:
5918 op = S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
5919
5920 case ACMN, AADDS:
5921 op = S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
5922
5923 case ACMNW, AADDSW:
5924 op = S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
5925
5926 case ASUB:
5927 op = S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
5928
5929 case ASUBW:
5930 op = S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
5931
5932 case ACMP, ASUBS:
5933 op = S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
5934
5935 case ACMPW, ASUBSW:
5936 op = S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
5937
5938 case AAND:
5939 op = S64 | 0<<29 | 0xA<<24
5940
5941 case AANDW:
5942 op = S32 | 0<<29 | 0xA<<24
5943
5944 case AMOVD, AORR:
5945 op = S64 | 1<<29 | 0xA<<24
5946
5947
5948 case AMOVWU, AORRW:
5949 op = S32 | 1<<29 | 0xA<<24
5950
5951 case AEOR:
5952 op = S64 | 2<<29 | 0xA<<24
5953
5954 case AEORW:
5955 op = S32 | 2<<29 | 0xA<<24
5956
5957 case AANDS, ATST:
5958 op = S64 | 3<<29 | 0xA<<24
5959
5960 case AANDSW, ATSTW:
5961 op = S32 | 3<<29 | 0xA<<24
5962
5963 case ABIC:
5964 op = S64 | 0<<29 | 0xA<<24 | 1<<21
5965
5966 case ABICW:
5967 op = S32 | 0<<29 | 0xA<<24 | 1<<21
5968
5969 case ABICS:
5970 op = S64 | 3<<29 | 0xA<<24 | 1<<21
5971
5972 case ABICSW:
5973 op = S32 | 3<<29 | 0xA<<24 | 1<<21
5974
5975 case AEON:
5976 op = S64 | 2<<29 | 0xA<<24 | 1<<21
5977
5978 case AEONW:
5979 op = S32 | 2<<29 | 0xA<<24 | 1<<21
5980
5981 case AMVN, AORN:
5982 op = S64 | 1<<29 | 0xA<<24 | 1<<21
5983
5984 case AMVNW, AORNW:
5985 op = S32 | 1<<29 | 0xA<<24 | 1<<21
5986
5987 case AASR:
5988 op = S64 | OPDP2(10)
5989
5990 case AASRW:
5991 op = S32 | OPDP2(10)
5992
5993 case ALSL:
5994 op = S64 | OPDP2(8)
5995
5996 case ALSLW:
5997 op = S32 | OPDP2(8)
5998
5999 case ALSR:
6000 op = S64 | OPDP2(9)
6001
6002 case ALSRW:
6003 op = S32 | OPDP2(9)
6004
6005 case AROR:
6006 op = S64 | OPDP2(11)
6007
6008 case ARORW:
6009 op = S32 | OPDP2(11)
6010
6011 case ACCMN:
6012 op = S64 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4
6013
6014 case ACCMNW:
6015 op = S32 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4
6016
6017 case ACCMP:
6018 op = S64 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4
6019
6020 case ACCMPW:
6021 op = S32 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4
6022
6023 case ACRC32B:
6024 op = S32 | OPDP2(16)
6025
6026 case ACRC32H:
6027 op = S32 | OPDP2(17)
6028
6029 case ACRC32W:
6030 op = S32 | OPDP2(18)
6031
6032 case ACRC32X:
6033 op = S64 | OPDP2(19)
6034
6035 case ACRC32CB:
6036 op = S32 | OPDP2(20)
6037
6038 case ACRC32CH:
6039 op = S32 | OPDP2(21)
6040
6041 case ACRC32CW:
6042 op = S32 | OPDP2(22)
6043
6044 case ACRC32CX:
6045 op = S64 | OPDP2(23)
6046
6047 case ACSEL:
6048 op = S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
6049
6050 case ACSELW:
6051 op = S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
6052
6053 case ACSET:
6054 op = S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
6055
6056 case ACSETW:
6057 op = S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
6058
6059 case ACSETM:
6060 op = S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
6061
6062 case ACSETMW:
6063 op = S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
6064
6065 case ACINC, ACSINC:
6066 op = S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
6067
6068 case ACINCW, ACSINCW:
6069 op = S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
6070
6071 case ACINV, ACSINV:
6072 op = S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
6073
6074 case ACINVW, ACSINVW:
6075 op = S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
6076
6077 case ACNEG, ACSNEG:
6078 op = S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
6079
6080 case ACNEGW, ACSNEGW:
6081 op = S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
6082
6083 case AMUL, AMADD:
6084 op = S64 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15
6085
6086 case AMULW, AMADDW:
6087 op = S32 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15
6088
6089 case AMNEG, AMSUB:
6090 op = S64 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15
6091
6092 case AMNEGW, AMSUBW:
6093 op = S32 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15
6094
6095 case AMRS:
6096 op = SYSOP(1, 2, 0, 0, 0, 0, 0)
6097
6098 case AMSR:
6099 op = SYSOP(0, 2, 0, 0, 0, 0, 0)
6100
6101 case ANEG:
6102 op = S64 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21
6103
6104 case ANEGW:
6105 op = S32 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21
6106
6107 case ANEGS:
6108 op = S64 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21
6109
6110 case ANEGSW:
6111 op = S32 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21
6112
6113 case AREM, ASDIV:
6114 op = S64 | OPDP2(3)
6115
6116 case AREMW, ASDIVW:
6117 op = S32 | OPDP2(3)
6118
6119 case ASMULL, ASMADDL:
6120 op = OPDP3(1, 0, 1, 0)
6121
6122 case ASMNEGL, ASMSUBL:
6123 op = OPDP3(1, 0, 1, 1)
6124
6125 case ASMULH:
6126 op = OPDP3(1, 0, 2, 0)
6127
6128 case AUMULL, AUMADDL:
6129 op = OPDP3(1, 0, 5, 0)
6130
6131 case AUMNEGL, AUMSUBL:
6132 op = OPDP3(1, 0, 5, 1)
6133
6134 case AUMULH:
6135 op = OPDP3(1, 0, 6, 0)
6136
6137 case AUREM, AUDIV:
6138 op = S64 | OPDP2(2)
6139
6140 case AUREMW, AUDIVW:
6141 op = S32 | OPDP2(2)
6142
6143 case AAESE:
6144 op = 0x4E<<24 | 2<<20 | 8<<16 | 4<<12 | 2<<10
6145
6146 case AAESD:
6147 op = 0x4E<<24 | 2<<20 | 8<<16 | 5<<12 | 2<<10
6148
6149 case AAESMC:
6150 op = 0x4E<<24 | 2<<20 | 8<<16 | 6<<12 | 2<<10
6151
6152 case AAESIMC:
6153 op = 0x4E<<24 | 2<<20 | 8<<16 | 7<<12 | 2<<10
6154
6155 case ASHA1C:
6156 op = 0x5E<<24 | 0<<12
6157
6158 case ASHA1P:
6159 op = 0x5E<<24 | 1<<12
6160
6161 case ASHA1M:
6162 op = 0x5E<<24 | 2<<12
6163
6164 case ASHA1SU0:
6165 op = 0x5E<<24 | 3<<12
6166
6167 case ASHA256H:
6168 op = 0x5E<<24 | 4<<12
6169
6170 case ASHA256H2:
6171 op = 0x5E<<24 | 5<<12
6172
6173 case ASHA256SU1:
6174 op = 0x5E<<24 | 6<<12
6175
6176 case ASHA1H:
6177 op = 0x5E<<24 | 2<<20 | 8<<16 | 0<<12 | 2<<10
6178
6179 case ASHA1SU1:
6180 op = 0x5E<<24 | 2<<20 | 8<<16 | 1<<12 | 2<<10
6181
6182 case ASHA256SU0:
6183 op = 0x5E<<24 | 2<<20 | 8<<16 | 2<<12 | 2<<10
6184
6185 case ASHA512H:
6186 op = 0xCE<<24 | 3<<21 | 8<<12
6187
6188 case ASHA512H2:
6189 op = 0xCE<<24 | 3<<21 | 8<<12 | 4<<8
6190
6191 case ASHA512SU1:
6192 op = 0xCE<<24 | 3<<21 | 8<<12 | 8<<8
6193
6194 case ASHA512SU0:
6195 op = 0xCE<<24 | 3<<22 | 8<<12
6196
6197 case AFCVTZSD:
6198 op = FPCVTI(1, 0, 1, 3, 0)
6199
6200 case AFCVTZSDW:
6201 op = FPCVTI(0, 0, 1, 3, 0)
6202
6203 case AFCVTZSS:
6204 op = FPCVTI(1, 0, 0, 3, 0)
6205
6206 case AFCVTZSSW:
6207 op = FPCVTI(0, 0, 0, 3, 0)
6208
6209 case AFCVTZUD:
6210 op = FPCVTI(1, 0, 1, 3, 1)
6211
6212 case AFCVTZUDW:
6213 op = FPCVTI(0, 0, 1, 3, 1)
6214
6215 case AFCVTZUS:
6216 op = FPCVTI(1, 0, 0, 3, 1)
6217
6218 case AFCVTZUSW:
6219 op = FPCVTI(0, 0, 0, 3, 1)
6220
6221 case ASCVTFD:
6222 op = FPCVTI(1, 0, 1, 0, 2)
6223
6224 case ASCVTFS:
6225 op = FPCVTI(1, 0, 0, 0, 2)
6226
6227 case ASCVTFWD:
6228 op = FPCVTI(0, 0, 1, 0, 2)
6229
6230 case ASCVTFWS:
6231 op = FPCVTI(0, 0, 0, 0, 2)
6232
6233 case AUCVTFD:
6234 op = FPCVTI(1, 0, 1, 0, 3)
6235
6236 case AUCVTFS:
6237 op = FPCVTI(1, 0, 0, 0, 3)
6238
6239 case AUCVTFWD:
6240 op = FPCVTI(0, 0, 1, 0, 3)
6241
6242 case AUCVTFWS:
6243 op = FPCVTI(0, 0, 0, 0, 3)
6244
6245 case AFADDS:
6246 op = FPOP2S(0, 0, 0, 2)
6247
6248 case AFADDD:
6249 op = FPOP2S(0, 0, 1, 2)
6250
6251 case AFSUBS:
6252 op = FPOP2S(0, 0, 0, 3)
6253
6254 case AFSUBD:
6255 op = FPOP2S(0, 0, 1, 3)
6256
6257 case AFMADDD:
6258 op = FPOP3S(0, 0, 1, 0, 0)
6259
6260 case AFMADDS:
6261 op = FPOP3S(0, 0, 0, 0, 0)
6262
6263 case AFMSUBD:
6264 op = FPOP3S(0, 0, 1, 0, 1)
6265
6266 case AFMSUBS:
6267 op = FPOP3S(0, 0, 0, 0, 1)
6268
6269 case AFNMADDD:
6270 op = FPOP3S(0, 0, 1, 1, 0)
6271
6272 case AFNMADDS:
6273 op = FPOP3S(0, 0, 0, 1, 0)
6274
6275 case AFNMSUBD:
6276 op = FPOP3S(0, 0, 1, 1, 1)
6277
6278 case AFNMSUBS:
6279 op = FPOP3S(0, 0, 0, 1, 1)
6280
6281 case AFMULS:
6282 op = FPOP2S(0, 0, 0, 0)
6283
6284 case AFMULD:
6285 op = FPOP2S(0, 0, 1, 0)
6286
6287 case AFDIVS:
6288 op = FPOP2S(0, 0, 0, 1)
6289
6290 case AFDIVD:
6291 op = FPOP2S(0, 0, 1, 1)
6292
6293 case AFMAXS:
6294 op = FPOP2S(0, 0, 0, 4)
6295
6296 case AFMINS:
6297 op = FPOP2S(0, 0, 0, 5)
6298
6299 case AFMAXD:
6300 op = FPOP2S(0, 0, 1, 4)
6301
6302 case AFMIND:
6303 op = FPOP2S(0, 0, 1, 5)
6304
6305 case AFMAXNMS:
6306 op = FPOP2S(0, 0, 0, 6)
6307
6308 case AFMAXNMD:
6309 op = FPOP2S(0, 0, 1, 6)
6310
6311 case AFMINNMS:
6312 op = FPOP2S(0, 0, 0, 7)
6313
6314 case AFMINNMD:
6315 op = FPOP2S(0, 0, 1, 7)
6316
6317 case AFNMULS:
6318 op = FPOP2S(0, 0, 0, 8)
6319
6320 case AFNMULD:
6321 op = FPOP2S(0, 0, 1, 8)
6322
6323 case AFCMPS:
6324 op = FPCMP(0, 0, 0, 0, 0)
6325
6326 case AFCMPD:
6327 op = FPCMP(0, 0, 1, 0, 0)
6328
6329 case AFCMPES:
6330 op = FPCMP(0, 0, 0, 0, 16)
6331
6332 case AFCMPED:
6333 op = FPCMP(0, 0, 1, 0, 16)
6334
6335 case AFCCMPS:
6336 op = FPCCMP(0, 0, 0, 0)
6337
6338 case AFCCMPD:
6339 op = FPCCMP(0, 0, 1, 0)
6340
6341 case AFCCMPES:
6342 op = FPCCMP(0, 0, 0, 1)
6343
6344 case AFCCMPED:
6345 op = FPCCMP(0, 0, 1, 1)
6346
6347 case AFCSELS:
6348 op = 0x1E<<24 | 0<<22 | 1<<21 | 3<<10
6349
6350 case AFCSELD:
6351 op = 0x1E<<24 | 1<<22 | 1<<21 | 3<<10
6352
6353 case AFMOVS:
6354 op = FPOP1S(0, 0, 0, 0)
6355
6356 case AFABSS:
6357 op = FPOP1S(0, 0, 0, 1)
6358
6359 case AFNEGS:
6360 op = FPOP1S(0, 0, 0, 2)
6361
6362 case AFSQRTS:
6363 op = FPOP1S(0, 0, 0, 3)
6364
6365 case AFCVTSD:
6366 op = FPOP1S(0, 0, 0, 5)
6367
6368 case AFCVTSH:
6369 op = FPOP1S(0, 0, 0, 7)
6370
6371 case AFRINTNS:
6372 op = FPOP1S(0, 0, 0, 8)
6373
6374 case AFRINTPS:
6375 op = FPOP1S(0, 0, 0, 9)
6376
6377 case AFRINTMS:
6378 op = FPOP1S(0, 0, 0, 10)
6379
6380 case AFRINTZS:
6381 op = FPOP1S(0, 0, 0, 11)
6382
6383 case AFRINTAS:
6384 op = FPOP1S(0, 0, 0, 12)
6385
6386 case AFRINTXS:
6387 op = FPOP1S(0, 0, 0, 14)
6388
6389 case AFRINTIS:
6390 op = FPOP1S(0, 0, 0, 15)
6391
6392 case AFMOVD:
6393 op = FPOP1S(0, 0, 1, 0)
6394
6395 case AFABSD:
6396 op = FPOP1S(0, 0, 1, 1)
6397
6398 case AFNEGD:
6399 op = FPOP1S(0, 0, 1, 2)
6400
6401 case AFSQRTD:
6402 op = FPOP1S(0, 0, 1, 3)
6403
6404 case AFCVTDS:
6405 op = FPOP1S(0, 0, 1, 4)
6406
6407 case AFCVTDH:
6408 op = FPOP1S(0, 0, 1, 7)
6409
6410 case AFRINTND:
6411 op = FPOP1S(0, 0, 1, 8)
6412
6413 case AFRINTPD:
6414 op = FPOP1S(0, 0, 1, 9)
6415
6416 case AFRINTMD:
6417 op = FPOP1S(0, 0, 1, 10)
6418
6419 case AFRINTZD:
6420 op = FPOP1S(0, 0, 1, 11)
6421
6422 case AFRINTAD:
6423 op = FPOP1S(0, 0, 1, 12)
6424
6425 case AFRINTXD:
6426 op = FPOP1S(0, 0, 1, 14)
6427
6428 case AFRINTID:
6429 op = FPOP1S(0, 0, 1, 15)
6430
6431 case AFCVTHS:
6432 op = FPOP1S(0, 0, 3, 4)
6433
6434 case AFCVTHD:
6435 op = FPOP1S(0, 0, 3, 5)
6436
6437 case AVADD:
6438 op = 7<<25 | 1<<21 | 1<<15 | 1<<10
6439
6440 case AVSUB:
6441 op = 0x17<<25 | 1<<21 | 1<<15 | 1<<10
6442
6443 case AVADDP:
6444 op = 7<<25 | 1<<21 | 1<<15 | 15<<10
6445
6446 case AVAND:
6447 op = 7<<25 | 1<<21 | 7<<10
6448
6449 case AVBCAX:
6450 op = 0xCE<<24 | 1<<21
6451
6452 case AVCMEQ:
6453 op = 1<<29 | 0x71<<21 | 0x23<<10
6454
6455 case AVCNT:
6456 op = 0xE<<24 | 0x10<<17 | 5<<12 | 2<<10
6457
6458 case AVZIP1:
6459 op = 0xE<<24 | 3<<12 | 2<<10
6460
6461 case AVZIP2:
6462 op = 0xE<<24 | 1<<14 | 3<<12 | 2<<10
6463
6464 case AVEOR:
6465 op = 1<<29 | 0x71<<21 | 7<<10
6466
6467 case AVEOR3:
6468 op = 0xCE << 24
6469
6470 case AVORR:
6471 op = 7<<25 | 5<<21 | 7<<10
6472
6473 case AVREV16:
6474 op = 3<<26 | 2<<24 | 1<<21 | 3<<11
6475
6476 case AVRAX1:
6477 op = 0xCE<<24 | 3<<21 | 1<<15 | 3<<10
6478
6479 case AVREV32:
6480 op = 11<<26 | 2<<24 | 1<<21 | 1<<11
6481
6482 case AVREV64:
6483 op = 3<<26 | 2<<24 | 1<<21 | 1<<11
6484
6485 case AVMOV:
6486 op = 7<<25 | 5<<21 | 7<<10
6487
6488 case AVADDV:
6489 op = 7<<25 | 3<<20 | 3<<15 | 7<<11
6490
6491 case AVUADDLV:
6492 op = 1<<29 | 7<<25 | 3<<20 | 7<<11
6493
6494 case AVFMLA:
6495 op = 7<<25 | 0<<23 | 1<<21 | 3<<14 | 3<<10
6496
6497 case AVFMLS:
6498 op = 7<<25 | 1<<23 | 1<<21 | 3<<14 | 3<<10
6499
6500 case AVPMULL, AVPMULL2:
6501 op = 0xE<<24 | 1<<21 | 0x38<<10
6502
6503 case AVRBIT:
6504 op = 0x2E<<24 | 1<<22 | 0x10<<17 | 5<<12 | 2<<10
6505
6506 case AVLD1, AVLD2, AVLD3, AVLD4:
6507 op = 3<<26 | 1<<22
6508
6509 case AVLD1R, AVLD3R:
6510 op = 0xD<<24 | 1<<22
6511
6512 case AVLD2R, AVLD4R:
6513 op = 0xD<<24 | 3<<21
6514
6515 case AVBIF:
6516 op = 1<<29 | 7<<25 | 7<<21 | 7<<10
6517
6518 case AVBIT:
6519 op = 1<<29 | 0x75<<21 | 7<<10
6520
6521 case AVBSL:
6522 op = 1<<29 | 0x73<<21 | 7<<10
6523
6524 case AVCMTST:
6525 op = 0xE<<24 | 1<<21 | 0x23<<10
6526
6527 case AVUMAX:
6528 op = 1<<29 | 7<<25 | 1<<21 | 0x19<<10
6529
6530 case AVUMIN:
6531 op = 1<<29 | 7<<25 | 1<<21 | 0x1b<<10
6532
6533 case AVUZP1:
6534 op = 7<<25 | 3<<11
6535
6536 case AVUZP2:
6537 op = 7<<25 | 1<<14 | 3<<11
6538
6539 case AVUADDW, AVUADDW2:
6540 op = 0x17<<25 | 1<<21 | 1<<12
6541
6542 case AVTRN1:
6543 op = 7<<25 | 5<<11
6544
6545 case AVTRN2:
6546 op = 7<<25 | 1<<14 | 5<<11
6547
6548 default:
6549 c.ctxt.Diag("%v: bad rrr %d %v", p, a, a)
6550 return 0
6551 }
6552
6553 op |= uint32(rm&0x1f)<<16 | uint32(rn&0x1f)<<5 | uint32(rd&0x1f)
6554
6555 return op
6556 }
6557
6558 func (c *ctxt7) oprrrr(p *obj.Prog, a obj.As, rd, rn, rm, ra int16) uint32 {
6559 return c.oprrr(p, a, rd, rn, rm) | uint32(ra&0x1f)<<10
6560 }
6561
6562
6566 func (c *ctxt7) opirr(p *obj.Prog, a obj.As) uint32 {
6567 switch a {
6568
6569 case AMOVD, AADD:
6570 return S64 | 0<<30 | 0<<29 | 0x11<<24
6571
6572 case ACMN, AADDS:
6573 return S64 | 0<<30 | 1<<29 | 0x11<<24
6574
6575 case AMOVW, AADDW:
6576 return S32 | 0<<30 | 0<<29 | 0x11<<24
6577
6578 case ACMNW, AADDSW:
6579 return S32 | 0<<30 | 1<<29 | 0x11<<24
6580
6581 case ASUB:
6582 return S64 | 1<<30 | 0<<29 | 0x11<<24
6583
6584 case ACMP, ASUBS:
6585 return S64 | 1<<30 | 1<<29 | 0x11<<24
6586
6587 case ASUBW:
6588 return S32 | 1<<30 | 0<<29 | 0x11<<24
6589
6590 case ACMPW, ASUBSW:
6591 return S32 | 1<<30 | 1<<29 | 0x11<<24
6592
6593
6594 case AADR:
6595 return 0<<31 | 0x10<<24
6596
6597 case AADRP:
6598 return 1<<31 | 0x10<<24
6599
6600
6601 case AAND, ABIC:
6602 return S64 | 0<<29 | 0x24<<23
6603
6604 case AANDW, ABICW:
6605 return S32 | 0<<29 | 0x24<<23 | 0<<22
6606
6607 case AORR, AORN:
6608 return S64 | 1<<29 | 0x24<<23
6609
6610 case AORRW, AORNW:
6611 return S32 | 1<<29 | 0x24<<23 | 0<<22
6612
6613 case AEOR, AEON:
6614 return S64 | 2<<29 | 0x24<<23
6615
6616 case AEORW, AEONW:
6617 return S32 | 2<<29 | 0x24<<23 | 0<<22
6618
6619 case AANDS, ABICS, ATST:
6620 return S64 | 3<<29 | 0x24<<23
6621
6622 case AANDSW, ABICSW, ATSTW:
6623 return S32 | 3<<29 | 0x24<<23 | 0<<22
6624
6625 case AASR:
6626 return S64 | 0<<29 | 0x26<<23
6627
6628 case AASRW:
6629 return S32 | 0<<29 | 0x26<<23 | 0<<22
6630
6631
6632 case ABFI:
6633 return S64 | 2<<29 | 0x26<<23 | 1<<22
6634
6635
6636 case ABFIW:
6637 return S32 | 2<<29 | 0x26<<23 | 0<<22
6638
6639
6640 case ABFM:
6641 return S64 | 1<<29 | 0x26<<23 | 1<<22
6642
6643 case ABFMW:
6644 return S32 | 1<<29 | 0x26<<23 | 0<<22
6645
6646 case ASBFM:
6647 return S64 | 0<<29 | 0x26<<23 | 1<<22
6648
6649 case ASBFMW:
6650 return S32 | 0<<29 | 0x26<<23 | 0<<22
6651
6652 case AUBFM:
6653 return S64 | 2<<29 | 0x26<<23 | 1<<22
6654
6655 case AUBFMW:
6656 return S32 | 2<<29 | 0x26<<23 | 0<<22
6657
6658 case ABFXIL:
6659 return S64 | 1<<29 | 0x26<<23 | 1<<22
6660
6661 case ABFXILW:
6662 return S32 | 1<<29 | 0x26<<23 | 0<<22
6663
6664 case AEXTR:
6665 return S64 | 0<<29 | 0x27<<23 | 1<<22 | 0<<21
6666
6667 case AEXTRW:
6668 return S32 | 0<<29 | 0x27<<23 | 0<<22 | 0<<21
6669
6670 case ACBNZ:
6671 return S64 | 0x1A<<25 | 1<<24
6672
6673 case ACBNZW:
6674 return S32 | 0x1A<<25 | 1<<24
6675
6676 case ACBZ:
6677 return S64 | 0x1A<<25 | 0<<24
6678
6679 case ACBZW:
6680 return S32 | 0x1A<<25 | 0<<24
6681
6682 case ACCMN:
6683 return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4
6684
6685 case ACCMNW:
6686 return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4
6687
6688 case ACCMP:
6689 return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4
6690
6691 case ACCMPW:
6692 return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4
6693
6694 case AMOVK:
6695 return S64 | 3<<29 | 0x25<<23
6696
6697 case AMOVKW:
6698 return S32 | 3<<29 | 0x25<<23
6699
6700 case AMOVN:
6701 return S64 | 0<<29 | 0x25<<23
6702
6703 case AMOVNW:
6704 return S32 | 0<<29 | 0x25<<23
6705
6706 case AMOVZ:
6707 return S64 | 2<<29 | 0x25<<23
6708
6709 case AMOVZW:
6710 return S32 | 2<<29 | 0x25<<23
6711
6712 case AMSR:
6713 return SYSOP(0, 0, 0, 4, 0, 0, 0x1F)
6714
6715 case AAT,
6716 ADC,
6717 AIC,
6718 ATLBI,
6719 ASYS:
6720 return SYSOP(0, 1, 0, 0, 0, 0, 0)
6721
6722 case ASYSL:
6723 return SYSOP(1, 1, 0, 0, 0, 0, 0)
6724
6725 case ATBZ:
6726 return 0x36 << 24
6727
6728 case ATBNZ:
6729 return 0x37 << 24
6730
6731 case ADSB:
6732 return SYSOP(0, 0, 3, 3, 0, 4, 0x1F)
6733
6734 case ADMB:
6735 return SYSOP(0, 0, 3, 3, 0, 5, 0x1F)
6736
6737 case AISB:
6738 return SYSOP(0, 0, 3, 3, 0, 6, 0x1F)
6739
6740 case AHINT:
6741 return SYSHINT(0)
6742
6743 case AVEXT:
6744 return 0x2E<<24 | 0<<23 | 0<<21 | 0<<15
6745
6746 case AVUSHR:
6747 return 0x5E<<23 | 1<<10
6748
6749 case AVSHL:
6750 return 0x1E<<23 | 21<<10
6751
6752 case AVSRI:
6753 return 0x5E<<23 | 17<<10
6754
6755 case AVSLI:
6756 return 0x5E<<23 | 21<<10
6757
6758 case AVUSHLL, AVUXTL:
6759 return 1<<29 | 15<<24 | 0x29<<10
6760
6761 case AVUSHLL2, AVUXTL2:
6762 return 3<<29 | 15<<24 | 0x29<<10
6763
6764 case AVXAR:
6765 return 0xCE<<24 | 1<<23
6766
6767 case AVUSRA:
6768 return 1<<29 | 15<<24 | 5<<10
6769
6770 case APRFM:
6771 return 0xf9<<24 | 2<<22
6772 }
6773
6774 c.ctxt.Diag("%v: bad irr %v", p, a)
6775 return 0
6776 }
6777
6778 func (c *ctxt7) opbit(p *obj.Prog, a obj.As) uint32 {
6779 switch a {
6780 case ACLS:
6781 return S64 | OPBIT(5)
6782
6783 case ACLSW:
6784 return S32 | OPBIT(5)
6785
6786 case ACLZ:
6787 return S64 | OPBIT(4)
6788
6789 case ACLZW:
6790 return S32 | OPBIT(4)
6791
6792 case ARBIT:
6793 return S64 | OPBIT(0)
6794
6795 case ARBITW:
6796 return S32 | OPBIT(0)
6797
6798 case AREV:
6799 return S64 | OPBIT(3)
6800
6801 case AREVW:
6802 return S32 | OPBIT(2)
6803
6804 case AREV16:
6805 return S64 | OPBIT(1)
6806
6807 case AREV16W:
6808 return S32 | OPBIT(1)
6809
6810 case AREV32:
6811 return S64 | OPBIT(2)
6812
6813 default:
6814 c.ctxt.Diag("bad bit op\n%v", p)
6815 return 0
6816 }
6817 }
6818
6819
6822 func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As, rd, rn, rm int16, extend bool) uint32 {
6823 extension := uint32(0)
6824 if !extend {
6825 if isADDop(a) {
6826 extension = LSL0_64
6827 }
6828 if isADDWop(a) {
6829 extension = LSL0_32
6830 }
6831 }
6832
6833 var op uint32
6834
6835 switch a {
6836 case AADD:
6837 op = S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
6838
6839 case AADDW:
6840 op = S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
6841
6842 case ACMN, AADDS:
6843 op = S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
6844
6845 case ACMNW, AADDSW:
6846 op = S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
6847
6848 case ASUB:
6849 op = S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
6850
6851 case ASUBW:
6852 op = S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
6853
6854 case ACMP, ASUBS:
6855 op = S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
6856
6857 case ACMPW, ASUBSW:
6858 op = S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
6859
6860 default:
6861 c.ctxt.Diag("bad opxrrr %v\n%v", a, p)
6862 return 0
6863 }
6864
6865 op |= uint32(rm&0x1f)<<16 | uint32(rn&0x1f)<<5 | uint32(rd&0x1f)
6866
6867 return op
6868 }
6869
6870 func (c *ctxt7) opimm(p *obj.Prog, a obj.As) uint32 {
6871 switch a {
6872 case ASVC:
6873 return 0xD4<<24 | 0<<21 | 1
6874
6875 case AHVC:
6876 return 0xD4<<24 | 0<<21 | 2
6877
6878 case ASMC:
6879 return 0xD4<<24 | 0<<21 | 3
6880
6881 case ABRK:
6882 return 0xD4<<24 | 1<<21 | 0
6883
6884 case AHLT:
6885 return 0xD4<<24 | 2<<21 | 0
6886
6887 case ADCPS1:
6888 return 0xD4<<24 | 5<<21 | 1
6889
6890 case ADCPS2:
6891 return 0xD4<<24 | 5<<21 | 2
6892
6893 case ADCPS3:
6894 return 0xD4<<24 | 5<<21 | 3
6895
6896 case ACLREX:
6897 return SYSOP(0, 0, 3, 3, 0, 2, 0x1F)
6898 }
6899
6900 c.ctxt.Diag("%v: bad imm %v", p, a)
6901 return 0
6902 }
6903
6904 func (c *ctxt7) brdist(p *obj.Prog, preshift int, flen int, shift int) int64 {
6905 v := int64(0)
6906 t := int64(0)
6907 var q *obj.Prog
6908 if p.To.Type == obj.TYPE_BRANCH {
6909 q = p.To.Target()
6910 } else if p.From.Type == obj.TYPE_BRANCH {
6911 q = p.From.Target()
6912 }
6913 if q == nil {
6914
6915
6916 q = p.Pool
6917 }
6918 if q != nil {
6919 v = (q.Pc >> uint(preshift)) - (c.pc >> uint(preshift))
6920 if (v & ((1 << uint(shift)) - 1)) != 0 {
6921 c.ctxt.Diag("misaligned label\n%v", p)
6922 }
6923 v >>= uint(shift)
6924 t = int64(1) << uint(flen-1)
6925 if v < -t || v >= t {
6926 c.ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, c.blitrl, p, q)
6927 panic("branch too far")
6928 }
6929 }
6930
6931 return v & ((t << 1) - 1)
6932 }
6933
6934
6937 func (c *ctxt7) opbra(p *obj.Prog, a obj.As) uint32 {
6938 switch a {
6939 case ABEQ:
6940 return OPBcc(0x0)
6941
6942 case ABNE:
6943 return OPBcc(0x1)
6944
6945 case ABCS:
6946 return OPBcc(0x2)
6947
6948 case ABHS:
6949 return OPBcc(0x2)
6950
6951 case ABCC:
6952 return OPBcc(0x3)
6953
6954 case ABLO:
6955 return OPBcc(0x3)
6956
6957 case ABMI:
6958 return OPBcc(0x4)
6959
6960 case ABPL:
6961 return OPBcc(0x5)
6962
6963 case ABVS:
6964 return OPBcc(0x6)
6965
6966 case ABVC:
6967 return OPBcc(0x7)
6968
6969 case ABHI:
6970 return OPBcc(0x8)
6971
6972 case ABLS:
6973 return OPBcc(0x9)
6974
6975 case ABGE:
6976 return OPBcc(0xa)
6977
6978 case ABLT:
6979 return OPBcc(0xb)
6980
6981 case ABGT:
6982 return OPBcc(0xc)
6983
6984 case ABLE:
6985 return OPBcc(0xd)
6986
6987 case AB:
6988 return 0<<31 | 5<<26
6989
6990 case ABL:
6991 return 1<<31 | 5<<26
6992 }
6993
6994 c.ctxt.Diag("%v: bad bra %v", p, a)
6995 return 0
6996 }
6997
6998 func (c *ctxt7) opbrr(p *obj.Prog, a obj.As) uint32 {
6999 switch a {
7000 case ABL:
7001 return OPBLR(1)
7002
7003 case AB:
7004 return OPBLR(0)
7005
7006 case obj.ARET:
7007 return OPBLR(2)
7008 }
7009
7010 c.ctxt.Diag("%v: bad brr %v", p, a)
7011 return 0
7012 }
7013
7014 func (c *ctxt7) op0(p *obj.Prog, a obj.As) uint32 {
7015 switch a {
7016 case ADRPS:
7017 return 0x6B<<25 | 5<<21 | 0x1F<<16 | 0x1F<<5
7018
7019 case AERET:
7020 return 0x6B<<25 | 4<<21 | 0x1F<<16 | 0<<10 | 0x1F<<5
7021
7022 case ANOOP:
7023 return SYSHINT(0)
7024
7025 case AYIELD:
7026 return SYSHINT(1)
7027
7028 case AWFE:
7029 return SYSHINT(2)
7030
7031 case AWFI:
7032 return SYSHINT(3)
7033
7034 case ASEV:
7035 return SYSHINT(4)
7036
7037 case ASEVL:
7038 return SYSHINT(5)
7039
7040 case APACIASP:
7041 return SYSHINT(25)
7042
7043 case AAUTIASP:
7044 return SYSHINT(29)
7045
7046 case APACIBSP:
7047 return SYSHINT(27)
7048
7049 case AAUTIBSP:
7050 return SYSHINT(31)
7051
7052 case AAUTIA1716:
7053 return SYSHINT(12)
7054
7055 case AAUTIB1716:
7056 return SYSHINT(14)
7057 }
7058
7059 c.ctxt.Diag("%v: bad op0 %v", p, a)
7060 return 0
7061 }
7062
7063
7066 func (c *ctxt7) opload(p *obj.Prog, a obj.As) uint32 {
7067 switch a {
7068 case ALDAR:
7069 return LDSTX(3, 1, 1, 0, 1) | 0x1F<<10
7070
7071 case ALDARW:
7072 return LDSTX(2, 1, 1, 0, 1) | 0x1F<<10
7073
7074 case ALDARB:
7075 return LDSTX(0, 1, 1, 0, 1) | 0x1F<<10
7076
7077 case ALDARH:
7078 return LDSTX(1, 1, 1, 0, 1) | 0x1F<<10
7079
7080 case ALDAXP:
7081 return LDSTX(3, 0, 1, 1, 1)
7082
7083 case ALDAXPW:
7084 return LDSTX(2, 0, 1, 1, 1)
7085
7086 case ALDAXR:
7087 return LDSTX(3, 0, 1, 0, 1) | 0x1F<<10
7088
7089 case ALDAXRW:
7090 return LDSTX(2, 0, 1, 0, 1) | 0x1F<<10
7091
7092 case ALDAXRB:
7093 return LDSTX(0, 0, 1, 0, 1) | 0x1F<<10
7094
7095 case ALDAXRH:
7096 return LDSTX(1, 0, 1, 0, 1) | 0x1F<<10
7097
7098 case ALDXR:
7099 return LDSTX(3, 0, 1, 0, 0) | 0x1F<<10
7100
7101 case ALDXRB:
7102 return LDSTX(0, 0, 1, 0, 0) | 0x1F<<10
7103
7104 case ALDXRH:
7105 return LDSTX(1, 0, 1, 0, 0) | 0x1F<<10
7106
7107 case ALDXRW:
7108 return LDSTX(2, 0, 1, 0, 0) | 0x1F<<10
7109
7110 case ALDXP:
7111 return LDSTX(3, 0, 1, 1, 0)
7112
7113 case ALDXPW:
7114 return LDSTX(2, 0, 1, 1, 0)
7115 }
7116
7117 c.ctxt.Diag("bad opload %v\n%v", a, p)
7118 return 0
7119 }
7120
7121 func (c *ctxt7) opstore(p *obj.Prog, a obj.As) uint32 {
7122 switch a {
7123 case ASTLR:
7124 return LDSTX(3, 1, 0, 0, 1) | 0x1F<<10
7125
7126 case ASTLRB:
7127 return LDSTX(0, 1, 0, 0, 1) | 0x1F<<10
7128
7129 case ASTLRH:
7130 return LDSTX(1, 1, 0, 0, 1) | 0x1F<<10
7131
7132 case ASTLRW:
7133 return LDSTX(2, 1, 0, 0, 1) | 0x1F<<10
7134
7135 case ASTLXP:
7136 return LDSTX(3, 0, 0, 1, 1)
7137
7138 case ASTLXPW:
7139 return LDSTX(2, 0, 0, 1, 1)
7140
7141 case ASTLXR:
7142 return LDSTX(3, 0, 0, 0, 1) | 0x1F<<10
7143
7144 case ASTLXRB:
7145 return LDSTX(0, 0, 0, 0, 1) | 0x1F<<10
7146
7147 case ASTLXRH:
7148 return LDSTX(1, 0, 0, 0, 1) | 0x1F<<10
7149
7150 case ASTLXRW:
7151 return LDSTX(2, 0, 0, 0, 1) | 0x1F<<10
7152
7153 case ASTXR:
7154 return LDSTX(3, 0, 0, 0, 0) | 0x1F<<10
7155
7156 case ASTXRB:
7157 return LDSTX(0, 0, 0, 0, 0) | 0x1F<<10
7158
7159 case ASTXRH:
7160 return LDSTX(1, 0, 0, 0, 0) | 0x1F<<10
7161
7162 case ASTXP:
7163 return LDSTX(3, 0, 0, 1, 0)
7164
7165 case ASTXPW:
7166 return LDSTX(2, 0, 0, 1, 0)
7167
7168 case ASTXRW:
7169 return LDSTX(2, 0, 0, 0, 0) | 0x1F<<10
7170 }
7171
7172 c.ctxt.Diag("bad opstore %v\n%v", a, p)
7173 return 0
7174 }
7175
7176
7180 func (c *ctxt7) olsr12u(p *obj.Prog, o uint32, v int32, rn, rt int16) uint32 {
7181 if v < 0 || v >= (1<<12) {
7182 c.ctxt.Diag("offset out of range: %d\n%v", v, p)
7183 }
7184 o |= uint32(v&0xFFF) << 10
7185 o |= uint32(rn&31) << 5
7186 o |= uint32(rt & 31)
7187 o |= 1 << 24
7188 return o
7189 }
7190
7191
7194 func (c *ctxt7) olsr9s(p *obj.Prog, o uint32, v int32, rn, rt int16) uint32 {
7195 if v < -256 || v > 255 {
7196 c.ctxt.Diag("offset out of range: %d\n%v", v, p)
7197 }
7198 o |= uint32((v & 0x1FF) << 12)
7199 o |= uint32(rn&31) << 5
7200 o |= uint32(rt & 31)
7201 return o
7202 }
7203
7204
7205
7206
7207
7208
7209 func (c *ctxt7) opstr(p *obj.Prog, a obj.As) uint32 {
7210 enc := c.opldr(p, a)
7211 switch p.As {
7212 case AFMOVQ:
7213 enc = enc &^ (1 << 22)
7214 default:
7215 enc = LD2STR(enc)
7216 }
7217 return enc
7218 }
7219
7220
7221
7222
7223
7224
7225 func (c *ctxt7) opldr(p *obj.Prog, a obj.As) uint32 {
7226 switch a {
7227 case AMOVD:
7228 return LDSTR(3, 0, 1)
7229
7230 case AMOVW:
7231 return LDSTR(2, 0, 2)
7232
7233 case AMOVWU:
7234 return LDSTR(2, 0, 1)
7235
7236 case AMOVH:
7237 return LDSTR(1, 0, 2)
7238
7239 case AMOVHU:
7240 return LDSTR(1, 0, 1)
7241
7242 case AMOVB:
7243 return LDSTR(0, 0, 2)
7244
7245 case AMOVBU:
7246 return LDSTR(0, 0, 1)
7247
7248 case AFMOVS, AVMOVS:
7249 return LDSTR(2, 1, 1)
7250
7251 case AFMOVD, AVMOVD:
7252 return LDSTR(3, 1, 1)
7253
7254 case AFMOVQ, AVMOVQ:
7255 return LDSTR(0, 1, 3)
7256 }
7257
7258 c.ctxt.Diag("bad opldr %v\n%v", a, p)
7259 return 0
7260 }
7261
7262
7263
7264
7265 func (c *ctxt7) opldrr(p *obj.Prog, a obj.As, rt, rn, rm int16, extension bool) uint32 {
7266 var op uint32
7267
7268 OptionS := uint32(0x1a)
7269 if extension {
7270 OptionS = uint32(0)
7271 }
7272 switch a {
7273 case AMOVD:
7274 op = OptionS<<10 | 0x3<<21 | 0x1f<<27
7275 case AMOVW:
7276 op = OptionS<<10 | 0x5<<21 | 0x17<<27
7277 case AMOVWU:
7278 op = OptionS<<10 | 0x3<<21 | 0x17<<27
7279 case AMOVH:
7280 op = OptionS<<10 | 0x5<<21 | 0x0f<<27
7281 case AMOVHU:
7282 op = OptionS<<10 | 0x3<<21 | 0x0f<<27
7283 case AMOVB:
7284 op = OptionS<<10 | 0x5<<21 | 0x07<<27
7285 case AMOVBU:
7286 op = OptionS<<10 | 0x3<<21 | 0x07<<27
7287 case AFMOVS:
7288 op = OptionS<<10 | 0x3<<21 | 0x17<<27 | 1<<26
7289 case AFMOVD:
7290 op = OptionS<<10 | 0x3<<21 | 0x1f<<27 | 1<<26
7291 case AFMOVQ:
7292 op = OptionS<<10 | 0x7<<21 | 0x07<<27 | 1<<26
7293 default:
7294 c.ctxt.Diag("bad opldrr %v\n%v", a, p)
7295 return 0
7296 }
7297 op |= uint32(rm&31)<<16 | uint32(rn&31)<<5 | uint32(rt&31)
7298
7299 return op
7300 }
7301
7302
7303
7304
7305 func (c *ctxt7) opstrr(p *obj.Prog, a obj.As, rt, rn, rm int16, extension bool) uint32 {
7306 var op uint32
7307
7308 OptionS := uint32(0x1a)
7309 if extension {
7310 OptionS = uint32(0)
7311 }
7312 switch a {
7313 case AMOVD:
7314 op = OptionS<<10 | 0x1<<21 | 0x1f<<27
7315 case AMOVW, AMOVWU:
7316 op = OptionS<<10 | 0x1<<21 | 0x17<<27
7317 case AMOVH, AMOVHU:
7318 op = OptionS<<10 | 0x1<<21 | 0x0f<<27
7319 case AMOVB, AMOVBU:
7320 op = OptionS<<10 | 0x1<<21 | 0x07<<27
7321 case AFMOVS:
7322 op = OptionS<<10 | 0x1<<21 | 0x17<<27 | 1<<26
7323 case AFMOVD:
7324 op = OptionS<<10 | 0x1<<21 | 0x1f<<27 | 1<<26
7325 case AFMOVQ:
7326 op = OptionS<<10 | 0x5<<21 | 0x07<<27 | 1<<26
7327 default:
7328 c.ctxt.Diag("bad opstrr %v\n%v", a, p)
7329 return 0
7330 }
7331 op |= uint32(rm&31)<<16 | uint32(rn&31)<<5 | uint32(rt&31)
7332
7333 return op
7334 }
7335
7336 func (c *ctxt7) oaddi(p *obj.Prog, a obj.As, v int32, rd, rn int16) uint32 {
7337 op := c.opirr(p, a)
7338
7339 if (v & 0xFFF000) != 0 {
7340 if v&0xFFF != 0 {
7341 c.ctxt.Diag("%v misuses oaddi", p)
7342 }
7343 v >>= 12
7344 op |= 1 << 22
7345 }
7346
7347 op |= (uint32(v&0xFFF) << 10) | (uint32(rn&31) << 5) | uint32(rd&31)
7348
7349 return op
7350 }
7351
7352 func (c *ctxt7) oaddi12(p *obj.Prog, v int32, rd, rn int16) uint32 {
7353 if v < -4095 || v > 4095 {
7354 c.ctxt.Diag("%v is not a 12 bit immediate: %v", v, p)
7355 return 0
7356 }
7357 a := AADD
7358 if v < 0 {
7359 a = ASUB
7360 v = -v
7361 }
7362 return c.oaddi(p, a, v, rd, rn)
7363 }
7364
7365
7368 func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
7369 var o1 int32
7370 if p.Pool == nil {
7371 c.aclass(a)
7372 c.ctxt.Logf("omovlit add %d (%#x)\n", c.instoffset, uint64(c.instoffset))
7373
7374
7375 o1 = int32(c.opirr(p, AADD))
7376
7377 v := int32(c.instoffset)
7378 if v != 0 && (v&0xFFF) == 0 {
7379 v >>= 12
7380 o1 |= 1 << 22
7381 }
7382
7383 o1 |= ((v & 0xFFF) << 10) | (REGZERO & 31 << 5) | int32(dr&31)
7384 } else {
7385 fp, w := 0, 0
7386 switch as {
7387 case AFMOVS, AVMOVS:
7388 fp = 1
7389 w = 0
7390
7391 case AFMOVD, AVMOVD:
7392 fp = 1
7393 w = 1
7394
7395 case AVMOVQ:
7396 fp = 1
7397 w = 2
7398
7399 case AMOVD:
7400 if p.Pool.As == ADWORD {
7401 w = 1
7402 } else if p.Pool.To.Offset < 0 {
7403 w = 2
7404 } else if p.Pool.To.Offset >= 0 {
7405 w = 0
7406 } else {
7407 c.ctxt.Diag("invalid operand %v in %v", a, p)
7408 }
7409
7410 case AMOVBU, AMOVHU, AMOVWU:
7411 w = 0
7412
7413 case AMOVB, AMOVH, AMOVW:
7414 w = 2
7415
7416 default:
7417 c.ctxt.Diag("invalid operation %v in %v", as, p)
7418 }
7419
7420 v := int32(c.brdist(p, 0, 19, 2))
7421 o1 = (int32(w) << 30) | (int32(fp) << 26) | (3 << 27)
7422 o1 |= (v & 0x7FFFF) << 5
7423 o1 |= int32(dr & 31)
7424 }
7425
7426 return uint32(o1)
7427 }
7428
7429
7430 func (c *ctxt7) omovconst(as obj.As, p *obj.Prog, a *obj.Addr, rt int) (o1 uint32) {
7431 if cls := int(a.Class); (cls == C_BITCON || cls == C_ABCON || cls == C_ABCON0) && rt != REGZERO {
7432
7433 mode := 64
7434 var as1 obj.As
7435 switch as {
7436 case AMOVW:
7437 as1 = AORRW
7438 mode = 32
7439 case AMOVD:
7440 as1 = AORR
7441 }
7442 o1 = c.opirr(p, as1)
7443 o1 |= bitconEncode(uint64(a.Offset), mode) | uint32(REGZERO&31)<<5 | uint32(rt&31)
7444 return o1
7445 }
7446
7447 if as == AMOVW {
7448 d := uint32(a.Offset)
7449 s := movcon(int64(d))
7450 if s < 0 || s >= 32 {
7451 d = ^d
7452 s = movcon(int64(d))
7453 if s < 0 || s >= 32 {
7454 c.ctxt.Diag("impossible 32-bit move wide: %#x\n%v", uint32(a.Offset), p)
7455 }
7456 o1 = c.opirr(p, AMOVNW)
7457 } else {
7458 o1 = c.opirr(p, AMOVZW)
7459 }
7460 o1 |= MOVCONST(int64(d), s>>4, rt)
7461 }
7462 if as == AMOVD {
7463 d := a.Offset
7464 s := movcon(d)
7465 if s < 0 || s >= 64 {
7466 d = ^d
7467 s = movcon(d)
7468 if s < 0 || s >= 64 {
7469 c.ctxt.Diag("impossible 64-bit move wide: %#x\n%v", uint64(a.Offset), p)
7470 }
7471 o1 = c.opirr(p, AMOVN)
7472 } else {
7473 o1 = c.opirr(p, AMOVZ)
7474 }
7475 o1 |= MOVCONST(d, s>>4, rt)
7476 }
7477 return o1
7478 }
7479
7480
7481
7482 func (c *ctxt7) omovlconst(as obj.As, p *obj.Prog, a *obj.Addr, rt int, os []uint32) (num uint8) {
7483 switch as {
7484 case AMOVW:
7485 d := uint32(a.Offset)
7486
7487 os[0] = c.opirr(p, AMOVZW)
7488 os[0] |= MOVCONST(int64(d), 0, rt)
7489 os[1] = c.opirr(p, AMOVKW)
7490 os[1] |= MOVCONST(int64(d), 1, rt)
7491 return 2
7492
7493 case AMOVD:
7494 d := a.Offset
7495 dn := ^d
7496 var immh [4]uint64
7497 var i int
7498 zeroCount := int(0)
7499 negCount := int(0)
7500 for i = 0; i < 4; i++ {
7501 immh[i] = uint64((d >> uint(i*16)) & 0xffff)
7502 if immh[i] == 0 {
7503 zeroCount++
7504 } else if immh[i] == 0xffff {
7505 negCount++
7506 }
7507 }
7508
7509 if zeroCount == 4 || negCount == 4 {
7510 c.ctxt.Diag("the immediate should be MOVCON: %v", p)
7511 }
7512 switch {
7513 case zeroCount == 3:
7514
7515 for i = 0; i < 4; i++ {
7516 if immh[i] != 0 {
7517 os[0] = c.opirr(p, AMOVZ)
7518 os[0] |= MOVCONST(d, i, rt)
7519 break
7520 }
7521 }
7522 return 1
7523
7524 case negCount == 3:
7525
7526 for i = 0; i < 4; i++ {
7527 if immh[i] != 0xffff {
7528 os[0] = c.opirr(p, AMOVN)
7529 os[0] |= MOVCONST(dn, i, rt)
7530 break
7531 }
7532 }
7533 return 1
7534
7535 case zeroCount == 2:
7536
7537 for i = 0; i < 4; i++ {
7538 if immh[i] != 0 {
7539 os[0] = c.opirr(p, AMOVZ)
7540 os[0] |= MOVCONST(d, i, rt)
7541 i++
7542 break
7543 }
7544 }
7545 for ; i < 4; i++ {
7546 if immh[i] != 0 {
7547 os[1] = c.opirr(p, AMOVK)
7548 os[1] |= MOVCONST(d, i, rt)
7549 }
7550 }
7551 return 2
7552
7553 case negCount == 2:
7554
7555 for i = 0; i < 4; i++ {
7556 if immh[i] != 0xffff {
7557 os[0] = c.opirr(p, AMOVN)
7558 os[0] |= MOVCONST(dn, i, rt)
7559 i++
7560 break
7561 }
7562 }
7563 for ; i < 4; i++ {
7564 if immh[i] != 0xffff {
7565 os[1] = c.opirr(p, AMOVK)
7566 os[1] |= MOVCONST(d, i, rt)
7567 }
7568 }
7569 return 2
7570 }
7571
7572
7573
7574
7575 for i = 0; i < 4; i++ {
7576 mask := uint64(0xffff) << (i * 16)
7577 for period := 2; period <= 32; period *= 2 {
7578
7579 x := uint64(d)&^mask | bits.RotateLeft64(uint64(d), max(period, 16))&mask
7580 if isbitcon(x) {
7581
7582 os[0] = c.opirr(p, AORR)
7583 os[0] |= bitconEncode(x, 64) | uint32(REGZERO&31)<<5 | uint32(rt&31)
7584
7585 os[1] = c.opirr(p, AMOVK)
7586 os[1] |= MOVCONST(d, i, rt)
7587 return 2
7588 }
7589 }
7590 }
7591
7592
7593
7594 switch {
7595
7596 case zeroCount == 1:
7597
7598 for i = 0; i < 4; i++ {
7599 if immh[i] != 0 {
7600 os[0] = c.opirr(p, AMOVZ)
7601 os[0] |= MOVCONST(d, i, rt)
7602 i++
7603 break
7604 }
7605 }
7606
7607 for j := 1; i < 4; i++ {
7608 if immh[i] != 0 {
7609 os[j] = c.opirr(p, AMOVK)
7610 os[j] |= MOVCONST(d, i, rt)
7611 j++
7612 }
7613 }
7614 return 3
7615
7616 case negCount == 1:
7617
7618 for i = 0; i < 4; i++ {
7619 if immh[i] != 0xffff {
7620 os[0] = c.opirr(p, AMOVN)
7621 os[0] |= MOVCONST(dn, i, rt)
7622 i++
7623 break
7624 }
7625 }
7626
7627 for j := 1; i < 4; i++ {
7628 if immh[i] != 0xffff {
7629 os[j] = c.opirr(p, AMOVK)
7630 os[j] |= MOVCONST(d, i, rt)
7631 j++
7632 }
7633 }
7634 return 3
7635
7636 default:
7637
7638 os[0] = c.opirr(p, AMOVZ)
7639 os[0] |= MOVCONST(d, 0, rt)
7640 for i = 1; i < 4; i++ {
7641 os[i] = c.opirr(p, AMOVK)
7642 os[i] |= MOVCONST(d, i, rt)
7643 }
7644 return 4
7645 }
7646 default:
7647 return 0
7648 }
7649 }
7650
7651 func (c *ctxt7) opbfm(p *obj.Prog, a obj.As, r, s int64, rf, rt int16) uint32 {
7652 var b uint32
7653 o := c.opirr(p, a)
7654 if (o & (1 << 31)) == 0 {
7655 b = 32
7656 } else {
7657 b = 64
7658 }
7659 if r < 0 || uint32(r) >= b {
7660 c.ctxt.Diag("illegal bit number\n%v", p)
7661 }
7662 o |= (uint32(r) & 0x3F) << 16
7663 if s < 0 || uint32(s) >= b {
7664 c.ctxt.Diag("illegal bit number\n%v", p)
7665 }
7666 o |= (uint32(s) & 0x3F) << 10
7667 o |= (uint32(rf&31) << 5) | uint32(rt&31)
7668 return o
7669 }
7670
7671 func (c *ctxt7) opextr(p *obj.Prog, a obj.As, v int64, rn, rm, rt int16) uint32 {
7672 var b uint32
7673 o := c.opirr(p, a)
7674 if (o & (1 << 31)) != 0 {
7675 b = 63
7676 } else {
7677 b = 31
7678 }
7679 if v < 0 || uint32(v) > b {
7680 c.ctxt.Diag("illegal bit number\n%v", p)
7681 }
7682 o |= uint32(v) << 10
7683 o |= uint32(rn&31) << 5
7684 o |= uint32(rm&31) << 16
7685 o |= uint32(rt & 31)
7686 return o
7687 }
7688
7689
7690 func (c *ctxt7) opldpstp(p *obj.Prog, o *Optab, vo int32, rbase, rl, rh int16, ldp uint32) uint32 {
7691 wback := false
7692 if o.scond == C_XPOST || o.scond == C_XPRE {
7693 wback = true
7694 }
7695 switch p.As {
7696 case ALDP, ALDPW, ALDPSW:
7697 c.checkUnpredictable(p, true, wback, p.From.Reg, p.To.Reg, int16(p.To.Offset))
7698 case ASTP, ASTPW:
7699 if wback {
7700 c.checkUnpredictable(p, false, true, p.To.Reg, p.From.Reg, int16(p.From.Offset))
7701 }
7702 case AFLDPD, AFLDPQ, AFLDPS:
7703 c.checkUnpredictable(p, true, false, p.From.Reg, p.To.Reg, int16(p.To.Offset))
7704 }
7705 var ret uint32
7706
7707 switch p.As {
7708 case AFLDPQ, AFSTPQ:
7709 if vo < -1024 || vo > 1008 || vo%16 != 0 {
7710 c.ctxt.Diag("invalid offset %v\n", p)
7711 }
7712 vo /= 16
7713 ret = 2<<30 | 1<<26
7714 case AFLDPD, AFSTPD:
7715 if vo < -512 || vo > 504 || vo%8 != 0 {
7716 c.ctxt.Diag("invalid offset %v\n", p)
7717 }
7718 vo /= 8
7719 ret = 1<<30 | 1<<26
7720 case AFLDPS, AFSTPS:
7721 if vo < -256 || vo > 252 || vo%4 != 0 {
7722 c.ctxt.Diag("invalid offset %v\n", p)
7723 }
7724 vo /= 4
7725 ret = 1 << 26
7726 case ALDP, ASTP:
7727 if vo < -512 || vo > 504 || vo%8 != 0 {
7728 c.ctxt.Diag("invalid offset %v\n", p)
7729 }
7730 vo /= 8
7731 ret = 2 << 30
7732 case ALDPW, ASTPW:
7733 if vo < -256 || vo > 252 || vo%4 != 0 {
7734 c.ctxt.Diag("invalid offset %v\n", p)
7735 }
7736 vo /= 4
7737 ret = 0
7738 case ALDPSW:
7739 if vo < -256 || vo > 252 || vo%4 != 0 {
7740 c.ctxt.Diag("invalid offset %v\n", p)
7741 }
7742 vo /= 4
7743 ret = 1 << 30
7744 default:
7745 c.ctxt.Diag("invalid instruction %v\n", p)
7746 }
7747
7748 switch p.As {
7749 case AFLDPQ, AFLDPD, AFLDPS, AFSTPQ, AFSTPD, AFSTPS:
7750 if rl < REG_F0 || REG_F31 < rl || rh < REG_F0 || REG_F31 < rh {
7751 c.ctxt.Diag("invalid register pair %v\n", p)
7752 }
7753 case ALDP, ALDPW, ALDPSW:
7754 if rl < REG_R0 || REG_R31 < rl || rh < REG_R0 || REG_R31 < rh {
7755 c.ctxt.Diag("invalid register pair %v\n", p)
7756 }
7757 case ASTP, ASTPW:
7758 if rl < REG_R0 || REG_R31 < rl || rh < REG_R0 || REG_R31 < rh {
7759 c.ctxt.Diag("invalid register pair %v\n", p)
7760 }
7761 }
7762
7763 switch o.scond {
7764 case C_XPOST:
7765 ret |= 1 << 23
7766 case C_XPRE:
7767 ret |= 3 << 23
7768 default:
7769 ret |= 2 << 23
7770 }
7771 ret |= 5<<27 | (ldp&1)<<22 | uint32(vo&0x7f)<<15 | uint32(rh&31)<<10 | uint32(rbase&31)<<5 | uint32(rl&31)
7772 return ret
7773 }
7774
7775 func (c *ctxt7) maskOpvldvst(p *obj.Prog, o1 uint32) uint32 {
7776 if p.As == AVLD1 || p.As == AVST1 {
7777 return o1
7778 }
7779
7780 o1 &^= 0xf000
7781 switch p.As {
7782 case AVLD1R, AVLD2R:
7783 o1 |= 0xC << 12
7784 case AVLD3R, AVLD4R:
7785 o1 |= 0xE << 12
7786 case AVLD2, AVST2:
7787 o1 |= 8 << 12
7788 case AVLD3, AVST3:
7789 o1 |= 4 << 12
7790 case AVLD4, AVST4:
7791 default:
7792 c.ctxt.Diag("unsupported instruction:%v\n", p.As)
7793 }
7794 return o1
7795 }
7796
7797
7800 func movesize(a obj.As) int {
7801 switch a {
7802 case AFMOVQ:
7803 return 4
7804
7805 case AMOVD, AFMOVD:
7806 return 3
7807
7808 case AMOVW, AMOVWU, AFMOVS:
7809 return 2
7810
7811 case AMOVH, AMOVHU:
7812 return 1
7813
7814 case AMOVB, AMOVBU:
7815 return 0
7816
7817 default:
7818 return -1
7819 }
7820 }
7821
7822
7823 func roff(rm int16, o uint32, amount int16) uint32 {
7824 return uint32(rm&31)<<16 | o<<13 | uint32(amount)<<10
7825 }
7826
7827
7828 func (c *ctxt7) encRegShiftOrExt(p *obj.Prog, a *obj.Addr, r int16) uint32 {
7829 var num, rm int16
7830 num = (r >> 5) & 7
7831 rm = r & 31
7832 switch {
7833 case REG_UXTB <= r && r < REG_UXTH:
7834 return roff(rm, 0, num)
7835 case REG_UXTH <= r && r < REG_UXTW:
7836 return roff(rm, 1, num)
7837 case REG_UXTW <= r && r < REG_UXTX:
7838 if a.Type == obj.TYPE_MEM {
7839 if num == 0 {
7840
7841
7842
7843
7844
7845 return roff(rm, 2, 2)
7846 } else {
7847 return roff(rm, 2, 6)
7848 }
7849 } else {
7850 return roff(rm, 2, num)
7851 }
7852 case REG_UXTX <= r && r < REG_SXTB:
7853 return roff(rm, 3, num)
7854 case REG_SXTB <= r && r < REG_SXTH:
7855 return roff(rm, 4, num)
7856 case REG_SXTH <= r && r < REG_SXTW:
7857 return roff(rm, 5, num)
7858 case REG_SXTW <= r && r < REG_SXTX:
7859 if a.Type == obj.TYPE_MEM {
7860 if num == 0 {
7861 return roff(rm, 6, 2)
7862 } else {
7863 return roff(rm, 6, 6)
7864 }
7865 } else {
7866 return roff(rm, 6, num)
7867 }
7868 case REG_SXTX <= r && r < REG_SPECIAL:
7869 if a.Type == obj.TYPE_MEM {
7870 if num == 0 {
7871 return roff(rm, 7, 2)
7872 } else {
7873 return roff(rm, 7, 6)
7874 }
7875 } else {
7876 return roff(rm, 7, num)
7877 }
7878 case REG_LSL <= r && r < REG_ARNG:
7879 if a.Type == obj.TYPE_MEM {
7880 if num == 0 {
7881 return roff(rm, 3, 2)
7882 } else {
7883 return roff(rm, 3, 6)
7884 }
7885 } else if isADDWop(p.As) {
7886 return roff(rm, 2, num)
7887 }
7888 return roff(rm, 3, num)
7889 default:
7890 c.ctxt.Diag("unsupported register extension type.")
7891 }
7892
7893 return 0
7894 }
7895
7896
7897 func pack(q uint32, arngA, arngB uint8) uint32 {
7898 return q<<16 | uint32(arngA)<<8 | uint32(arngB)
7899 }
7900
7901
7902 func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error {
7903 Rnum := (reg & 31) + num<<5
7904 if isAmount {
7905 if num < 0 || num > 7 {
7906 return errors.New("index shift amount is out of range")
7907 }
7908 }
7909 if reg <= REG_R31 && reg >= REG_R0 {
7910 if !isAmount {
7911 return errors.New("invalid register extension")
7912 }
7913 switch ext {
7914 case "UXTB":
7915 if a.Type == obj.TYPE_MEM {
7916 return errors.New("invalid shift for the register offset addressing mode")
7917 }
7918 a.Reg = REG_UXTB + Rnum
7919 case "UXTH":
7920 if a.Type == obj.TYPE_MEM {
7921 return errors.New("invalid shift for the register offset addressing mode")
7922 }
7923 a.Reg = REG_UXTH + Rnum
7924 case "UXTW":
7925
7926 if a.Type == obj.TYPE_MEM {
7927 a.Index = REG_UXTW + Rnum
7928 } else {
7929 a.Reg = REG_UXTW + Rnum
7930 }
7931 case "UXTX":
7932 if a.Type == obj.TYPE_MEM {
7933 return errors.New("invalid shift for the register offset addressing mode")
7934 }
7935 a.Reg = REG_UXTX + Rnum
7936 case "SXTB":
7937 if a.Type == obj.TYPE_MEM {
7938 return errors.New("invalid shift for the register offset addressing mode")
7939 }
7940 a.Reg = REG_SXTB + Rnum
7941 case "SXTH":
7942 if a.Type == obj.TYPE_MEM {
7943 return errors.New("invalid shift for the register offset addressing mode")
7944 }
7945 a.Reg = REG_SXTH + Rnum
7946 case "SXTW":
7947 if a.Type == obj.TYPE_MEM {
7948 a.Index = REG_SXTW + Rnum
7949 } else {
7950 a.Reg = REG_SXTW + Rnum
7951 }
7952 case "SXTX":
7953 if a.Type == obj.TYPE_MEM {
7954 a.Index = REG_SXTX + Rnum
7955 } else {
7956 a.Reg = REG_SXTX + Rnum
7957 }
7958 case "LSL":
7959 a.Index = REG_LSL + Rnum
7960 default:
7961 return errors.New("unsupported general register extension type: " + ext)
7962
7963 }
7964 } else if reg <= REG_V31 && reg >= REG_V0 {
7965 switch ext {
7966 case "B8":
7967 if isIndex {
7968 return errors.New("invalid register extension")
7969 }
7970 a.Reg = REG_ARNG + (reg & 31) + ((ARNG_8B & 15) << 5)
7971 case "B16":
7972 if isIndex {
7973 return errors.New("invalid register extension")
7974 }
7975 a.Reg = REG_ARNG + (reg & 31) + ((ARNG_16B & 15) << 5)
7976 case "H4":
7977 if isIndex {
7978 return errors.New("invalid register extension")
7979 }
7980 a.Reg = REG_ARNG + (reg & 31) + ((ARNG_4H & 15) << 5)
7981 case "H8":
7982 if isIndex {
7983 return errors.New("invalid register extension")
7984 }
7985 a.Reg = REG_ARNG + (reg & 31) + ((ARNG_8H & 15) << 5)
7986 case "S2":
7987 if isIndex {
7988 return errors.New("invalid register extension")
7989 }
7990 a.Reg = REG_ARNG + (reg & 31) + ((ARNG_2S & 15) << 5)
7991 case "S4":
7992 if isIndex {
7993 return errors.New("invalid register extension")
7994 }
7995 a.Reg = REG_ARNG + (reg & 31) + ((ARNG_4S & 15) << 5)
7996 case "D1":
7997 if isIndex {
7998 return errors.New("invalid register extension")
7999 }
8000 a.Reg = REG_ARNG + (reg & 31) + ((ARNG_1D & 15) << 5)
8001 case "D2":
8002 if isIndex {
8003 return errors.New("invalid register extension")
8004 }
8005 a.Reg = REG_ARNG + (reg & 31) + ((ARNG_2D & 15) << 5)
8006 case "Q1":
8007 if isIndex {
8008 return errors.New("invalid register extension")
8009 }
8010 a.Reg = REG_ARNG + (reg & 31) + ((ARNG_1Q & 15) << 5)
8011 case "B":
8012 if !isIndex {
8013 return nil
8014 }
8015 a.Reg = REG_ELEM + (reg & 31) + ((ARNG_B & 15) << 5)
8016 a.Index = num
8017 case "H":
8018 if !isIndex {
8019 return nil
8020 }
8021 a.Reg = REG_ELEM + (reg & 31) + ((ARNG_H & 15) << 5)
8022 a.Index = num
8023 case "S":
8024 if !isIndex {
8025 return nil
8026 }
8027 a.Reg = REG_ELEM + (reg & 31) + ((ARNG_S & 15) << 5)
8028 a.Index = num
8029 case "D":
8030 if !isIndex {
8031 return nil
8032 }
8033 a.Reg = REG_ELEM + (reg & 31) + ((ARNG_D & 15) << 5)
8034 a.Index = num
8035 default:
8036 return errors.New("unsupported simd register extension type: " + ext)
8037 }
8038 } else {
8039 return errors.New("invalid register and extension combination")
8040 }
8041 return nil
8042 }
8043
View as plain text