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