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