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