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