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