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