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