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