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