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