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