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