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 "fmt"
36 )
37
38 var strcond = [16]string{
39 "EQ",
40 "NE",
41 "HS",
42 "LO",
43 "MI",
44 "PL",
45 "VS",
46 "VC",
47 "HI",
48 "LS",
49 "GE",
50 "LT",
51 "GT",
52 "LE",
53 "AL",
54 "NV",
55 }
56
57 func init() {
58 obj.RegisterRegister(obj.RBaseARM64, REG_SPECIAL+1024, rconv)
59 obj.RegisterOpcode(obj.ABaseARM64, Anames)
60 obj.RegisterRegisterList(obj.RegListARM64Lo, obj.RegListARM64Hi, rlconv)
61 obj.RegisterOpSuffix("arm64", obj.CConvARM)
62 obj.RegisterSpecialOperands(int64(SPOP_BEGIN), int64(SPOP_END), SPCconv)
63 }
64
65 func arrange(a int) string {
66 switch a {
67 case ARNG_8B:
68 return "B8"
69 case ARNG_16B:
70 return "B16"
71 case ARNG_4H:
72 return "H4"
73 case ARNG_8H:
74 return "H8"
75 case ARNG_2S:
76 return "S2"
77 case ARNG_4S:
78 return "S4"
79 case ARNG_1D:
80 return "D1"
81 case ARNG_2D:
82 return "D2"
83 case ARNG_B:
84 return "B"
85 case ARNG_H:
86 return "H"
87 case ARNG_S:
88 return "S"
89 case ARNG_D:
90 return "D"
91 case ARNG_1Q:
92 return "Q1"
93 case ARNG_Q:
94 return "Q"
95 case PRED_M:
96 return "M"
97 case PRED_Z:
98 return "Z"
99 default:
100 return ""
101 }
102 }
103
104 func rconv(r int) string {
105 ext := (r >> 5) & 7
106 if r == REGG {
107 return "g"
108 }
109 switch {
110 case REG_R0 <= r && r <= REG_R30:
111 return fmt.Sprintf("R%d", r-REG_R0)
112 case r == REG_R31:
113 return "ZR"
114 case REG_F0 <= r && r <= REG_F31:
115 return fmt.Sprintf("F%d", r-REG_F0)
116 case REG_V0 <= r && r <= REG_V31:
117 return fmt.Sprintf("V%d", r-REG_V0)
118 case REG_Z0 <= r && r <= REG_Z31:
119 return fmt.Sprintf("Z%d", r-REG_Z0)
120 case REG_P0 <= r && r <= REG_P15:
121 return fmt.Sprintf("P%d", r-REG_P0)
122 case REG_PN0 <= r && r <= REG_PN15:
123 return fmt.Sprintf("PN%d", r-REG_PN0)
124 case r == REGSP:
125 return "RSP"
126 case REG_UXTB <= r && r < REG_UXTH:
127 if ext != 0 {
128 return fmt.Sprintf("%s.UXTB<<%d", regname(r), ext)
129 } else {
130 return fmt.Sprintf("%s.UXTB", regname(r))
131 }
132 case REG_UXTH <= r && r < REG_UXTW:
133 if ext != 0 {
134 return fmt.Sprintf("%s.UXTH<<%d", regname(r), ext)
135 } else {
136 return fmt.Sprintf("%s.UXTH", regname(r))
137 }
138 case REG_UXTW <= r && r < REG_UXTX:
139 if ext != 0 {
140 return fmt.Sprintf("%s.UXTW<<%d", regname(r), ext)
141 } else {
142 return fmt.Sprintf("%s.UXTW", regname(r))
143 }
144 case REG_UXTX <= r && r < REG_SXTB:
145 if ext != 0 {
146 return fmt.Sprintf("%s.UXTX<<%d", regname(r), ext)
147 } else {
148 return fmt.Sprintf("%s.UXTX", regname(r))
149 }
150 case REG_SXTB <= r && r < REG_SXTH:
151 if ext != 0 {
152 return fmt.Sprintf("%s.SXTB<<%d", regname(r), ext)
153 } else {
154 return fmt.Sprintf("%s.SXTB", regname(r))
155 }
156 case REG_SXTH <= r && r < REG_SXTW:
157 if ext != 0 {
158 return fmt.Sprintf("%s.SXTH<<%d", regname(r), ext)
159 } else {
160 return fmt.Sprintf("%s.SXTH", regname(r))
161 }
162 case REG_SXTW <= r && r < REG_SXTX:
163 if ext != 0 {
164 return fmt.Sprintf("%s.SXTW<<%d", regname(r), ext)
165 } else {
166 return fmt.Sprintf("%s.SXTW", regname(r))
167 }
168 case REG_SXTX <= r && r < REG_SPECIAL:
169 if ext != 0 {
170 return fmt.Sprintf("%s.SXTX<<%d", regname(r), ext)
171 } else {
172 return fmt.Sprintf("%s.SXTX", regname(r))
173 }
174
175 case REG_LSL <= r && r < (REG_LSL+1<<8):
176 return fmt.Sprintf("R%d<<%d", r&31, (r>>5)&7)
177 case REG_ARNG <= r && r < REG_ELEM:
178 return fmt.Sprintf("V%d.%s", r&31, arrange((r>>5)&15))
179 case REG_ELEM <= r && r < REG_ZARNG:
180 return fmt.Sprintf("V%d.%s", r&31, arrange((r>>5)&15))
181 case REG_ZARNG <= r && r < REG_PZELEM:
182 return fmt.Sprintf("Z%d.%s", r&31, arrange((r>>5)&15))
183 case REG_PZELEM <= r && r < REG_PARNGZM:
184 regPrefix := "Z"
185 reg := r & 31
186 if r&(1<<5) != 0 {
187 regPrefix = "P"
188 if reg >= 16 {
189 regPrefix = "PN"
190 reg -= 16
191 }
192 }
193 return fmt.Sprintf("%s%d", regPrefix, reg)
194 case REG_PARNGZM <= r && r < REG_PARNGZM_END:
195
196
197 arng := (r >> 5) & 15
198 suffix := arrange(arng)
199 reg := r & 31
200 if reg >= 16 {
201
202 return fmt.Sprintf("PN%d.%s", reg-16, suffix)
203 }
204 return fmt.Sprintf("P%d.%s", reg, suffix)
205 }
206
207 name, _, _ := SysRegEnc(int16(r))
208 if name != "" {
209 return name
210 }
211 return fmt.Sprintf("badreg(%d)", r)
212 }
213
214 func DRconv(a int) string {
215 if a >= C_NONE && a <= C_NCLASS {
216 return cnames7[a]
217 }
218 return "C_??"
219 }
220
221 func SPCconv(a int64) string {
222 spc := SpecialOperand(a)
223 if spc >= SPOP_BEGIN && spc < SPOP_END {
224 return fmt.Sprintf("%s", spc)
225 }
226 return "SPC_??"
227 }
228
229 func rlconv(list int64) string {
230 str := ""
231
232
233
234
235
236
237
238
239
240
241
242
243
244 firstReg := int(list & 31)
245 opcode := (list >> 12) & 15
246 var regCnt int
247 var t string
248 switch opcode {
249 case 0x7:
250 regCnt = 1
251 case 0xa:
252 regCnt = 2
253 case 0x6:
254 regCnt = 3
255 case 0x2:
256 regCnt = 4
257 case 0x1:
258
259 regCnt = 5
260 case 0x3:
261
262 regCnt = 6
263 default:
264 regCnt = -1
265 }
266
267 var regPrefix string
268 regType := (list >> 32) & 3
269 switch regType {
270 case 0:
271 regPrefix = "V"
272 case 1:
273 regPrefix = "Z"
274 case 2:
275 regPrefix = "P"
276 }
277 arng := ((list>>30)&3)<<2 | (list>>10)&3
278 switch arng {
279 case 0:
280 t = "B8"
281 case 4:
282 t = "B16"
283 case 1:
284 t = "H4"
285 case 5:
286 t = "H8"
287 case 2:
288 t = "S2"
289 case 6:
290 t = "S4"
291 case 3:
292 t = "D1"
293 case 7:
294 t = "D2"
295 case 9:
296 t = "B"
297 case 10:
298 t = "H"
299 case 11:
300 t = "S"
301 case 13:
302 t = "D"
303 case 14:
304 t = "Q"
305 }
306 if regCnt > 4 {
307 rangeSize := 2 << (regCnt - 5)
308 str = fmt.Sprintf("[%s%d.%s-%s%d.%s]", regPrefix, firstReg, t, regPrefix, (firstReg+rangeSize-1)&31, t)
309 } else {
310 for i := 0; i < regCnt; i++ {
311 if str == "" {
312 str += "["
313 } else {
314 str += ","
315 }
316 str += fmt.Sprintf("%s%d.", regPrefix, (firstReg+i)&31)
317 str += t
318 }
319 str += "]"
320 }
321 return str
322 }
323
324 func regname(r int) string {
325 if r&31 == 31 {
326 return "ZR"
327 }
328 return fmt.Sprintf("R%d", r&31)
329 }
330
View as plain text