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