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