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