1 | //===- AArch64Disassembler.cpp - Disassembler for AArch64 ISA -------------===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | // |
10 | // This file contains the functions necessary to decode AArch64 instruction |
11 | // bitpatterns into MCInsts (with the help of TableGenerated information from |
12 | // the instruction definitions). |
13 | // |
14 | //===----------------------------------------------------------------------===// |
15 | |
16 | /* Capstone Disassembly Engine */ |
17 | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */ |
18 | |
19 | #ifdef CAPSTONE_HAS_ARM64 |
20 | |
21 | #include <stdio.h> // DEBUG |
22 | #include <stdlib.h> |
23 | |
24 | #include "../../cs_priv.h" |
25 | #include "../../utils.h" |
26 | |
27 | #include "../../MCInst.h" |
28 | #include "../../MCInstrDesc.h" |
29 | #include "../../MCFixedLenDisassembler.h" |
30 | #include "../../MCRegisterInfo.h" |
31 | #include "../../MCDisassembler.h" |
32 | |
33 | #include "AArch64BaseInfo.h" |
34 | #include "AArch64AddressingModes.h" |
35 | |
36 | |
37 | // Forward declare these because the autogenerated code will reference them. |
38 | // Definitions are further down. |
39 | static DecodeStatus DecodeFPR128RegisterClass(MCInst *Inst, |
40 | unsigned RegNo, uint64_t Address, |
41 | const void *Decoder); |
42 | static DecodeStatus DecodeFPR128_loRegisterClass(MCInst *Inst, |
43 | unsigned RegNo, |
44 | uint64_t Address, |
45 | const void *Decoder); |
46 | static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
47 | uint64_t Address, |
48 | const void *Decoder); |
49 | static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
50 | uint64_t Address, |
51 | const void *Decoder); |
52 | static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, unsigned RegNo, |
53 | uint64_t Address, |
54 | const void *Decoder); |
55 | static DecodeStatus DecodeFPR8RegisterClass(MCInst *Inst, unsigned RegNo, |
56 | uint64_t Address, |
57 | const void *Decoder); |
58 | static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
59 | uint64_t Address, |
60 | const void *Decoder); |
61 | static DecodeStatus DecodeGPR64spRegisterClass(MCInst *Inst, |
62 | unsigned RegNo, uint64_t Address, |
63 | const void *Decoder); |
64 | static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
65 | uint64_t Address, |
66 | const void *Decoder); |
67 | static DecodeStatus DecodeGPR32spRegisterClass(MCInst *Inst, |
68 | unsigned RegNo, uint64_t Address, |
69 | const void *Decoder); |
70 | static DecodeStatus DecodeQQRegisterClass(MCInst *Inst, unsigned RegNo, |
71 | uint64_t Address, |
72 | const void *Decoder); |
73 | static DecodeStatus DecodeQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
74 | uint64_t Address, |
75 | const void *Decoder); |
76 | static DecodeStatus DecodeQQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
77 | uint64_t Address, |
78 | const void *Decoder); |
79 | static DecodeStatus DecodeDDRegisterClass(MCInst *Inst, unsigned RegNo, |
80 | uint64_t Address, |
81 | const void *Decoder); |
82 | static DecodeStatus DecodeDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
83 | uint64_t Address, |
84 | const void *Decoder); |
85 | static DecodeStatus DecodeDDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
86 | uint64_t Address, |
87 | const void *Decoder); |
88 | |
89 | static DecodeStatus DecodeFixedPointScaleImm32(MCInst *Inst, unsigned Imm, |
90 | uint64_t Address, |
91 | const void *Decoder); |
92 | static DecodeStatus DecodeFixedPointScaleImm64(MCInst *Inst, unsigned Imm, |
93 | uint64_t Address, |
94 | const void *Decoder); |
95 | static DecodeStatus DecodePCRelLabel19(MCInst *Inst, unsigned Imm, |
96 | uint64_t Address, const void *Decoder); |
97 | static DecodeStatus DecodeMemExtend(MCInst *Inst, unsigned Imm, |
98 | uint64_t Address, const void *Decoder); |
99 | static DecodeStatus DecodeMRSSystemRegister(MCInst *Inst, unsigned Imm, |
100 | uint64_t Address, const void *Decoder); |
101 | static DecodeStatus DecodeMSRSystemRegister(MCInst *Inst, unsigned Imm, |
102 | uint64_t Address, const void *Decoder); |
103 | static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst *Inst, |
104 | uint32_t insn, |
105 | uint64_t Address, |
106 | const void *Decoder); |
107 | static DecodeStatus DecodeMoveImmInstruction(MCInst *Inst, uint32_t insn, |
108 | uint64_t Address, |
109 | const void *Decoder); |
110 | static DecodeStatus DecodeUnsignedLdStInstruction(MCInst *Inst, |
111 | uint32_t insn, |
112 | uint64_t Address, |
113 | const void *Decoder); |
114 | static DecodeStatus DecodeSignedLdStInstruction(MCInst *Inst, |
115 | uint32_t insn, uint64_t Address, |
116 | const void *Decoder); |
117 | static DecodeStatus DecodeExclusiveLdStInstruction(MCInst *Inst, |
118 | uint32_t insn, |
119 | uint64_t Address, |
120 | const void *Decoder); |
121 | static DecodeStatus DecodePairLdStInstruction(MCInst *Inst, uint32_t insn, |
122 | uint64_t Address, |
123 | const void *Decoder); |
124 | static DecodeStatus DecodeAddSubERegInstruction(MCInst *Inst, |
125 | uint32_t insn, uint64_t Address, |
126 | const void *Decoder); |
127 | static DecodeStatus DecodeLogicalImmInstruction(MCInst *Inst, |
128 | uint32_t insn, uint64_t Address, |
129 | const void *Decoder); |
130 | static DecodeStatus DecodeModImmInstruction(MCInst *Inst, uint32_t insn, |
131 | uint64_t Address, |
132 | const void *Decoder); |
133 | static DecodeStatus DecodeModImmTiedInstruction(MCInst *Inst, |
134 | uint32_t insn, uint64_t Address, |
135 | const void *Decoder); |
136 | static DecodeStatus DecodeAdrInstruction(MCInst *Inst, uint32_t insn, |
137 | uint64_t Address, const void *Decoder); |
138 | static DecodeStatus DecodeBaseAddSubImm(MCInst *Inst, uint32_t insn, |
139 | uint64_t Address, const void *Decoder); |
140 | static DecodeStatus DecodeUnconditionalBranch(MCInst *Inst, uint32_t insn, |
141 | uint64_t Address, |
142 | const void *Decoder); |
143 | static DecodeStatus DecodeSystemPStateInstruction(MCInst *Inst, |
144 | uint32_t insn, |
145 | uint64_t Address, |
146 | const void *Decoder); |
147 | static DecodeStatus DecodeTestAndBranch(MCInst *Inst, uint32_t insn, |
148 | uint64_t Address, const void *Decoder); |
149 | |
150 | static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn, |
151 | uint64_t Address, |
152 | const void *Decoder); |
153 | static DecodeStatus DecodeVecShiftR64Imm(MCInst *Inst, unsigned Imm, |
154 | uint64_t Addr, const void *Decoder); |
155 | static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst *Inst, unsigned Imm, |
156 | uint64_t Addr, |
157 | const void *Decoder); |
158 | static DecodeStatus DecodeVecShiftR32Imm(MCInst *Inst, unsigned Imm, |
159 | uint64_t Addr, const void *Decoder); |
160 | static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst *Inst, unsigned Imm, |
161 | uint64_t Addr, |
162 | const void *Decoder); |
163 | static DecodeStatus DecodeVecShiftR16Imm(MCInst *Inst, unsigned Imm, |
164 | uint64_t Addr, const void *Decoder); |
165 | static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst *Inst, unsigned Imm, |
166 | uint64_t Addr, |
167 | const void *Decoder); |
168 | static DecodeStatus DecodeVecShiftR8Imm(MCInst *Inst, unsigned Imm, |
169 | uint64_t Addr, const void *Decoder); |
170 | static DecodeStatus DecodeVecShiftL64Imm(MCInst *Inst, unsigned Imm, |
171 | uint64_t Addr, const void *Decoder); |
172 | static DecodeStatus DecodeVecShiftL32Imm(MCInst *Inst, unsigned Imm, |
173 | uint64_t Addr, const void *Decoder); |
174 | static DecodeStatus DecodeVecShiftL16Imm(MCInst *Inst, unsigned Imm, |
175 | uint64_t Addr, const void *Decoder); |
176 | static DecodeStatus DecodeVecShiftL8Imm(MCInst *Inst, unsigned Imm, |
177 | uint64_t Addr, const void *Decoder); |
178 | |
179 | static bool Check(DecodeStatus *Out, DecodeStatus In) |
180 | { |
181 | switch (In) { |
182 | default: // never reach |
183 | return true; |
184 | case MCDisassembler_Success: |
185 | // Out stays the same. |
186 | return true; |
187 | case MCDisassembler_SoftFail: |
188 | *Out = In; |
189 | return true; |
190 | case MCDisassembler_Fail: |
191 | *Out = In; |
192 | return false; |
193 | } |
194 | // llvm_unreachable("Invalid DecodeStatus!"); |
195 | } |
196 | |
197 | // Hacky: enable all features for disassembler |
198 | static uint64_t getFeatureBits(int feature) |
199 | { |
200 | // enable all features |
201 | return (uint64_t)-1; |
202 | } |
203 | |
204 | #define GET_SUBTARGETINFO_ENUM |
205 | #include "AArch64GenSubtargetInfo.inc" |
206 | |
207 | #include "AArch64GenDisassemblerTables.inc" |
208 | |
209 | #define GET_INSTRINFO_ENUM |
210 | #include "AArch64GenInstrInfo.inc" |
211 | |
212 | #define GET_REGINFO_ENUM |
213 | #define GET_REGINFO_MC_DESC |
214 | #include "AArch64GenRegisterInfo.inc" |
215 | |
216 | #define Success MCDisassembler_Success |
217 | #define Fail MCDisassembler_Fail |
218 | #define SoftFail MCDisassembler_SoftFail |
219 | |
220 | static DecodeStatus _getInstruction(cs_struct *ud, MCInst *MI, |
221 | const uint8_t *code, size_t code_len, |
222 | uint16_t *Size, |
223 | uint64_t Address, MCRegisterInfo *MRI) |
224 | { |
225 | uint32_t insn; |
226 | DecodeStatus result; |
227 | size_t i; |
228 | |
229 | if (code_len < 4) { |
230 | // not enough data |
231 | *Size = 0; |
232 | return MCDisassembler_Fail; |
233 | } |
234 | |
235 | if (MI->flat_insn->detail) { |
236 | memset(MI->flat_insn->detail, 0, sizeof(cs_detail)); |
237 | for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm64.operands); i++) |
238 | MI->flat_insn->detail->arm64.operands[i].vector_index = -1; |
239 | } |
240 | |
241 | if (MODE_IS_BIG_ENDIAN(ud->mode)) |
242 | insn = (code[3] << 0) | (code[2] << 8) | |
243 | (code[1] << 16) | (code[0] << 24); |
244 | else |
245 | insn = (code[3] << 24) | (code[2] << 16) | |
246 | (code[1] << 8) | (code[0] << 0); |
247 | |
248 | // Calling the auto-generated decoder function. |
249 | result = decodeInstruction(DecoderTable32, MI, insn, Address, MRI, 0); |
250 | if (result != MCDisassembler_Fail) { |
251 | *Size = 4; |
252 | return result; |
253 | } |
254 | |
255 | MCInst_clear(MI); |
256 | *Size = 0; |
257 | return MCDisassembler_Fail; |
258 | } |
259 | |
260 | bool AArch64_getInstruction(csh ud, const uint8_t *code, size_t code_len, |
261 | MCInst *instr, uint16_t *size, uint64_t address, void *info) |
262 | { |
263 | DecodeStatus status = _getInstruction((cs_struct *)ud, instr, |
264 | code, code_len, |
265 | size, |
266 | address, (MCRegisterInfo *)info); |
267 | |
268 | return status == MCDisassembler_Success; |
269 | } |
270 | |
271 | static const unsigned FPR128DecoderTable[] = { |
272 | AArch64_Q0, AArch64_Q1, AArch64_Q2, AArch64_Q3, AArch64_Q4, |
273 | AArch64_Q5, AArch64_Q6, AArch64_Q7, AArch64_Q8, AArch64_Q9, |
274 | AArch64_Q10, AArch64_Q11, AArch64_Q12, AArch64_Q13, AArch64_Q14, |
275 | AArch64_Q15, AArch64_Q16, AArch64_Q17, AArch64_Q18, AArch64_Q19, |
276 | AArch64_Q20, AArch64_Q21, AArch64_Q22, AArch64_Q23, AArch64_Q24, |
277 | AArch64_Q25, AArch64_Q26, AArch64_Q27, AArch64_Q28, AArch64_Q29, |
278 | AArch64_Q30, AArch64_Q31 |
279 | }; |
280 | |
281 | static DecodeStatus DecodeFPR128RegisterClass(MCInst *Inst, unsigned RegNo, |
282 | uint64_t Addr, |
283 | const void *Decoder) |
284 | { |
285 | unsigned Register; |
286 | if (RegNo > 31) |
287 | return Fail; |
288 | |
289 | Register = FPR128DecoderTable[RegNo]; |
290 | MCOperand_CreateReg0(Inst, Register); |
291 | return Success; |
292 | } |
293 | |
294 | static DecodeStatus DecodeFPR128_loRegisterClass(MCInst *Inst, unsigned RegNo, |
295 | uint64_t Addr, |
296 | const void *Decoder) |
297 | { |
298 | if (RegNo > 15) |
299 | return Fail; |
300 | |
301 | return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder); |
302 | } |
303 | |
304 | static const unsigned FPR64DecoderTable[] = { |
305 | AArch64_D0, AArch64_D1, AArch64_D2, AArch64_D3, AArch64_D4, |
306 | AArch64_D5, AArch64_D6, AArch64_D7, AArch64_D8, AArch64_D9, |
307 | AArch64_D10, AArch64_D11, AArch64_D12, AArch64_D13, AArch64_D14, |
308 | AArch64_D15, AArch64_D16, AArch64_D17, AArch64_D18, AArch64_D19, |
309 | AArch64_D20, AArch64_D21, AArch64_D22, AArch64_D23, AArch64_D24, |
310 | AArch64_D25, AArch64_D26, AArch64_D27, AArch64_D28, AArch64_D29, |
311 | AArch64_D30, AArch64_D31 |
312 | }; |
313 | |
314 | static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
315 | uint64_t Addr, |
316 | const void *Decoder) |
317 | { |
318 | unsigned Register; |
319 | |
320 | if (RegNo > 31) |
321 | return Fail; |
322 | |
323 | Register = FPR64DecoderTable[RegNo]; |
324 | MCOperand_CreateReg0(Inst, Register); |
325 | return Success; |
326 | } |
327 | |
328 | static const unsigned FPR32DecoderTable[] = { |
329 | AArch64_S0, AArch64_S1, AArch64_S2, AArch64_S3, AArch64_S4, |
330 | AArch64_S5, AArch64_S6, AArch64_S7, AArch64_S8, AArch64_S9, |
331 | AArch64_S10, AArch64_S11, AArch64_S12, AArch64_S13, AArch64_S14, |
332 | AArch64_S15, AArch64_S16, AArch64_S17, AArch64_S18, AArch64_S19, |
333 | AArch64_S20, AArch64_S21, AArch64_S22, AArch64_S23, AArch64_S24, |
334 | AArch64_S25, AArch64_S26, AArch64_S27, AArch64_S28, AArch64_S29, |
335 | AArch64_S30, AArch64_S31 |
336 | }; |
337 | |
338 | static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
339 | uint64_t Addr, |
340 | const void *Decoder) |
341 | { |
342 | unsigned Register; |
343 | |
344 | if (RegNo > 31) |
345 | return Fail; |
346 | |
347 | Register = FPR32DecoderTable[RegNo]; |
348 | MCOperand_CreateReg0(Inst, Register); |
349 | return Success; |
350 | } |
351 | |
352 | static const unsigned FPR16DecoderTable[] = { |
353 | AArch64_H0, AArch64_H1, AArch64_H2, AArch64_H3, AArch64_H4, |
354 | AArch64_H5, AArch64_H6, AArch64_H7, AArch64_H8, AArch64_H9, |
355 | AArch64_H10, AArch64_H11, AArch64_H12, AArch64_H13, AArch64_H14, |
356 | AArch64_H15, AArch64_H16, AArch64_H17, AArch64_H18, AArch64_H19, |
357 | AArch64_H20, AArch64_H21, AArch64_H22, AArch64_H23, AArch64_H24, |
358 | AArch64_H25, AArch64_H26, AArch64_H27, AArch64_H28, AArch64_H29, |
359 | AArch64_H30, AArch64_H31 |
360 | }; |
361 | |
362 | static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, unsigned RegNo, |
363 | uint64_t Addr, |
364 | const void *Decoder) |
365 | { |
366 | unsigned Register; |
367 | |
368 | if (RegNo > 31) |
369 | return Fail; |
370 | |
371 | Register = FPR16DecoderTable[RegNo]; |
372 | MCOperand_CreateReg0(Inst, Register); |
373 | return Success; |
374 | } |
375 | |
376 | static const unsigned FPR8DecoderTable[] = { |
377 | AArch64_B0, AArch64_B1, AArch64_B2, AArch64_B3, AArch64_B4, |
378 | AArch64_B5, AArch64_B6, AArch64_B7, AArch64_B8, AArch64_B9, |
379 | AArch64_B10, AArch64_B11, AArch64_B12, AArch64_B13, AArch64_B14, |
380 | AArch64_B15, AArch64_B16, AArch64_B17, AArch64_B18, AArch64_B19, |
381 | AArch64_B20, AArch64_B21, AArch64_B22, AArch64_B23, AArch64_B24, |
382 | AArch64_B25, AArch64_B26, AArch64_B27, AArch64_B28, AArch64_B29, |
383 | AArch64_B30, AArch64_B31 |
384 | }; |
385 | |
386 | static DecodeStatus DecodeFPR8RegisterClass(MCInst *Inst, unsigned RegNo, |
387 | uint64_t Addr, |
388 | const void *Decoder) |
389 | { |
390 | unsigned Register; |
391 | |
392 | if (RegNo > 31) |
393 | return Fail; |
394 | |
395 | Register = FPR8DecoderTable[RegNo]; |
396 | MCOperand_CreateReg0(Inst, Register); |
397 | return Success; |
398 | } |
399 | |
400 | static const unsigned GPR64DecoderTable[] = { |
401 | AArch64_X0, AArch64_X1, AArch64_X2, AArch64_X3, AArch64_X4, |
402 | AArch64_X5, AArch64_X6, AArch64_X7, AArch64_X8, AArch64_X9, |
403 | AArch64_X10, AArch64_X11, AArch64_X12, AArch64_X13, AArch64_X14, |
404 | AArch64_X15, AArch64_X16, AArch64_X17, AArch64_X18, AArch64_X19, |
405 | AArch64_X20, AArch64_X21, AArch64_X22, AArch64_X23, AArch64_X24, |
406 | AArch64_X25, AArch64_X26, AArch64_X27, AArch64_X28, AArch64_FP, |
407 | AArch64_LR, AArch64_XZR |
408 | }; |
409 | |
410 | static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
411 | uint64_t Addr, |
412 | const void *Decoder) |
413 | { |
414 | unsigned Register; |
415 | |
416 | if (RegNo > 31) |
417 | return Fail; |
418 | |
419 | Register = GPR64DecoderTable[RegNo]; |
420 | MCOperand_CreateReg0(Inst, Register); |
421 | return Success; |
422 | } |
423 | |
424 | static DecodeStatus DecodeGPR64spRegisterClass(MCInst *Inst, unsigned RegNo, |
425 | uint64_t Addr, |
426 | const void *Decoder) |
427 | { |
428 | unsigned Register; |
429 | |
430 | if (RegNo > 31) |
431 | return Fail; |
432 | |
433 | Register = GPR64DecoderTable[RegNo]; |
434 | if (Register == AArch64_XZR) |
435 | Register = AArch64_SP; |
436 | |
437 | MCOperand_CreateReg0(Inst, Register); |
438 | |
439 | return Success; |
440 | } |
441 | |
442 | static const unsigned GPR32DecoderTable[] = { |
443 | AArch64_W0, AArch64_W1, AArch64_W2, AArch64_W3, AArch64_W4, |
444 | AArch64_W5, AArch64_W6, AArch64_W7, AArch64_W8, AArch64_W9, |
445 | AArch64_W10, AArch64_W11, AArch64_W12, AArch64_W13, AArch64_W14, |
446 | AArch64_W15, AArch64_W16, AArch64_W17, AArch64_W18, AArch64_W19, |
447 | AArch64_W20, AArch64_W21, AArch64_W22, AArch64_W23, AArch64_W24, |
448 | AArch64_W25, AArch64_W26, AArch64_W27, AArch64_W28, AArch64_W29, |
449 | AArch64_W30, AArch64_WZR |
450 | }; |
451 | |
452 | static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
453 | uint64_t Addr, |
454 | const void *Decoder) |
455 | { |
456 | unsigned Register; |
457 | |
458 | if (RegNo > 31) |
459 | return Fail; |
460 | |
461 | Register = GPR32DecoderTable[RegNo]; |
462 | MCOperand_CreateReg0(Inst, Register); |
463 | return Success; |
464 | } |
465 | |
466 | static DecodeStatus DecodeGPR32spRegisterClass(MCInst *Inst, unsigned RegNo, |
467 | uint64_t Addr, |
468 | const void *Decoder) |
469 | { |
470 | unsigned Register; |
471 | |
472 | if (RegNo > 31) |
473 | return Fail; |
474 | |
475 | Register = GPR32DecoderTable[RegNo]; |
476 | if (Register == AArch64_WZR) |
477 | Register = AArch64_WSP; |
478 | |
479 | MCOperand_CreateReg0(Inst, Register); |
480 | return Success; |
481 | } |
482 | |
483 | static const unsigned VectorDecoderTable[] = { |
484 | AArch64_Q0, AArch64_Q1, AArch64_Q2, AArch64_Q3, AArch64_Q4, |
485 | AArch64_Q5, AArch64_Q6, AArch64_Q7, AArch64_Q8, AArch64_Q9, |
486 | AArch64_Q10, AArch64_Q11, AArch64_Q12, AArch64_Q13, AArch64_Q14, |
487 | AArch64_Q15, AArch64_Q16, AArch64_Q17, AArch64_Q18, AArch64_Q19, |
488 | AArch64_Q20, AArch64_Q21, AArch64_Q22, AArch64_Q23, AArch64_Q24, |
489 | AArch64_Q25, AArch64_Q26, AArch64_Q27, AArch64_Q28, AArch64_Q29, |
490 | AArch64_Q30, AArch64_Q31 |
491 | }; |
492 | |
493 | static DecodeStatus DecodeVectorRegisterClass(MCInst *Inst, unsigned RegNo, |
494 | uint64_t Addr, |
495 | const void *Decoder) |
496 | { |
497 | unsigned Register; |
498 | |
499 | if (RegNo > 31) |
500 | return Fail; |
501 | |
502 | Register = VectorDecoderTable[RegNo]; |
503 | MCOperand_CreateReg0(Inst, Register); |
504 | return Success; |
505 | } |
506 | |
507 | static const unsigned QQDecoderTable[] = { |
508 | AArch64_Q0_Q1, AArch64_Q1_Q2, AArch64_Q2_Q3, AArch64_Q3_Q4, |
509 | AArch64_Q4_Q5, AArch64_Q5_Q6, AArch64_Q6_Q7, AArch64_Q7_Q8, |
510 | AArch64_Q8_Q9, AArch64_Q9_Q10, AArch64_Q10_Q11, AArch64_Q11_Q12, |
511 | AArch64_Q12_Q13, AArch64_Q13_Q14, AArch64_Q14_Q15, AArch64_Q15_Q16, |
512 | AArch64_Q16_Q17, AArch64_Q17_Q18, AArch64_Q18_Q19, AArch64_Q19_Q20, |
513 | AArch64_Q20_Q21, AArch64_Q21_Q22, AArch64_Q22_Q23, AArch64_Q23_Q24, |
514 | AArch64_Q24_Q25, AArch64_Q25_Q26, AArch64_Q26_Q27, AArch64_Q27_Q28, |
515 | AArch64_Q28_Q29, AArch64_Q29_Q30, AArch64_Q30_Q31, AArch64_Q31_Q0 |
516 | }; |
517 | |
518 | static DecodeStatus DecodeQQRegisterClass(MCInst *Inst, unsigned RegNo, |
519 | uint64_t Addr, const void *Decoder) |
520 | { |
521 | unsigned Register; |
522 | |
523 | if (RegNo > 31) |
524 | return Fail; |
525 | |
526 | Register = QQDecoderTable[RegNo]; |
527 | MCOperand_CreateReg0(Inst, Register); |
528 | return Success; |
529 | } |
530 | |
531 | static const unsigned QQQDecoderTable[] = { |
532 | AArch64_Q0_Q1_Q2, AArch64_Q1_Q2_Q3, AArch64_Q2_Q3_Q4, |
533 | AArch64_Q3_Q4_Q5, AArch64_Q4_Q5_Q6, AArch64_Q5_Q6_Q7, |
534 | AArch64_Q6_Q7_Q8, AArch64_Q7_Q8_Q9, AArch64_Q8_Q9_Q10, |
535 | AArch64_Q9_Q10_Q11, AArch64_Q10_Q11_Q12, AArch64_Q11_Q12_Q13, |
536 | AArch64_Q12_Q13_Q14, AArch64_Q13_Q14_Q15, AArch64_Q14_Q15_Q16, |
537 | AArch64_Q15_Q16_Q17, AArch64_Q16_Q17_Q18, AArch64_Q17_Q18_Q19, |
538 | AArch64_Q18_Q19_Q20, AArch64_Q19_Q20_Q21, AArch64_Q20_Q21_Q22, |
539 | AArch64_Q21_Q22_Q23, AArch64_Q22_Q23_Q24, AArch64_Q23_Q24_Q25, |
540 | AArch64_Q24_Q25_Q26, AArch64_Q25_Q26_Q27, AArch64_Q26_Q27_Q28, |
541 | AArch64_Q27_Q28_Q29, AArch64_Q28_Q29_Q30, AArch64_Q29_Q30_Q31, |
542 | AArch64_Q30_Q31_Q0, AArch64_Q31_Q0_Q1 |
543 | }; |
544 | |
545 | static DecodeStatus DecodeQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
546 | uint64_t Addr, const void *Decoder) |
547 | { |
548 | unsigned Register; |
549 | |
550 | if (RegNo > 31) |
551 | return Fail; |
552 | |
553 | Register = QQQDecoderTable[RegNo]; |
554 | MCOperand_CreateReg0(Inst, Register); |
555 | return Success; |
556 | } |
557 | |
558 | static const unsigned QQQQDecoderTable[] = { |
559 | AArch64_Q0_Q1_Q2_Q3, AArch64_Q1_Q2_Q3_Q4, AArch64_Q2_Q3_Q4_Q5, |
560 | AArch64_Q3_Q4_Q5_Q6, AArch64_Q4_Q5_Q6_Q7, AArch64_Q5_Q6_Q7_Q8, |
561 | AArch64_Q6_Q7_Q8_Q9, AArch64_Q7_Q8_Q9_Q10, AArch64_Q8_Q9_Q10_Q11, |
562 | AArch64_Q9_Q10_Q11_Q12, AArch64_Q10_Q11_Q12_Q13, AArch64_Q11_Q12_Q13_Q14, |
563 | AArch64_Q12_Q13_Q14_Q15, AArch64_Q13_Q14_Q15_Q16, AArch64_Q14_Q15_Q16_Q17, |
564 | AArch64_Q15_Q16_Q17_Q18, AArch64_Q16_Q17_Q18_Q19, AArch64_Q17_Q18_Q19_Q20, |
565 | AArch64_Q18_Q19_Q20_Q21, AArch64_Q19_Q20_Q21_Q22, AArch64_Q20_Q21_Q22_Q23, |
566 | AArch64_Q21_Q22_Q23_Q24, AArch64_Q22_Q23_Q24_Q25, AArch64_Q23_Q24_Q25_Q26, |
567 | AArch64_Q24_Q25_Q26_Q27, AArch64_Q25_Q26_Q27_Q28, AArch64_Q26_Q27_Q28_Q29, |
568 | AArch64_Q27_Q28_Q29_Q30, AArch64_Q28_Q29_Q30_Q31, AArch64_Q29_Q30_Q31_Q0, |
569 | AArch64_Q30_Q31_Q0_Q1, AArch64_Q31_Q0_Q1_Q2 |
570 | }; |
571 | |
572 | static DecodeStatus DecodeQQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
573 | uint64_t Addr, |
574 | const void *Decoder) |
575 | { |
576 | unsigned Register; |
577 | if (RegNo > 31) |
578 | return Fail; |
579 | |
580 | Register = QQQQDecoderTable[RegNo]; |
581 | MCOperand_CreateReg0(Inst, Register); |
582 | return Success; |
583 | } |
584 | |
585 | static const unsigned DDDecoderTable[] = { |
586 | AArch64_D0_D1, AArch64_D1_D2, AArch64_D2_D3, AArch64_D3_D4, |
587 | AArch64_D4_D5, AArch64_D5_D6, AArch64_D6_D7, AArch64_D7_D8, |
588 | AArch64_D8_D9, AArch64_D9_D10, AArch64_D10_D11, AArch64_D11_D12, |
589 | AArch64_D12_D13, AArch64_D13_D14, AArch64_D14_D15, AArch64_D15_D16, |
590 | AArch64_D16_D17, AArch64_D17_D18, AArch64_D18_D19, AArch64_D19_D20, |
591 | AArch64_D20_D21, AArch64_D21_D22, AArch64_D22_D23, AArch64_D23_D24, |
592 | AArch64_D24_D25, AArch64_D25_D26, AArch64_D26_D27, AArch64_D27_D28, |
593 | AArch64_D28_D29, AArch64_D29_D30, AArch64_D30_D31, AArch64_D31_D0 |
594 | }; |
595 | |
596 | static DecodeStatus DecodeDDRegisterClass(MCInst *Inst, unsigned RegNo, |
597 | uint64_t Addr, const void *Decoder) |
598 | { |
599 | unsigned Register; |
600 | |
601 | if (RegNo > 31) |
602 | return Fail; |
603 | |
604 | Register = DDDecoderTable[RegNo]; |
605 | MCOperand_CreateReg0(Inst, Register); |
606 | return Success; |
607 | } |
608 | |
609 | static const unsigned DDDDecoderTable[] = { |
610 | AArch64_D0_D1_D2, AArch64_D1_D2_D3, AArch64_D2_D3_D4, |
611 | AArch64_D3_D4_D5, AArch64_D4_D5_D6, AArch64_D5_D6_D7, |
612 | AArch64_D6_D7_D8, AArch64_D7_D8_D9, AArch64_D8_D9_D10, |
613 | AArch64_D9_D10_D11, AArch64_D10_D11_D12, AArch64_D11_D12_D13, |
614 | AArch64_D12_D13_D14, AArch64_D13_D14_D15, AArch64_D14_D15_D16, |
615 | AArch64_D15_D16_D17, AArch64_D16_D17_D18, AArch64_D17_D18_D19, |
616 | AArch64_D18_D19_D20, AArch64_D19_D20_D21, AArch64_D20_D21_D22, |
617 | AArch64_D21_D22_D23, AArch64_D22_D23_D24, AArch64_D23_D24_D25, |
618 | AArch64_D24_D25_D26, AArch64_D25_D26_D27, AArch64_D26_D27_D28, |
619 | AArch64_D27_D28_D29, AArch64_D28_D29_D30, AArch64_D29_D30_D31, |
620 | AArch64_D30_D31_D0, AArch64_D31_D0_D1 |
621 | }; |
622 | |
623 | static DecodeStatus DecodeDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
624 | uint64_t Addr, const void *Decoder) |
625 | { |
626 | unsigned Register; |
627 | |
628 | if (RegNo > 31) |
629 | return Fail; |
630 | |
631 | Register = DDDDecoderTable[RegNo]; |
632 | MCOperand_CreateReg0(Inst, Register); |
633 | return Success; |
634 | } |
635 | |
636 | static const unsigned DDDDDecoderTable[] = { |
637 | AArch64_D0_D1_D2_D3, AArch64_D1_D2_D3_D4, AArch64_D2_D3_D4_D5, |
638 | AArch64_D3_D4_D5_D6, AArch64_D4_D5_D6_D7, AArch64_D5_D6_D7_D8, |
639 | AArch64_D6_D7_D8_D9, AArch64_D7_D8_D9_D10, AArch64_D8_D9_D10_D11, |
640 | AArch64_D9_D10_D11_D12, AArch64_D10_D11_D12_D13, AArch64_D11_D12_D13_D14, |
641 | AArch64_D12_D13_D14_D15, AArch64_D13_D14_D15_D16, AArch64_D14_D15_D16_D17, |
642 | AArch64_D15_D16_D17_D18, AArch64_D16_D17_D18_D19, AArch64_D17_D18_D19_D20, |
643 | AArch64_D18_D19_D20_D21, AArch64_D19_D20_D21_D22, AArch64_D20_D21_D22_D23, |
644 | AArch64_D21_D22_D23_D24, AArch64_D22_D23_D24_D25, AArch64_D23_D24_D25_D26, |
645 | AArch64_D24_D25_D26_D27, AArch64_D25_D26_D27_D28, AArch64_D26_D27_D28_D29, |
646 | AArch64_D27_D28_D29_D30, AArch64_D28_D29_D30_D31, AArch64_D29_D30_D31_D0, |
647 | AArch64_D30_D31_D0_D1, AArch64_D31_D0_D1_D2 |
648 | }; |
649 | |
650 | static DecodeStatus DecodeDDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
651 | uint64_t Addr, |
652 | const void *Decoder) |
653 | { |
654 | unsigned Register; |
655 | |
656 | if (RegNo > 31) |
657 | return Fail; |
658 | |
659 | Register = DDDDDecoderTable[RegNo]; |
660 | MCOperand_CreateReg0(Inst, Register); |
661 | return Success; |
662 | } |
663 | |
664 | static DecodeStatus DecodeFixedPointScaleImm32(MCInst *Inst, unsigned Imm, |
665 | uint64_t Addr, |
666 | const void *Decoder) |
667 | { |
668 | // scale{5} is asserted as 1 in tblgen. |
669 | Imm |= 0x20; |
670 | MCOperand_CreateImm0(Inst, 64 - Imm); |
671 | return Success; |
672 | } |
673 | |
674 | static DecodeStatus DecodeFixedPointScaleImm64(MCInst *Inst, unsigned Imm, |
675 | uint64_t Addr, |
676 | const void *Decoder) |
677 | { |
678 | MCOperand_CreateImm0(Inst, 64 - Imm); |
679 | return Success; |
680 | } |
681 | |
682 | static DecodeStatus DecodePCRelLabel19(MCInst *Inst, unsigned Imm, |
683 | uint64_t Addr, const void *Decoder) |
684 | { |
685 | int64_t ImmVal = Imm; |
686 | |
687 | // Sign-extend 19-bit immediate. |
688 | if (ImmVal & (1 << (19 - 1))) |
689 | ImmVal |= ~((1LL << 19) - 1); |
690 | |
691 | MCOperand_CreateImm0(Inst, ImmVal); |
692 | return Success; |
693 | } |
694 | |
695 | static DecodeStatus DecodeMemExtend(MCInst *Inst, unsigned Imm, |
696 | uint64_t Address, const void *Decoder) |
697 | { |
698 | MCOperand_CreateImm0(Inst, (Imm >> 1) & 1); |
699 | MCOperand_CreateImm0(Inst, Imm & 1); |
700 | return Success; |
701 | } |
702 | |
703 | static DecodeStatus (MCInst *Inst, unsigned Imm, |
704 | uint64_t Address, const void *Decoder) |
705 | { |
706 | bool ValidNamed; |
707 | char result[128]; |
708 | |
709 | Imm |= 0x8000; |
710 | MCOperand_CreateImm0(Inst, Imm); |
711 | |
712 | A64SysRegMapper_toString(&AArch64_MRSMapper, Imm, &ValidNamed, result); |
713 | |
714 | return ValidNamed ? Success : Fail; |
715 | } |
716 | |
717 | static DecodeStatus DecodeMSRSystemRegister(MCInst *Inst, unsigned Imm, |
718 | uint64_t Address, |
719 | const void *Decoder) |
720 | { |
721 | bool ValidNamed; |
722 | char result[128]; |
723 | |
724 | Imm |= 0x8000; |
725 | MCOperand_CreateImm0(Inst, Imm); |
726 | |
727 | A64SysRegMapper_toString(&AArch64_MSRMapper, Imm, &ValidNamed, result); |
728 | |
729 | return ValidNamed ? Success : Fail; |
730 | } |
731 | |
732 | static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn, |
733 | uint64_t Address, |
734 | const void *Decoder) |
735 | { |
736 | // This decoder exists to add the dummy Lane operand to the MCInst, which must |
737 | // be 1 in assembly but has no other real manifestation. |
738 | unsigned Rd = fieldFromInstruction(Insn, 0, 5); |
739 | unsigned Rn = fieldFromInstruction(Insn, 5, 5); |
740 | unsigned IsToVec = fieldFromInstruction(Insn, 16, 1); |
741 | |
742 | if (IsToVec) { |
743 | DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder); |
744 | DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder); |
745 | } else { |
746 | DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder); |
747 | DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder); |
748 | } |
749 | |
750 | // Add the lane |
751 | MCOperand_CreateImm0(Inst, 1); |
752 | |
753 | return Success; |
754 | } |
755 | |
756 | static DecodeStatus DecodeVecShiftRImm(MCInst *Inst, unsigned Imm, |
757 | unsigned Add) |
758 | { |
759 | MCOperand_CreateImm0(Inst, Add - Imm); |
760 | return Success; |
761 | } |
762 | |
763 | static DecodeStatus DecodeVecShiftLImm(MCInst *Inst, unsigned Imm, |
764 | unsigned Add) |
765 | { |
766 | MCOperand_CreateImm0(Inst, (Imm + Add) & (Add - 1)); |
767 | return Success; |
768 | } |
769 | |
770 | static DecodeStatus DecodeVecShiftR64Imm(MCInst *Inst, unsigned Imm, |
771 | uint64_t Addr, const void *Decoder) |
772 | { |
773 | return DecodeVecShiftRImm(Inst, Imm, 64); |
774 | } |
775 | |
776 | static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst *Inst, unsigned Imm, |
777 | uint64_t Addr, |
778 | const void *Decoder) |
779 | { |
780 | return DecodeVecShiftRImm(Inst, Imm | 0x20, 64); |
781 | } |
782 | |
783 | static DecodeStatus DecodeVecShiftR32Imm(MCInst *Inst, unsigned Imm, |
784 | uint64_t Addr, const void *Decoder) |
785 | { |
786 | return DecodeVecShiftRImm(Inst, Imm, 32); |
787 | } |
788 | |
789 | static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst *Inst, unsigned Imm, |
790 | uint64_t Addr, |
791 | const void *Decoder) |
792 | { |
793 | return DecodeVecShiftRImm(Inst, Imm | 0x10, 32); |
794 | } |
795 | |
796 | static DecodeStatus DecodeVecShiftR16Imm(MCInst *Inst, unsigned Imm, |
797 | uint64_t Addr, const void *Decoder) |
798 | { |
799 | return DecodeVecShiftRImm(Inst, Imm, 16); |
800 | } |
801 | |
802 | static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst *Inst, unsigned Imm, |
803 | uint64_t Addr, |
804 | const void *Decoder) |
805 | { |
806 | return DecodeVecShiftRImm(Inst, Imm | 0x8, 16); |
807 | } |
808 | |
809 | static DecodeStatus DecodeVecShiftR8Imm(MCInst *Inst, unsigned Imm, |
810 | uint64_t Addr, const void *Decoder) |
811 | { |
812 | return DecodeVecShiftRImm(Inst, Imm, 8); |
813 | } |
814 | |
815 | static DecodeStatus DecodeVecShiftL64Imm(MCInst *Inst, unsigned Imm, |
816 | uint64_t Addr, const void *Decoder) |
817 | { |
818 | return DecodeVecShiftLImm(Inst, Imm, 64); |
819 | } |
820 | |
821 | static DecodeStatus DecodeVecShiftL32Imm(MCInst *Inst, unsigned Imm, |
822 | uint64_t Addr, const void *Decoder) |
823 | { |
824 | return DecodeVecShiftLImm(Inst, Imm, 32); |
825 | } |
826 | |
827 | static DecodeStatus DecodeVecShiftL16Imm(MCInst *Inst, unsigned Imm, |
828 | uint64_t Addr, const void *Decoder) |
829 | { |
830 | return DecodeVecShiftLImm(Inst, Imm, 16); |
831 | } |
832 | |
833 | static DecodeStatus DecodeVecShiftL8Imm(MCInst *Inst, unsigned Imm, |
834 | uint64_t Addr, const void *Decoder) |
835 | { |
836 | return DecodeVecShiftLImm(Inst, Imm, 8); |
837 | } |
838 | |
839 | static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst *Inst, |
840 | uint32_t insn, uint64_t Addr, |
841 | const void *Decoder) |
842 | { |
843 | unsigned Rd = fieldFromInstruction(insn, 0, 5); |
844 | unsigned Rn = fieldFromInstruction(insn, 5, 5); |
845 | unsigned Rm = fieldFromInstruction(insn, 16, 5); |
846 | unsigned shiftHi = fieldFromInstruction(insn, 22, 2); |
847 | unsigned shiftLo = fieldFromInstruction(insn, 10, 6); |
848 | unsigned shift = (shiftHi << 6) | shiftLo; |
849 | |
850 | switch (MCInst_getOpcode(Inst)) { |
851 | default: |
852 | return Fail; |
853 | case AArch64_ADDWrs: |
854 | case AArch64_ADDSWrs: |
855 | case AArch64_SUBWrs: |
856 | case AArch64_SUBSWrs: |
857 | // if shift == '11' then ReservedValue() |
858 | if (shiftHi == 0x3) |
859 | return Fail; |
860 | // Deliberate fallthrough |
861 | case AArch64_ANDWrs: |
862 | case AArch64_ANDSWrs: |
863 | case AArch64_BICWrs: |
864 | case AArch64_BICSWrs: |
865 | case AArch64_ORRWrs: |
866 | case AArch64_ORNWrs: |
867 | case AArch64_EORWrs: |
868 | case AArch64_EONWrs: { |
869 | // if sf == '0' and imm6<5> == '1' then ReservedValue() |
870 | if (shiftLo >> 5 == 1) |
871 | return Fail; |
872 | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
873 | DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); |
874 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
875 | break; |
876 | } |
877 | case AArch64_ADDXrs: |
878 | case AArch64_ADDSXrs: |
879 | case AArch64_SUBXrs: |
880 | case AArch64_SUBSXrs: |
881 | // if shift == '11' then ReservedValue() |
882 | if (shiftHi == 0x3) |
883 | return Fail; |
884 | // Deliberate fallthrough |
885 | case AArch64_ANDXrs: |
886 | case AArch64_ANDSXrs: |
887 | case AArch64_BICXrs: |
888 | case AArch64_BICSXrs: |
889 | case AArch64_ORRXrs: |
890 | case AArch64_ORNXrs: |
891 | case AArch64_EORXrs: |
892 | case AArch64_EONXrs: |
893 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
894 | DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); |
895 | DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
896 | break; |
897 | } |
898 | |
899 | MCOperand_CreateImm0(Inst, shift); |
900 | return Success; |
901 | } |
902 | |
903 | static DecodeStatus DecodeMoveImmInstruction(MCInst *Inst, uint32_t insn, |
904 | uint64_t Addr, |
905 | const void *Decoder) |
906 | { |
907 | unsigned Rd = fieldFromInstruction(insn, 0, 5); |
908 | unsigned imm = fieldFromInstruction(insn, 5, 16); |
909 | unsigned shift = fieldFromInstruction(insn, 21, 2); |
910 | |
911 | shift <<= 4; |
912 | |
913 | switch (MCInst_getOpcode(Inst)) { |
914 | default: |
915 | return Fail; |
916 | case AArch64_MOVZWi: |
917 | case AArch64_MOVNWi: |
918 | case AArch64_MOVKWi: |
919 | if (shift & (1U << 5)) |
920 | return Fail; |
921 | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
922 | break; |
923 | case AArch64_MOVZXi: |
924 | case AArch64_MOVNXi: |
925 | case AArch64_MOVKXi: |
926 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
927 | break; |
928 | } |
929 | |
930 | if (MCInst_getOpcode(Inst) == AArch64_MOVKWi || |
931 | MCInst_getOpcode(Inst) == AArch64_MOVKXi) |
932 | MCInst_addOperand2(Inst, MCInst_getOperand(Inst, 0)); |
933 | |
934 | MCOperand_CreateImm0(Inst, imm); |
935 | MCOperand_CreateImm0(Inst, shift); |
936 | return Success; |
937 | } |
938 | |
939 | static DecodeStatus DecodeUnsignedLdStInstruction(MCInst *Inst, |
940 | uint32_t insn, uint64_t Addr, |
941 | const void *Decoder) |
942 | { |
943 | unsigned Rt = fieldFromInstruction(insn, 0, 5); |
944 | unsigned Rn = fieldFromInstruction(insn, 5, 5); |
945 | unsigned offset = fieldFromInstruction(insn, 10, 12); |
946 | |
947 | switch (MCInst_getOpcode(Inst)) { |
948 | default: |
949 | return Fail; |
950 | case AArch64_PRFMui: |
951 | // Rt is an immediate in prefetch. |
952 | MCOperand_CreateImm0(Inst, Rt); |
953 | break; |
954 | case AArch64_STRBBui: |
955 | case AArch64_LDRBBui: |
956 | case AArch64_LDRSBWui: |
957 | case AArch64_STRHHui: |
958 | case AArch64_LDRHHui: |
959 | case AArch64_LDRSHWui: |
960 | case AArch64_STRWui: |
961 | case AArch64_LDRWui: |
962 | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
963 | break; |
964 | case AArch64_LDRSBXui: |
965 | case AArch64_LDRSHXui: |
966 | case AArch64_LDRSWui: |
967 | case AArch64_STRXui: |
968 | case AArch64_LDRXui: |
969 | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
970 | break; |
971 | case AArch64_LDRQui: |
972 | case AArch64_STRQui: |
973 | DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
974 | break; |
975 | case AArch64_LDRDui: |
976 | case AArch64_STRDui: |
977 | DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
978 | break; |
979 | case AArch64_LDRSui: |
980 | case AArch64_STRSui: |
981 | DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
982 | break; |
983 | case AArch64_LDRHui: |
984 | case AArch64_STRHui: |
985 | DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); |
986 | break; |
987 | case AArch64_LDRBui: |
988 | case AArch64_STRBui: |
989 | DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); |
990 | break; |
991 | } |
992 | |
993 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
994 | //if (!Dis->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 4)) |
995 | MCOperand_CreateImm0(Inst, offset); |
996 | |
997 | return Success; |
998 | } |
999 | |
1000 | static DecodeStatus DecodeSignedLdStInstruction(MCInst *Inst, |
1001 | uint32_t insn, uint64_t Addr, |
1002 | const void *Decoder) |
1003 | { |
1004 | bool IsLoad; |
1005 | bool IsIndexed; |
1006 | bool IsFP; |
1007 | unsigned Rt = fieldFromInstruction(insn, 0, 5); |
1008 | unsigned Rn = fieldFromInstruction(insn, 5, 5); |
1009 | int64_t offset = fieldFromInstruction(insn, 12, 9); |
1010 | |
1011 | // offset is a 9-bit signed immediate, so sign extend it to |
1012 | // fill the unsigned. |
1013 | if (offset & (1 << (9 - 1))) |
1014 | offset |= ~((1LL << 9) - 1); |
1015 | |
1016 | // First operand is always the writeback to the address register, if needed. |
1017 | switch (MCInst_getOpcode(Inst)) { |
1018 | default: |
1019 | break; |
1020 | case AArch64_LDRSBWpre: |
1021 | case AArch64_LDRSHWpre: |
1022 | case AArch64_STRBBpre: |
1023 | case AArch64_LDRBBpre: |
1024 | case AArch64_STRHHpre: |
1025 | case AArch64_LDRHHpre: |
1026 | case AArch64_STRWpre: |
1027 | case AArch64_LDRWpre: |
1028 | case AArch64_LDRSBWpost: |
1029 | case AArch64_LDRSHWpost: |
1030 | case AArch64_STRBBpost: |
1031 | case AArch64_LDRBBpost: |
1032 | case AArch64_STRHHpost: |
1033 | case AArch64_LDRHHpost: |
1034 | case AArch64_STRWpost: |
1035 | case AArch64_LDRWpost: |
1036 | case AArch64_LDRSBXpre: |
1037 | case AArch64_LDRSHXpre: |
1038 | case AArch64_STRXpre: |
1039 | case AArch64_LDRSWpre: |
1040 | case AArch64_LDRXpre: |
1041 | case AArch64_LDRSBXpost: |
1042 | case AArch64_LDRSHXpost: |
1043 | case AArch64_STRXpost: |
1044 | case AArch64_LDRSWpost: |
1045 | case AArch64_LDRXpost: |
1046 | case AArch64_LDRQpre: |
1047 | case AArch64_STRQpre: |
1048 | case AArch64_LDRQpost: |
1049 | case AArch64_STRQpost: |
1050 | case AArch64_LDRDpre: |
1051 | case AArch64_STRDpre: |
1052 | case AArch64_LDRDpost: |
1053 | case AArch64_STRDpost: |
1054 | case AArch64_LDRSpre: |
1055 | case AArch64_STRSpre: |
1056 | case AArch64_LDRSpost: |
1057 | case AArch64_STRSpost: |
1058 | case AArch64_LDRHpre: |
1059 | case AArch64_STRHpre: |
1060 | case AArch64_LDRHpost: |
1061 | case AArch64_STRHpost: |
1062 | case AArch64_LDRBpre: |
1063 | case AArch64_STRBpre: |
1064 | case AArch64_LDRBpost: |
1065 | case AArch64_STRBpost: |
1066 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1067 | break; |
1068 | } |
1069 | |
1070 | switch (MCInst_getOpcode(Inst)) { |
1071 | default: |
1072 | return Fail; |
1073 | case AArch64_PRFUMi: |
1074 | // Rt is an immediate in prefetch. |
1075 | MCOperand_CreateImm0(Inst, Rt); |
1076 | break; |
1077 | case AArch64_STURBBi: |
1078 | case AArch64_LDURBBi: |
1079 | case AArch64_LDURSBWi: |
1080 | case AArch64_STURHHi: |
1081 | case AArch64_LDURHHi: |
1082 | case AArch64_LDURSHWi: |
1083 | case AArch64_STURWi: |
1084 | case AArch64_LDURWi: |
1085 | case AArch64_LDTRSBWi: |
1086 | case AArch64_LDTRSHWi: |
1087 | case AArch64_STTRWi: |
1088 | case AArch64_LDTRWi: |
1089 | case AArch64_STTRHi: |
1090 | case AArch64_LDTRHi: |
1091 | case AArch64_LDTRBi: |
1092 | case AArch64_STTRBi: |
1093 | case AArch64_LDRSBWpre: |
1094 | case AArch64_LDRSHWpre: |
1095 | case AArch64_STRBBpre: |
1096 | case AArch64_LDRBBpre: |
1097 | case AArch64_STRHHpre: |
1098 | case AArch64_LDRHHpre: |
1099 | case AArch64_STRWpre: |
1100 | case AArch64_LDRWpre: |
1101 | case AArch64_LDRSBWpost: |
1102 | case AArch64_LDRSHWpost: |
1103 | case AArch64_STRBBpost: |
1104 | case AArch64_LDRBBpost: |
1105 | case AArch64_STRHHpost: |
1106 | case AArch64_LDRHHpost: |
1107 | case AArch64_STRWpost: |
1108 | case AArch64_LDRWpost: |
1109 | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1110 | break; |
1111 | case AArch64_LDURSBXi: |
1112 | case AArch64_LDURSHXi: |
1113 | case AArch64_LDURSWi: |
1114 | case AArch64_STURXi: |
1115 | case AArch64_LDURXi: |
1116 | case AArch64_LDTRSBXi: |
1117 | case AArch64_LDTRSHXi: |
1118 | case AArch64_LDTRSWi: |
1119 | case AArch64_STTRXi: |
1120 | case AArch64_LDTRXi: |
1121 | case AArch64_LDRSBXpre: |
1122 | case AArch64_LDRSHXpre: |
1123 | case AArch64_STRXpre: |
1124 | case AArch64_LDRSWpre: |
1125 | case AArch64_LDRXpre: |
1126 | case AArch64_LDRSBXpost: |
1127 | case AArch64_LDRSHXpost: |
1128 | case AArch64_STRXpost: |
1129 | case AArch64_LDRSWpost: |
1130 | case AArch64_LDRXpost: |
1131 | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1132 | break; |
1133 | case AArch64_LDURQi: |
1134 | case AArch64_STURQi: |
1135 | case AArch64_LDRQpre: |
1136 | case AArch64_STRQpre: |
1137 | case AArch64_LDRQpost: |
1138 | case AArch64_STRQpost: |
1139 | DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
1140 | break; |
1141 | case AArch64_LDURDi: |
1142 | case AArch64_STURDi: |
1143 | case AArch64_LDRDpre: |
1144 | case AArch64_STRDpre: |
1145 | case AArch64_LDRDpost: |
1146 | case AArch64_STRDpost: |
1147 | DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1148 | break; |
1149 | case AArch64_LDURSi: |
1150 | case AArch64_STURSi: |
1151 | case AArch64_LDRSpre: |
1152 | case AArch64_STRSpre: |
1153 | case AArch64_LDRSpost: |
1154 | case AArch64_STRSpost: |
1155 | DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1156 | break; |
1157 | case AArch64_LDURHi: |
1158 | case AArch64_STURHi: |
1159 | case AArch64_LDRHpre: |
1160 | case AArch64_STRHpre: |
1161 | case AArch64_LDRHpost: |
1162 | case AArch64_STRHpost: |
1163 | DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); |
1164 | break; |
1165 | case AArch64_LDURBi: |
1166 | case AArch64_STURBi: |
1167 | case AArch64_LDRBpre: |
1168 | case AArch64_STRBpre: |
1169 | case AArch64_LDRBpost: |
1170 | case AArch64_STRBpost: |
1171 | DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); |
1172 | break; |
1173 | } |
1174 | |
1175 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1176 | MCOperand_CreateImm0(Inst, offset); |
1177 | |
1178 | IsLoad = fieldFromInstruction(insn, 22, 1) != 0; |
1179 | IsIndexed = fieldFromInstruction(insn, 10, 2) != 0; |
1180 | IsFP = fieldFromInstruction(insn, 26, 1) != 0; |
1181 | |
1182 | // Cannot write back to a transfer register (but xzr != sp). |
1183 | if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn) |
1184 | return SoftFail; |
1185 | |
1186 | return Success; |
1187 | } |
1188 | |
1189 | static DecodeStatus DecodeExclusiveLdStInstruction(MCInst *Inst, |
1190 | uint32_t insn, uint64_t Addr, |
1191 | const void *Decoder) |
1192 | { |
1193 | unsigned Rt = fieldFromInstruction(insn, 0, 5); |
1194 | unsigned Rn = fieldFromInstruction(insn, 5, 5); |
1195 | unsigned Rt2 = fieldFromInstruction(insn, 10, 5); |
1196 | unsigned Rs = fieldFromInstruction(insn, 16, 5); |
1197 | unsigned Opcode = MCInst_getOpcode(Inst); |
1198 | |
1199 | switch (Opcode) { |
1200 | default: |
1201 | return Fail; |
1202 | case AArch64_STLXRW: |
1203 | case AArch64_STLXRB: |
1204 | case AArch64_STLXRH: |
1205 | case AArch64_STXRW: |
1206 | case AArch64_STXRB: |
1207 | case AArch64_STXRH: |
1208 | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1209 | // FALLTHROUGH |
1210 | case AArch64_LDARW: |
1211 | case AArch64_LDARB: |
1212 | case AArch64_LDARH: |
1213 | case AArch64_LDAXRW: |
1214 | case AArch64_LDAXRB: |
1215 | case AArch64_LDAXRH: |
1216 | case AArch64_LDXRW: |
1217 | case AArch64_LDXRB: |
1218 | case AArch64_LDXRH: |
1219 | case AArch64_STLRW: |
1220 | case AArch64_STLRB: |
1221 | case AArch64_STLRH: |
1222 | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1223 | break; |
1224 | case AArch64_STLXRX: |
1225 | case AArch64_STXRX: |
1226 | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1227 | // FALLTHROUGH |
1228 | case AArch64_LDARX: |
1229 | case AArch64_LDAXRX: |
1230 | case AArch64_LDXRX: |
1231 | case AArch64_STLRX: |
1232 | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1233 | break; |
1234 | case AArch64_STLXPW: |
1235 | case AArch64_STXPW: |
1236 | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1237 | // FALLTHROUGH |
1238 | case AArch64_LDAXPW: |
1239 | case AArch64_LDXPW: |
1240 | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1241 | DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
1242 | break; |
1243 | case AArch64_STLXPX: |
1244 | case AArch64_STXPX: |
1245 | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1246 | // FALLTHROUGH |
1247 | case AArch64_LDAXPX: |
1248 | case AArch64_LDXPX: |
1249 | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1250 | DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
1251 | break; |
1252 | } |
1253 | |
1254 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1255 | |
1256 | // You shouldn't load to the same register twice in an instruction... |
1257 | if ((Opcode == AArch64_LDAXPW || Opcode == AArch64_LDXPW || |
1258 | Opcode == AArch64_LDAXPX || Opcode == AArch64_LDXPX) && |
1259 | Rt == Rt2) |
1260 | return SoftFail; |
1261 | |
1262 | return Success; |
1263 | } |
1264 | |
1265 | static DecodeStatus DecodePairLdStInstruction(MCInst *Inst, uint32_t insn, |
1266 | uint64_t Addr, |
1267 | const void *Decoder) |
1268 | { |
1269 | unsigned Rt = fieldFromInstruction(insn, 0, 5); |
1270 | unsigned Rn = fieldFromInstruction(insn, 5, 5); |
1271 | unsigned Rt2 = fieldFromInstruction(insn, 10, 5); |
1272 | int64_t offset = fieldFromInstruction(insn, 15, 7); |
1273 | bool IsLoad = fieldFromInstruction(insn, 22, 1) != 0; |
1274 | unsigned Opcode = MCInst_getOpcode(Inst); |
1275 | bool NeedsDisjointWritebackTransfer = false; |
1276 | |
1277 | // offset is a 7-bit signed immediate, so sign extend it to |
1278 | // fill the unsigned. |
1279 | if (offset & (1 << (7 - 1))) |
1280 | offset |= ~((1LL << 7) - 1); |
1281 | |
1282 | // First operand is always writeback of base register. |
1283 | switch (Opcode) { |
1284 | default: |
1285 | break; |
1286 | case AArch64_LDPXpost: |
1287 | case AArch64_STPXpost: |
1288 | case AArch64_LDPSWpost: |
1289 | case AArch64_LDPXpre: |
1290 | case AArch64_STPXpre: |
1291 | case AArch64_LDPSWpre: |
1292 | case AArch64_LDPWpost: |
1293 | case AArch64_STPWpost: |
1294 | case AArch64_LDPWpre: |
1295 | case AArch64_STPWpre: |
1296 | case AArch64_LDPQpost: |
1297 | case AArch64_STPQpost: |
1298 | case AArch64_LDPQpre: |
1299 | case AArch64_STPQpre: |
1300 | case AArch64_LDPDpost: |
1301 | case AArch64_STPDpost: |
1302 | case AArch64_LDPDpre: |
1303 | case AArch64_STPDpre: |
1304 | case AArch64_LDPSpost: |
1305 | case AArch64_STPSpost: |
1306 | case AArch64_LDPSpre: |
1307 | case AArch64_STPSpre: |
1308 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1309 | break; |
1310 | } |
1311 | |
1312 | switch (Opcode) { |
1313 | default: |
1314 | return Fail; |
1315 | case AArch64_LDPXpost: |
1316 | case AArch64_STPXpost: |
1317 | case AArch64_LDPSWpost: |
1318 | case AArch64_LDPXpre: |
1319 | case AArch64_STPXpre: |
1320 | case AArch64_LDPSWpre: |
1321 | NeedsDisjointWritebackTransfer = true; |
1322 | // Fallthrough |
1323 | case AArch64_LDNPXi: |
1324 | case AArch64_STNPXi: |
1325 | case AArch64_LDPXi: |
1326 | case AArch64_STPXi: |
1327 | case AArch64_LDPSWi: |
1328 | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1329 | DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
1330 | break; |
1331 | case AArch64_LDPWpost: |
1332 | case AArch64_STPWpost: |
1333 | case AArch64_LDPWpre: |
1334 | case AArch64_STPWpre: |
1335 | NeedsDisjointWritebackTransfer = true; |
1336 | // Fallthrough |
1337 | case AArch64_LDNPWi: |
1338 | case AArch64_STNPWi: |
1339 | case AArch64_LDPWi: |
1340 | case AArch64_STPWi: |
1341 | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1342 | DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
1343 | break; |
1344 | case AArch64_LDNPQi: |
1345 | case AArch64_STNPQi: |
1346 | case AArch64_LDPQpost: |
1347 | case AArch64_STPQpost: |
1348 | case AArch64_LDPQi: |
1349 | case AArch64_STPQi: |
1350 | case AArch64_LDPQpre: |
1351 | case AArch64_STPQpre: |
1352 | DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
1353 | DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder); |
1354 | break; |
1355 | case AArch64_LDNPDi: |
1356 | case AArch64_STNPDi: |
1357 | case AArch64_LDPDpost: |
1358 | case AArch64_STPDpost: |
1359 | case AArch64_LDPDi: |
1360 | case AArch64_STPDi: |
1361 | case AArch64_LDPDpre: |
1362 | case AArch64_STPDpre: |
1363 | DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1364 | DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
1365 | break; |
1366 | case AArch64_LDNPSi: |
1367 | case AArch64_STNPSi: |
1368 | case AArch64_LDPSpost: |
1369 | case AArch64_STPSpost: |
1370 | case AArch64_LDPSi: |
1371 | case AArch64_STPSi: |
1372 | case AArch64_LDPSpre: |
1373 | case AArch64_STPSpre: |
1374 | DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1375 | DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
1376 | break; |
1377 | } |
1378 | |
1379 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1380 | MCOperand_CreateImm0(Inst, offset); |
1381 | |
1382 | // You shouldn't load to the same register twice in an instruction... |
1383 | if (IsLoad && Rt == Rt2) |
1384 | return SoftFail; |
1385 | |
1386 | // ... or do any operation that writes-back to a transfer register. But note |
1387 | // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different. |
1388 | if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn)) |
1389 | return SoftFail; |
1390 | |
1391 | return Success; |
1392 | } |
1393 | |
1394 | static DecodeStatus DecodeAddSubERegInstruction(MCInst *Inst, |
1395 | uint32_t insn, uint64_t Addr, |
1396 | const void *Decoder) |
1397 | { |
1398 | unsigned Rd, Rn, Rm; |
1399 | unsigned extend = fieldFromInstruction(insn, 10, 6); |
1400 | unsigned shift = extend & 0x7; |
1401 | |
1402 | if (shift > 4) |
1403 | return Fail; |
1404 | |
1405 | Rd = fieldFromInstruction(insn, 0, 5); |
1406 | Rn = fieldFromInstruction(insn, 5, 5); |
1407 | Rm = fieldFromInstruction(insn, 16, 5); |
1408 | |
1409 | switch (MCInst_getOpcode(Inst)) { |
1410 | default: |
1411 | return Fail; |
1412 | case AArch64_ADDWrx: |
1413 | case AArch64_SUBWrx: |
1414 | DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
1415 | DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
1416 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1417 | break; |
1418 | case AArch64_ADDSWrx: |
1419 | case AArch64_SUBSWrx: |
1420 | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1421 | DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
1422 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1423 | break; |
1424 | case AArch64_ADDXrx: |
1425 | case AArch64_SUBXrx: |
1426 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
1427 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1428 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1429 | break; |
1430 | case AArch64_ADDSXrx: |
1431 | case AArch64_SUBSXrx: |
1432 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1433 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1434 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1435 | break; |
1436 | case AArch64_ADDXrx64: |
1437 | case AArch64_SUBXrx64: |
1438 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
1439 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1440 | DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
1441 | break; |
1442 | case AArch64_SUBSXrx64: |
1443 | case AArch64_ADDSXrx64: |
1444 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1445 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1446 | DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
1447 | break; |
1448 | } |
1449 | |
1450 | MCOperand_CreateImm0(Inst, extend); |
1451 | return Success; |
1452 | } |
1453 | |
1454 | static DecodeStatus DecodeLogicalImmInstruction(MCInst *Inst, |
1455 | uint32_t insn, uint64_t Addr, |
1456 | const void *Decoder) |
1457 | { |
1458 | unsigned Rd = fieldFromInstruction(insn, 0, 5); |
1459 | unsigned Rn = fieldFromInstruction(insn, 5, 5); |
1460 | unsigned Datasize = fieldFromInstruction(insn, 31, 1); |
1461 | unsigned imm; |
1462 | |
1463 | if (Datasize) { |
1464 | if (MCInst_getOpcode(Inst) == AArch64_ANDSXri) |
1465 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1466 | else |
1467 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
1468 | DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); |
1469 | imm = fieldFromInstruction(insn, 10, 13); |
1470 | if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 64)) |
1471 | return Fail; |
1472 | } else { |
1473 | if (MCInst_getOpcode(Inst) == AArch64_ANDSWri) |
1474 | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1475 | else |
1476 | DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
1477 | DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); |
1478 | imm = fieldFromInstruction(insn, 10, 12); |
1479 | if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 32)) |
1480 | return Fail; |
1481 | } |
1482 | |
1483 | MCOperand_CreateImm0(Inst, imm); |
1484 | return Success; |
1485 | } |
1486 | |
1487 | static DecodeStatus DecodeModImmInstruction(MCInst *Inst, uint32_t insn, |
1488 | uint64_t Addr, |
1489 | const void *Decoder) |
1490 | { |
1491 | unsigned Rd = fieldFromInstruction(insn, 0, 5); |
1492 | unsigned cmode = fieldFromInstruction(insn, 12, 4); |
1493 | unsigned imm = fieldFromInstruction(insn, 16, 3) << 5; |
1494 | imm |= fieldFromInstruction(insn, 5, 5); |
1495 | |
1496 | if (MCInst_getOpcode(Inst) == AArch64_MOVID) |
1497 | DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1498 | else |
1499 | DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
1500 | |
1501 | MCOperand_CreateImm0(Inst, imm); |
1502 | |
1503 | switch (MCInst_getOpcode(Inst)) { |
1504 | default: |
1505 | break; |
1506 | case AArch64_MOVIv4i16: |
1507 | case AArch64_MOVIv8i16: |
1508 | case AArch64_MVNIv4i16: |
1509 | case AArch64_MVNIv8i16: |
1510 | case AArch64_MOVIv2i32: |
1511 | case AArch64_MOVIv4i32: |
1512 | case AArch64_MVNIv2i32: |
1513 | case AArch64_MVNIv4i32: |
1514 | MCOperand_CreateImm0(Inst, (cmode & 6) << 2); |
1515 | break; |
1516 | case AArch64_MOVIv2s_msl: |
1517 | case AArch64_MOVIv4s_msl: |
1518 | case AArch64_MVNIv2s_msl: |
1519 | case AArch64_MVNIv4s_msl: |
1520 | MCOperand_CreateImm0(Inst, cmode & 1 ? 0x110 : 0x108); |
1521 | break; |
1522 | } |
1523 | |
1524 | return Success; |
1525 | } |
1526 | |
1527 | static DecodeStatus DecodeModImmTiedInstruction(MCInst *Inst, |
1528 | uint32_t insn, uint64_t Addr, |
1529 | const void *Decoder) |
1530 | { |
1531 | unsigned Rd = fieldFromInstruction(insn, 0, 5); |
1532 | unsigned cmode = fieldFromInstruction(insn, 12, 4); |
1533 | unsigned imm = fieldFromInstruction(insn, 16, 3) << 5; |
1534 | imm |= fieldFromInstruction(insn, 5, 5); |
1535 | |
1536 | // Tied operands added twice. |
1537 | DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
1538 | DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
1539 | |
1540 | MCOperand_CreateImm0(Inst, imm); |
1541 | MCOperand_CreateImm0(Inst, (cmode & 6) << 2); |
1542 | |
1543 | return Success; |
1544 | } |
1545 | |
1546 | static DecodeStatus DecodeAdrInstruction(MCInst *Inst, uint32_t insn, |
1547 | uint64_t Addr, const void *Decoder) |
1548 | { |
1549 | unsigned Rd = fieldFromInstruction(insn, 0, 5); |
1550 | int64_t imm = fieldFromInstruction(insn, 5, 19) << 2; |
1551 | imm |= fieldFromInstruction(insn, 29, 2); |
1552 | |
1553 | // Sign-extend the 21-bit immediate. |
1554 | if (imm & (1 << (21 - 1))) |
1555 | imm |= ~((1LL << 21) - 1); |
1556 | |
1557 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1558 | //if (!Dis->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 4)) |
1559 | MCOperand_CreateImm0(Inst, imm); |
1560 | |
1561 | return Success; |
1562 | } |
1563 | |
1564 | static DecodeStatus DecodeBaseAddSubImm(MCInst *Inst, uint32_t insn, |
1565 | uint64_t Addr, const void *Decoder) |
1566 | { |
1567 | unsigned Rd = fieldFromInstruction(insn, 0, 5); |
1568 | unsigned Rn = fieldFromInstruction(insn, 5, 5); |
1569 | unsigned Imm = fieldFromInstruction(insn, 10, 14); |
1570 | unsigned S = fieldFromInstruction(insn, 29, 1); |
1571 | unsigned Datasize = fieldFromInstruction(insn, 31, 1); |
1572 | |
1573 | unsigned ShifterVal = (Imm >> 12) & 3; |
1574 | unsigned ImmVal = Imm & 0xFFF; |
1575 | |
1576 | if (ShifterVal != 0 && ShifterVal != 1) |
1577 | return Fail; |
1578 | |
1579 | if (Datasize) { |
1580 | if (Rd == 31 && !S) |
1581 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
1582 | else |
1583 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1584 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1585 | } else { |
1586 | if (Rd == 31 && !S) |
1587 | DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
1588 | else |
1589 | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1590 | DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
1591 | } |
1592 | |
1593 | //if (!Dis->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 4)) |
1594 | MCOperand_CreateImm0(Inst, ImmVal); |
1595 | MCOperand_CreateImm0(Inst, 12 * ShifterVal); |
1596 | return Success; |
1597 | } |
1598 | |
1599 | static DecodeStatus DecodeUnconditionalBranch(MCInst *Inst, uint32_t insn, |
1600 | uint64_t Addr, |
1601 | const void *Decoder) |
1602 | { |
1603 | int64_t imm = fieldFromInstruction(insn, 0, 26); |
1604 | |
1605 | // Sign-extend the 26-bit immediate. |
1606 | if (imm & (1 << (26 - 1))) |
1607 | imm |= ~((1LL << 26) - 1); |
1608 | |
1609 | // if (!Dis->tryAddingSymbolicOperand(Inst, imm << 2, Addr, true, 0, 4)) |
1610 | MCOperand_CreateImm0(Inst, imm); |
1611 | |
1612 | return Success; |
1613 | } |
1614 | |
1615 | static DecodeStatus DecodeSystemPStateInstruction(MCInst *Inst, |
1616 | uint32_t insn, uint64_t Addr, |
1617 | const void *Decoder) |
1618 | { |
1619 | uint32_t op1 = fieldFromInstruction(insn, 16, 3); |
1620 | uint32_t op2 = fieldFromInstruction(insn, 5, 3); |
1621 | uint32_t crm = fieldFromInstruction(insn, 8, 4); |
1622 | bool ValidNamed; |
1623 | uint32_t pstate_field = (op1 << 3) | op2; |
1624 | |
1625 | MCOperand_CreateImm0(Inst, pstate_field); |
1626 | MCOperand_CreateImm0(Inst, crm); |
1627 | |
1628 | A64NamedImmMapper_toString(&A64PState_PStateMapper, pstate_field, &ValidNamed); |
1629 | |
1630 | return ValidNamed ? Success : Fail; |
1631 | } |
1632 | |
1633 | static DecodeStatus DecodeTestAndBranch(MCInst *Inst, uint32_t insn, |
1634 | uint64_t Addr, const void *Decoder) |
1635 | { |
1636 | uint32_t Rt = fieldFromInstruction(insn, 0, 5); |
1637 | uint32_t bit = fieldFromInstruction(insn, 31, 1) << 5; |
1638 | uint32_t dst = fieldFromInstruction(insn, 5, 14); |
1639 | |
1640 | bit |= fieldFromInstruction(insn, 19, 5); |
1641 | |
1642 | // Sign-extend 14-bit immediate. |
1643 | if (dst & (1 << (14 - 1))) |
1644 | dst |= ~((1LL << 14) - 1); |
1645 | |
1646 | if (fieldFromInstruction(insn, 31, 1) == 0) |
1647 | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1648 | else |
1649 | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1650 | |
1651 | MCOperand_CreateImm0(Inst, bit); |
1652 | //if (!Dis->tryAddingSymbolicOperand(Inst, dst << 2, Addr, true, 0, 4)) |
1653 | MCOperand_CreateImm0(Inst, dst); |
1654 | |
1655 | return Success; |
1656 | } |
1657 | |
1658 | void AArch64_init(MCRegisterInfo *MRI) |
1659 | { |
1660 | /* |
1661 | InitMCRegisterInfo(AArch64RegDesc, 420, |
1662 | RA, PC, |
1663 | AArch64MCRegisterClasses, 43, |
1664 | AArch64RegUnitRoots, 66, AArch64RegDiffLists, |
1665 | AArch64RegStrings, |
1666 | AArch64SubRegIdxLists, 53, |
1667 | AArch64SubRegIdxRanges, |
1668 | AArch64RegEncodingTable); |
1669 | */ |
1670 | |
1671 | MCRegisterInfo_InitMCRegisterInfo(MRI, AArch64RegDesc, 420, |
1672 | 0, 0, |
1673 | AArch64MCRegisterClasses, 43, |
1674 | 0, 0, AArch64RegDiffLists, |
1675 | 0, |
1676 | AArch64SubRegIdxLists, 53, |
1677 | 0); |
1678 | } |
1679 | |
1680 | #endif |
1681 | |