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