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