| //===- AArch64Disassembler.cpp - Disassembler for AArch64 ISA -------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains the functions necessary to decode AArch64 instruction |
| // bitpatterns into MCInsts (with the help of TableGenerated information from |
| // the instruction definitions). |
| // |
| //===----------------------------------------------------------------------===// |
| |
| /* Capstone Disassembly Engine */ |
| /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */ |
| |
| #ifdef CAPSTONE_HAS_ARM64 |
| |
| #include <stdio.h> // DEBUG |
| #include <stdlib.h> |
| |
| #include "../../cs_priv.h" |
| #include "../../utils.h" |
| |
| #include "../../MCInst.h" |
| #include "../../MCInstrDesc.h" |
| #include "../../MCFixedLenDisassembler.h" |
| #include "../../MCRegisterInfo.h" |
| #include "../../MCDisassembler.h" |
| |
| #include "AArch64BaseInfo.h" |
| #include "AArch64AddressingModes.h" |
| |
| |
| // Forward declare these because the autogenerated code will reference them. |
| // Definitions are further down. |
| static DecodeStatus DecodeFPR128RegisterClass(MCInst *Inst, |
| unsigned RegNo, uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeFPR128_loRegisterClass(MCInst *Inst, |
| unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeFPR8RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeGPR64spRegisterClass(MCInst *Inst, |
| unsigned RegNo, uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeGPR32spRegisterClass(MCInst *Inst, |
| unsigned RegNo, uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeQQRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeQQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeDDRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeDDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Address, |
| void *Decoder); |
| |
| static DecodeStatus DecodeFixedPointScaleImm32(MCInst *Inst, unsigned Imm, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeFixedPointScaleImm64(MCInst *Inst, unsigned Imm, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodePCRelLabel19(MCInst *Inst, unsigned Imm, |
| uint64_t Address, void *Decoder); |
| static DecodeStatus DecodeMemExtend(MCInst *Inst, unsigned Imm, |
| uint64_t Address, void *Decoder); |
| static DecodeStatus DecodeMRSSystemRegister(MCInst *Inst, unsigned Imm, |
| uint64_t Address, void *Decoder); |
| static DecodeStatus DecodeMSRSystemRegister(MCInst *Inst, unsigned Imm, |
| uint64_t Address, void *Decoder); |
| static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst *Inst, |
| uint32_t insn, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeMoveImmInstruction(MCInst *Inst, uint32_t insn, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeUnsignedLdStInstruction(MCInst *Inst, |
| uint32_t insn, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeSignedLdStInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeExclusiveLdStInstruction(MCInst *Inst, |
| uint32_t insn, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodePairLdStInstruction(MCInst *Inst, uint32_t insn, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeAddSubERegInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeLogicalImmInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeModImmInstruction(MCInst *Inst, uint32_t insn, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeModImmTiedInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeAdrInstruction(MCInst *Inst, uint32_t insn, |
| uint64_t Address, void *Decoder); |
| static DecodeStatus DecodeBaseAddSubImm(MCInst *Inst, uint32_t insn, |
| uint64_t Address, void *Decoder); |
| static DecodeStatus DecodeUnconditionalBranch(MCInst *Inst, uint32_t insn, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeSystemPStateInstruction(MCInst *Inst, |
| uint32_t insn, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeTestAndBranch(MCInst *Inst, uint32_t insn, |
| uint64_t Address, void *Decoder); |
| |
| static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn, |
| uint64_t Address, |
| void *Decoder); |
| static DecodeStatus DecodeVecShiftR64Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder); |
| static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, |
| void *Decoder); |
| static DecodeStatus DecodeVecShiftR32Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder); |
| static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, |
| void *Decoder); |
| static DecodeStatus DecodeVecShiftR16Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder); |
| static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, |
| void *Decoder); |
| static DecodeStatus DecodeVecShiftR8Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder); |
| static DecodeStatus DecodeVecShiftL64Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder); |
| static DecodeStatus DecodeVecShiftL32Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder); |
| static DecodeStatus DecodeVecShiftL16Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder); |
| static DecodeStatus DecodeVecShiftL8Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder); |
| |
| static bool Check(DecodeStatus *Out, DecodeStatus In) |
| { |
| switch (In) { |
| default: // never reach |
| return true; |
| case MCDisassembler_Success: |
| // Out stays the same. |
| return true; |
| case MCDisassembler_SoftFail: |
| *Out = In; |
| return true; |
| case MCDisassembler_Fail: |
| *Out = In; |
| return false; |
| } |
| // llvm_unreachable("Invalid DecodeStatus!"); |
| } |
| |
| // Hacky: enable all features for disassembler |
| static uint64_t getFeatureBits(int feature) |
| { |
| // enable all features |
| return (uint64_t)-1; |
| } |
| |
| #define GET_SUBTARGETINFO_ENUM |
| #include "AArch64GenSubtargetInfo.inc" |
| |
| #include "AArch64GenDisassemblerTables.inc" |
| |
| #define GET_INSTRINFO_ENUM |
| #include "AArch64GenInstrInfo.inc" |
| |
| #define GET_REGINFO_ENUM |
| #define GET_REGINFO_MC_DESC |
| #include "AArch64GenRegisterInfo.inc" |
| |
| #define Success MCDisassembler_Success |
| #define Fail MCDisassembler_Fail |
| #define SoftFail MCDisassembler_SoftFail |
| |
| static DecodeStatus _getInstruction(cs_struct *ud, MCInst *MI, |
| const uint8_t *code, size_t code_len, |
| uint16_t *Size, |
| uint64_t Address, MCRegisterInfo *MRI) |
| { |
| uint32_t insn; |
| DecodeStatus result; |
| size_t i; |
| |
| if (code_len < 4) { |
| // not enough data |
| *Size = 0; |
| return MCDisassembler_Fail; |
| } |
| |
| if (MI->flat_insn->detail) { |
| memset(MI->flat_insn->detail, 0, sizeof(cs_detail)); |
| for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm64.operands); i++) |
| MI->flat_insn->detail->arm64.operands[i].vector_index = -1; |
| } |
| |
| if (ud->big_endian) |
| insn = (code[3] << 0) | (code[2] << 8) | |
| (code[1] << 16) | (code[0] << 24); |
| else |
| insn = (code[3] << 24) | (code[2] << 16) | |
| (code[1] << 8) | (code[0] << 0); |
| |
| // Calling the auto-generated decoder function. |
| result = decodeInstruction(DecoderTable32, MI, insn, Address, MRI, 0); |
| if (result != MCDisassembler_Fail) { |
| *Size = 4; |
| return result; |
| } |
| |
| MCInst_clear(MI); |
| *Size = 0; |
| return MCDisassembler_Fail; |
| } |
| |
| bool AArch64_getInstruction(csh ud, const uint8_t *code, size_t code_len, |
| MCInst *instr, uint16_t *size, uint64_t address, void *info) |
| { |
| DecodeStatus status = _getInstruction((cs_struct *)ud, instr, |
| code, code_len, |
| size, |
| address, (MCRegisterInfo *)info); |
| |
| return status == MCDisassembler_Success; |
| } |
| |
| static const unsigned FPR128DecoderTable[] = { |
| AArch64_Q0, AArch64_Q1, AArch64_Q2, AArch64_Q3, AArch64_Q4, |
| AArch64_Q5, AArch64_Q6, AArch64_Q7, AArch64_Q8, AArch64_Q9, |
| AArch64_Q10, AArch64_Q11, AArch64_Q12, AArch64_Q13, AArch64_Q14, |
| AArch64_Q15, AArch64_Q16, AArch64_Q17, AArch64_Q18, AArch64_Q19, |
| AArch64_Q20, AArch64_Q21, AArch64_Q22, AArch64_Q23, AArch64_Q24, |
| AArch64_Q25, AArch64_Q26, AArch64_Q27, AArch64_Q28, AArch64_Q29, |
| AArch64_Q30, AArch64_Q31 |
| }; |
| |
| static DecodeStatus DecodeFPR128RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = FPR128DecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeFPR128_loRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| if (RegNo > 15) |
| return Fail; |
| |
| return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder); |
| } |
| |
| static const unsigned FPR64DecoderTable[] = { |
| AArch64_D0, AArch64_D1, AArch64_D2, AArch64_D3, AArch64_D4, |
| AArch64_D5, AArch64_D6, AArch64_D7, AArch64_D8, AArch64_D9, |
| AArch64_D10, AArch64_D11, AArch64_D12, AArch64_D13, AArch64_D14, |
| AArch64_D15, AArch64_D16, AArch64_D17, AArch64_D18, AArch64_D19, |
| AArch64_D20, AArch64_D21, AArch64_D22, AArch64_D23, AArch64_D24, |
| AArch64_D25, AArch64_D26, AArch64_D27, AArch64_D28, AArch64_D29, |
| AArch64_D30, AArch64_D31 |
| }; |
| |
| static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = FPR64DecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned FPR32DecoderTable[] = { |
| AArch64_S0, AArch64_S1, AArch64_S2, AArch64_S3, AArch64_S4, |
| AArch64_S5, AArch64_S6, AArch64_S7, AArch64_S8, AArch64_S9, |
| AArch64_S10, AArch64_S11, AArch64_S12, AArch64_S13, AArch64_S14, |
| AArch64_S15, AArch64_S16, AArch64_S17, AArch64_S18, AArch64_S19, |
| AArch64_S20, AArch64_S21, AArch64_S22, AArch64_S23, AArch64_S24, |
| AArch64_S25, AArch64_S26, AArch64_S27, AArch64_S28, AArch64_S29, |
| AArch64_S30, AArch64_S31 |
| }; |
| |
| static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = FPR32DecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned FPR16DecoderTable[] = { |
| AArch64_H0, AArch64_H1, AArch64_H2, AArch64_H3, AArch64_H4, |
| AArch64_H5, AArch64_H6, AArch64_H7, AArch64_H8, AArch64_H9, |
| AArch64_H10, AArch64_H11, AArch64_H12, AArch64_H13, AArch64_H14, |
| AArch64_H15, AArch64_H16, AArch64_H17, AArch64_H18, AArch64_H19, |
| AArch64_H20, AArch64_H21, AArch64_H22, AArch64_H23, AArch64_H24, |
| AArch64_H25, AArch64_H26, AArch64_H27, AArch64_H28, AArch64_H29, |
| AArch64_H30, AArch64_H31 |
| }; |
| |
| static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = FPR16DecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned FPR8DecoderTable[] = { |
| AArch64_B0, AArch64_B1, AArch64_B2, AArch64_B3, AArch64_B4, |
| AArch64_B5, AArch64_B6, AArch64_B7, AArch64_B8, AArch64_B9, |
| AArch64_B10, AArch64_B11, AArch64_B12, AArch64_B13, AArch64_B14, |
| AArch64_B15, AArch64_B16, AArch64_B17, AArch64_B18, AArch64_B19, |
| AArch64_B20, AArch64_B21, AArch64_B22, AArch64_B23, AArch64_B24, |
| AArch64_B25, AArch64_B26, AArch64_B27, AArch64_B28, AArch64_B29, |
| AArch64_B30, AArch64_B31 |
| }; |
| |
| static DecodeStatus DecodeFPR8RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = FPR8DecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned GPR64DecoderTable[] = { |
| AArch64_X0, AArch64_X1, AArch64_X2, AArch64_X3, AArch64_X4, |
| AArch64_X5, AArch64_X6, AArch64_X7, AArch64_X8, AArch64_X9, |
| AArch64_X10, AArch64_X11, AArch64_X12, AArch64_X13, AArch64_X14, |
| AArch64_X15, AArch64_X16, AArch64_X17, AArch64_X18, AArch64_X19, |
| AArch64_X20, AArch64_X21, AArch64_X22, AArch64_X23, AArch64_X24, |
| AArch64_X25, AArch64_X26, AArch64_X27, AArch64_X28, AArch64_FP, |
| AArch64_LR, AArch64_XZR |
| }; |
| |
| static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = GPR64DecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeGPR64spRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = GPR64DecoderTable[RegNo]; |
| if (Register == AArch64_XZR) |
| Register = AArch64_SP; |
| |
| MCOperand_CreateReg0(Inst, Register); |
| |
| return Success; |
| } |
| |
| static const unsigned GPR32DecoderTable[] = { |
| AArch64_W0, AArch64_W1, AArch64_W2, AArch64_W3, AArch64_W4, |
| AArch64_W5, AArch64_W6, AArch64_W7, AArch64_W8, AArch64_W9, |
| AArch64_W10, AArch64_W11, AArch64_W12, AArch64_W13, AArch64_W14, |
| AArch64_W15, AArch64_W16, AArch64_W17, AArch64_W18, AArch64_W19, |
| AArch64_W20, AArch64_W21, AArch64_W22, AArch64_W23, AArch64_W24, |
| AArch64_W25, AArch64_W26, AArch64_W27, AArch64_W28, AArch64_W29, |
| AArch64_W30, AArch64_WZR |
| }; |
| |
| static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = GPR32DecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeGPR32spRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = GPR32DecoderTable[RegNo]; |
| if (Register == AArch64_WZR) |
| Register = AArch64_WSP; |
| |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned VectorDecoderTable[] = { |
| AArch64_Q0, AArch64_Q1, AArch64_Q2, AArch64_Q3, AArch64_Q4, |
| AArch64_Q5, AArch64_Q6, AArch64_Q7, AArch64_Q8, AArch64_Q9, |
| AArch64_Q10, AArch64_Q11, AArch64_Q12, AArch64_Q13, AArch64_Q14, |
| AArch64_Q15, AArch64_Q16, AArch64_Q17, AArch64_Q18, AArch64_Q19, |
| AArch64_Q20, AArch64_Q21, AArch64_Q22, AArch64_Q23, AArch64_Q24, |
| AArch64_Q25, AArch64_Q26, AArch64_Q27, AArch64_Q28, AArch64_Q29, |
| AArch64_Q30, AArch64_Q31 |
| }; |
| |
| static DecodeStatus DecodeVectorRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = VectorDecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned QQDecoderTable[] = { |
| AArch64_Q0_Q1, AArch64_Q1_Q2, AArch64_Q2_Q3, AArch64_Q3_Q4, |
| AArch64_Q4_Q5, AArch64_Q5_Q6, AArch64_Q6_Q7, AArch64_Q7_Q8, |
| AArch64_Q8_Q9, AArch64_Q9_Q10, AArch64_Q10_Q11, AArch64_Q11_Q12, |
| AArch64_Q12_Q13, AArch64_Q13_Q14, AArch64_Q14_Q15, AArch64_Q15_Q16, |
| AArch64_Q16_Q17, AArch64_Q17_Q18, AArch64_Q18_Q19, AArch64_Q19_Q20, |
| AArch64_Q20_Q21, AArch64_Q21_Q22, AArch64_Q22_Q23, AArch64_Q23_Q24, |
| AArch64_Q24_Q25, AArch64_Q25_Q26, AArch64_Q26_Q27, AArch64_Q27_Q28, |
| AArch64_Q28_Q29, AArch64_Q29_Q30, AArch64_Q30_Q31, AArch64_Q31_Q0 |
| }; |
| |
| static DecodeStatus DecodeQQRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = QQDecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned QQQDecoderTable[] = { |
| AArch64_Q0_Q1_Q2, AArch64_Q1_Q2_Q3, AArch64_Q2_Q3_Q4, |
| AArch64_Q3_Q4_Q5, AArch64_Q4_Q5_Q6, AArch64_Q5_Q6_Q7, |
| AArch64_Q6_Q7_Q8, AArch64_Q7_Q8_Q9, AArch64_Q8_Q9_Q10, |
| AArch64_Q9_Q10_Q11, AArch64_Q10_Q11_Q12, AArch64_Q11_Q12_Q13, |
| AArch64_Q12_Q13_Q14, AArch64_Q13_Q14_Q15, AArch64_Q14_Q15_Q16, |
| AArch64_Q15_Q16_Q17, AArch64_Q16_Q17_Q18, AArch64_Q17_Q18_Q19, |
| AArch64_Q18_Q19_Q20, AArch64_Q19_Q20_Q21, AArch64_Q20_Q21_Q22, |
| AArch64_Q21_Q22_Q23, AArch64_Q22_Q23_Q24, AArch64_Q23_Q24_Q25, |
| AArch64_Q24_Q25_Q26, AArch64_Q25_Q26_Q27, AArch64_Q26_Q27_Q28, |
| AArch64_Q27_Q28_Q29, AArch64_Q28_Q29_Q30, AArch64_Q29_Q30_Q31, |
| AArch64_Q30_Q31_Q0, AArch64_Q31_Q0_Q1 |
| }; |
| |
| static DecodeStatus DecodeQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = QQQDecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned QQQQDecoderTable[] = { |
| AArch64_Q0_Q1_Q2_Q3, AArch64_Q1_Q2_Q3_Q4, AArch64_Q2_Q3_Q4_Q5, |
| AArch64_Q3_Q4_Q5_Q6, AArch64_Q4_Q5_Q6_Q7, AArch64_Q5_Q6_Q7_Q8, |
| AArch64_Q6_Q7_Q8_Q9, AArch64_Q7_Q8_Q9_Q10, AArch64_Q8_Q9_Q10_Q11, |
| AArch64_Q9_Q10_Q11_Q12, AArch64_Q10_Q11_Q12_Q13, AArch64_Q11_Q12_Q13_Q14, |
| AArch64_Q12_Q13_Q14_Q15, AArch64_Q13_Q14_Q15_Q16, AArch64_Q14_Q15_Q16_Q17, |
| AArch64_Q15_Q16_Q17_Q18, AArch64_Q16_Q17_Q18_Q19, AArch64_Q17_Q18_Q19_Q20, |
| AArch64_Q18_Q19_Q20_Q21, AArch64_Q19_Q20_Q21_Q22, AArch64_Q20_Q21_Q22_Q23, |
| AArch64_Q21_Q22_Q23_Q24, AArch64_Q22_Q23_Q24_Q25, AArch64_Q23_Q24_Q25_Q26, |
| AArch64_Q24_Q25_Q26_Q27, AArch64_Q25_Q26_Q27_Q28, AArch64_Q26_Q27_Q28_Q29, |
| AArch64_Q27_Q28_Q29_Q30, AArch64_Q28_Q29_Q30_Q31, AArch64_Q29_Q30_Q31_Q0, |
| AArch64_Q30_Q31_Q0_Q1, AArch64_Q31_Q0_Q1_Q2 |
| }; |
| |
| static DecodeStatus DecodeQQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = QQQQDecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned DDDecoderTable[] = { |
| AArch64_D0_D1, AArch64_D1_D2, AArch64_D2_D3, AArch64_D3_D4, |
| AArch64_D4_D5, AArch64_D5_D6, AArch64_D6_D7, AArch64_D7_D8, |
| AArch64_D8_D9, AArch64_D9_D10, AArch64_D10_D11, AArch64_D11_D12, |
| AArch64_D12_D13, AArch64_D13_D14, AArch64_D14_D15, AArch64_D15_D16, |
| AArch64_D16_D17, AArch64_D17_D18, AArch64_D18_D19, AArch64_D19_D20, |
| AArch64_D20_D21, AArch64_D21_D22, AArch64_D22_D23, AArch64_D23_D24, |
| AArch64_D24_D25, AArch64_D25_D26, AArch64_D26_D27, AArch64_D27_D28, |
| AArch64_D28_D29, AArch64_D29_D30, AArch64_D30_D31, AArch64_D31_D0 |
| }; |
| |
| static DecodeStatus DecodeDDRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = DDDecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned DDDDecoderTable[] = { |
| AArch64_D0_D1_D2, AArch64_D1_D2_D3, AArch64_D2_D3_D4, |
| AArch64_D3_D4_D5, AArch64_D4_D5_D6, AArch64_D5_D6_D7, |
| AArch64_D6_D7_D8, AArch64_D7_D8_D9, AArch64_D8_D9_D10, |
| AArch64_D9_D10_D11, AArch64_D10_D11_D12, AArch64_D11_D12_D13, |
| AArch64_D12_D13_D14, AArch64_D13_D14_D15, AArch64_D14_D15_D16, |
| AArch64_D15_D16_D17, AArch64_D16_D17_D18, AArch64_D17_D18_D19, |
| AArch64_D18_D19_D20, AArch64_D19_D20_D21, AArch64_D20_D21_D22, |
| AArch64_D21_D22_D23, AArch64_D22_D23_D24, AArch64_D23_D24_D25, |
| AArch64_D24_D25_D26, AArch64_D25_D26_D27, AArch64_D26_D27_D28, |
| AArch64_D27_D28_D29, AArch64_D28_D29_D30, AArch64_D29_D30_D31, |
| AArch64_D30_D31_D0, AArch64_D31_D0_D1 |
| }; |
| |
| static DecodeStatus DecodeDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = DDDDecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static const unsigned DDDDDecoderTable[] = { |
| AArch64_D0_D1_D2_D3, AArch64_D1_D2_D3_D4, AArch64_D2_D3_D4_D5, |
| AArch64_D3_D4_D5_D6, AArch64_D4_D5_D6_D7, AArch64_D5_D6_D7_D8, |
| AArch64_D6_D7_D8_D9, AArch64_D7_D8_D9_D10, AArch64_D8_D9_D10_D11, |
| AArch64_D9_D10_D11_D12, AArch64_D10_D11_D12_D13, AArch64_D11_D12_D13_D14, |
| AArch64_D12_D13_D14_D15, AArch64_D13_D14_D15_D16, AArch64_D14_D15_D16_D17, |
| AArch64_D15_D16_D17_D18, AArch64_D16_D17_D18_D19, AArch64_D17_D18_D19_D20, |
| AArch64_D18_D19_D20_D21, AArch64_D19_D20_D21_D22, AArch64_D20_D21_D22_D23, |
| AArch64_D21_D22_D23_D24, AArch64_D22_D23_D24_D25, AArch64_D23_D24_D25_D26, |
| AArch64_D24_D25_D26_D27, AArch64_D25_D26_D27_D28, AArch64_D26_D27_D28_D29, |
| AArch64_D27_D28_D29_D30, AArch64_D28_D29_D30_D31, AArch64_D29_D30_D31_D0, |
| AArch64_D30_D31_D0_D1, AArch64_D31_D0_D1_D2 |
| }; |
| |
| static DecodeStatus DecodeDDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Register; |
| |
| if (RegNo > 31) |
| return Fail; |
| |
| Register = DDDDDecoderTable[RegNo]; |
| MCOperand_CreateReg0(Inst, Register); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeFixedPointScaleImm32(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| // scale{5} is asserted as 1 in tblgen. |
| Imm |= 0x20; |
| MCOperand_CreateImm0(Inst, 64 - Imm); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeFixedPointScaleImm64(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| MCOperand_CreateImm0(Inst, 64 - Imm); |
| return Success; |
| } |
| |
| static DecodeStatus DecodePCRelLabel19(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder) |
| { |
| int64_t ImmVal = Imm; |
| |
| // Sign-extend 19-bit immediate. |
| if (ImmVal & (1 << (19 - 1))) |
| ImmVal |= ~((1LL << 19) - 1); |
| |
| MCOperand_CreateImm0(Inst, ImmVal); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeMemExtend(MCInst *Inst, unsigned Imm, |
| uint64_t Address, void *Decoder) |
| { |
| MCOperand_CreateImm0(Inst, (Imm >> 1) & 1); |
| MCOperand_CreateImm0(Inst, Imm & 1); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeMRSSystemRegister(MCInst *Inst, unsigned Imm, |
| uint64_t Address, void *Decoder) |
| { |
| MCOperand_CreateImm0(Inst, Imm); |
| |
| // Every system register in the encoding space is valid with the syntax |
| // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds. |
| return Success; |
| } |
| |
| static DecodeStatus DecodeMSRSystemRegister(MCInst *Inst, unsigned Imm, |
| uint64_t Address, |
| void *Decoder) |
| { |
| MCOperand_CreateImm0(Inst, Imm); |
| |
| return Success; |
| } |
| |
| static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn, |
| uint64_t Address, |
| void *Decoder) |
| { |
| // This decoder exists to add the dummy Lane operand to the MCInst, which must |
| // be 1 in assembly but has no other real manifestation. |
| unsigned Rd = fieldFromInstruction(Insn, 0, 5); |
| unsigned Rn = fieldFromInstruction(Insn, 5, 5); |
| unsigned IsToVec = fieldFromInstruction(Insn, 16, 1); |
| |
| if (IsToVec) { |
| DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder); |
| DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder); |
| } else { |
| DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder); |
| DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder); |
| } |
| |
| // Add the lane |
| MCOperand_CreateImm0(Inst, 1); |
| |
| return Success; |
| } |
| |
| static DecodeStatus DecodeVecShiftRImm(MCInst *Inst, unsigned Imm, |
| unsigned Add) |
| { |
| MCOperand_CreateImm0(Inst, Add - Imm); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeVecShiftLImm(MCInst *Inst, unsigned Imm, |
| unsigned Add) |
| { |
| MCOperand_CreateImm0(Inst, (Imm + Add) & (Add - 1)); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeVecShiftR64Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder) |
| { |
| return DecodeVecShiftRImm(Inst, Imm, 64); |
| } |
| |
| static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| return DecodeVecShiftRImm(Inst, Imm | 0x20, 64); |
| } |
| |
| static DecodeStatus DecodeVecShiftR32Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder) |
| { |
| return DecodeVecShiftRImm(Inst, Imm, 32); |
| } |
| |
| static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| return DecodeVecShiftRImm(Inst, Imm | 0x10, 32); |
| } |
| |
| static DecodeStatus DecodeVecShiftR16Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder) |
| { |
| return DecodeVecShiftRImm(Inst, Imm, 16); |
| } |
| |
| static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| return DecodeVecShiftRImm(Inst, Imm | 0x8, 16); |
| } |
| |
| static DecodeStatus DecodeVecShiftR8Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder) |
| { |
| return DecodeVecShiftRImm(Inst, Imm, 8); |
| } |
| |
| static DecodeStatus DecodeVecShiftL64Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder) |
| { |
| return DecodeVecShiftLImm(Inst, Imm, 64); |
| } |
| |
| static DecodeStatus DecodeVecShiftL32Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder) |
| { |
| return DecodeVecShiftLImm(Inst, Imm, 32); |
| } |
| |
| static DecodeStatus DecodeVecShiftL16Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder) |
| { |
| return DecodeVecShiftLImm(Inst, Imm, 16); |
| } |
| |
| static DecodeStatus DecodeVecShiftL8Imm(MCInst *Inst, unsigned Imm, |
| uint64_t Addr, void *Decoder) |
| { |
| return DecodeVecShiftLImm(Inst, Imm, 8); |
| } |
| |
| static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Rd = fieldFromInstruction(insn, 0, 5); |
| unsigned Rn = fieldFromInstruction(insn, 5, 5); |
| unsigned Rm = fieldFromInstruction(insn, 16, 5); |
| unsigned shiftHi = fieldFromInstruction(insn, 22, 2); |
| unsigned shiftLo = fieldFromInstruction(insn, 10, 6); |
| unsigned shift = (shiftHi << 6) | shiftLo; |
| |
| switch (MCInst_getOpcode(Inst)) { |
| default: |
| return Fail; |
| case AArch64_ADDWrs: |
| case AArch64_ADDSWrs: |
| case AArch64_SUBWrs: |
| case AArch64_SUBSWrs: |
| // if shift == '11' then ReservedValue() |
| if (shiftHi == 0x3) |
| return Fail; |
| // Deliberate fallthrough |
| case AArch64_ANDWrs: |
| case AArch64_ANDSWrs: |
| case AArch64_BICWrs: |
| case AArch64_BICSWrs: |
| case AArch64_ORRWrs: |
| case AArch64_ORNWrs: |
| case AArch64_EORWrs: |
| case AArch64_EONWrs: { |
| // if sf == '0' and imm6<5> == '1' then ReservedValue() |
| if (shiftLo >> 5 == 1) |
| return Fail; |
| DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); |
| DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
| break; |
| } |
| case AArch64_ADDXrs: |
| case AArch64_ADDSXrs: |
| case AArch64_SUBXrs: |
| case AArch64_SUBSXrs: |
| // if shift == '11' then ReservedValue() |
| if (shiftHi == 0x3) |
| return Fail; |
| // Deliberate fallthrough |
| case AArch64_ANDXrs: |
| case AArch64_ANDSXrs: |
| case AArch64_BICXrs: |
| case AArch64_BICSXrs: |
| case AArch64_ORRXrs: |
| case AArch64_ORNXrs: |
| case AArch64_EORXrs: |
| case AArch64_EONXrs: |
| DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); |
| DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
| break; |
| } |
| |
| MCOperand_CreateImm0(Inst, shift); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeMoveImmInstruction(MCInst *Inst, uint32_t insn, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Rd = fieldFromInstruction(insn, 0, 5); |
| unsigned imm = fieldFromInstruction(insn, 5, 16); |
| unsigned shift = fieldFromInstruction(insn, 21, 2); |
| |
| shift <<= 4; |
| |
| switch (MCInst_getOpcode(Inst)) { |
| default: |
| return Fail; |
| case AArch64_MOVZWi: |
| case AArch64_MOVNWi: |
| case AArch64_MOVKWi: |
| if (shift & (1U << 5)) |
| return Fail; |
| DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
| break; |
| case AArch64_MOVZXi: |
| case AArch64_MOVNXi: |
| case AArch64_MOVKXi: |
| DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
| break; |
| } |
| |
| if (MCInst_getOpcode(Inst) == AArch64_MOVKWi || |
| MCInst_getOpcode(Inst) == AArch64_MOVKXi) |
| MCInst_addOperand2(Inst, MCInst_getOperand(Inst, 0)); |
| |
| MCOperand_CreateImm0(Inst, imm); |
| MCOperand_CreateImm0(Inst, shift); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeUnsignedLdStInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Rt = fieldFromInstruction(insn, 0, 5); |
| unsigned Rn = fieldFromInstruction(insn, 5, 5); |
| unsigned offset = fieldFromInstruction(insn, 10, 12); |
| |
| switch (MCInst_getOpcode(Inst)) { |
| default: |
| return Fail; |
| case AArch64_PRFMui: |
| // Rt is an immediate in prefetch. |
| MCOperand_CreateImm0(Inst, Rt); |
| break; |
| case AArch64_STRBBui: |
| case AArch64_LDRBBui: |
| case AArch64_LDRSBWui: |
| case AArch64_STRHHui: |
| case AArch64_LDRHHui: |
| case AArch64_LDRSHWui: |
| case AArch64_STRWui: |
| case AArch64_LDRWui: |
| DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDRSBXui: |
| case AArch64_LDRSHXui: |
| case AArch64_LDRSWui: |
| case AArch64_STRXui: |
| case AArch64_LDRXui: |
| DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDRQui: |
| case AArch64_STRQui: |
| DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDRDui: |
| case AArch64_STRDui: |
| DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDRSui: |
| case AArch64_STRSui: |
| DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDRHui: |
| case AArch64_STRHui: |
| DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDRBui: |
| case AArch64_STRBui: |
| DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| } |
| |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| //if (!Dis->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 4)) |
| MCOperand_CreateImm0(Inst, offset); |
| |
| return Success; |
| } |
| |
| static DecodeStatus DecodeSignedLdStInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Addr, |
| void *Decoder) |
| { |
| bool IsLoad; |
| bool IsIndexed; |
| bool IsFP; |
| unsigned Rt = fieldFromInstruction(insn, 0, 5); |
| unsigned Rn = fieldFromInstruction(insn, 5, 5); |
| int32_t offset = fieldFromInstruction(insn, 12, 9); |
| |
| // offset is a 9-bit signed immediate, so sign extend it to |
| // fill the unsigned. |
| if (offset & (1 << (9 - 1))) |
| offset |= ~((1LL << 9) - 1); |
| |
| // First operand is always the writeback to the address register, if needed. |
| switch (MCInst_getOpcode(Inst)) { |
| default: |
| break; |
| case AArch64_LDRSBWpre: |
| case AArch64_LDRSHWpre: |
| case AArch64_STRBBpre: |
| case AArch64_LDRBBpre: |
| case AArch64_STRHHpre: |
| case AArch64_LDRHHpre: |
| case AArch64_STRWpre: |
| case AArch64_LDRWpre: |
| case AArch64_LDRSBWpost: |
| case AArch64_LDRSHWpost: |
| case AArch64_STRBBpost: |
| case AArch64_LDRBBpost: |
| case AArch64_STRHHpost: |
| case AArch64_LDRHHpost: |
| case AArch64_STRWpost: |
| case AArch64_LDRWpost: |
| case AArch64_LDRSBXpre: |
| case AArch64_LDRSHXpre: |
| case AArch64_STRXpre: |
| case AArch64_LDRSWpre: |
| case AArch64_LDRXpre: |
| case AArch64_LDRSBXpost: |
| case AArch64_LDRSHXpost: |
| case AArch64_STRXpost: |
| case AArch64_LDRSWpost: |
| case AArch64_LDRXpost: |
| case AArch64_LDRQpre: |
| case AArch64_STRQpre: |
| case AArch64_LDRQpost: |
| case AArch64_STRQpost: |
| case AArch64_LDRDpre: |
| case AArch64_STRDpre: |
| case AArch64_LDRDpost: |
| case AArch64_STRDpost: |
| case AArch64_LDRSpre: |
| case AArch64_STRSpre: |
| case AArch64_LDRSpost: |
| case AArch64_STRSpost: |
| case AArch64_LDRHpre: |
| case AArch64_STRHpre: |
| case AArch64_LDRHpost: |
| case AArch64_STRHpost: |
| case AArch64_LDRBpre: |
| case AArch64_STRBpre: |
| case AArch64_LDRBpost: |
| case AArch64_STRBpost: |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| break; |
| } |
| |
| switch (MCInst_getOpcode(Inst)) { |
| default: |
| return Fail; |
| case AArch64_PRFUMi: |
| // Rt is an immediate in prefetch. |
| MCOperand_CreateImm0(Inst, Rt); |
| break; |
| case AArch64_STURBBi: |
| case AArch64_LDURBBi: |
| case AArch64_LDURSBWi: |
| case AArch64_STURHHi: |
| case AArch64_LDURHHi: |
| case AArch64_LDURSHWi: |
| case AArch64_STURWi: |
| case AArch64_LDURWi: |
| case AArch64_LDTRSBWi: |
| case AArch64_LDTRSHWi: |
| case AArch64_STTRWi: |
| case AArch64_LDTRWi: |
| case AArch64_STTRHi: |
| case AArch64_LDTRHi: |
| case AArch64_LDTRBi: |
| case AArch64_STTRBi: |
| case AArch64_LDRSBWpre: |
| case AArch64_LDRSHWpre: |
| case AArch64_STRBBpre: |
| case AArch64_LDRBBpre: |
| case AArch64_STRHHpre: |
| case AArch64_LDRHHpre: |
| case AArch64_STRWpre: |
| case AArch64_LDRWpre: |
| case AArch64_LDRSBWpost: |
| case AArch64_LDRSHWpost: |
| case AArch64_STRBBpost: |
| case AArch64_LDRBBpost: |
| case AArch64_STRHHpost: |
| case AArch64_LDRHHpost: |
| case AArch64_STRWpost: |
| case AArch64_LDRWpost: |
| DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDURSBXi: |
| case AArch64_LDURSHXi: |
| case AArch64_LDURSWi: |
| case AArch64_STURXi: |
| case AArch64_LDURXi: |
| case AArch64_LDTRSBXi: |
| case AArch64_LDTRSHXi: |
| case AArch64_LDTRSWi: |
| case AArch64_STTRXi: |
| case AArch64_LDTRXi: |
| case AArch64_LDRSBXpre: |
| case AArch64_LDRSHXpre: |
| case AArch64_STRXpre: |
| case AArch64_LDRSWpre: |
| case AArch64_LDRXpre: |
| case AArch64_LDRSBXpost: |
| case AArch64_LDRSHXpost: |
| case AArch64_STRXpost: |
| case AArch64_LDRSWpost: |
| case AArch64_LDRXpost: |
| DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDURQi: |
| case AArch64_STURQi: |
| case AArch64_LDRQpre: |
| case AArch64_STRQpre: |
| case AArch64_LDRQpost: |
| case AArch64_STRQpost: |
| DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDURDi: |
| case AArch64_STURDi: |
| case AArch64_LDRDpre: |
| case AArch64_STRDpre: |
| case AArch64_LDRDpost: |
| case AArch64_STRDpost: |
| DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDURSi: |
| case AArch64_STURSi: |
| case AArch64_LDRSpre: |
| case AArch64_STRSpre: |
| case AArch64_LDRSpost: |
| case AArch64_STRSpost: |
| DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDURHi: |
| case AArch64_STURHi: |
| case AArch64_LDRHpre: |
| case AArch64_STRHpre: |
| case AArch64_LDRHpost: |
| case AArch64_STRHpost: |
| DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_LDURBi: |
| case AArch64_STURBi: |
| case AArch64_LDRBpre: |
| case AArch64_STRBpre: |
| case AArch64_LDRBpost: |
| case AArch64_STRBpost: |
| DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| } |
| |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| MCOperand_CreateImm0(Inst, offset); |
| |
| IsLoad = fieldFromInstruction(insn, 22, 1) != 0; |
| IsIndexed = fieldFromInstruction(insn, 10, 2) != 0; |
| IsFP = fieldFromInstruction(insn, 26, 1) != 0; |
| |
| // Cannot write back to a transfer register (but xzr != sp). |
| if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn) |
| return SoftFail; |
| |
| return Success; |
| } |
| |
| static DecodeStatus DecodeExclusiveLdStInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Rt = fieldFromInstruction(insn, 0, 5); |
| unsigned Rn = fieldFromInstruction(insn, 5, 5); |
| unsigned Rt2 = fieldFromInstruction(insn, 10, 5); |
| unsigned Rs = fieldFromInstruction(insn, 16, 5); |
| unsigned Opcode = MCInst_getOpcode(Inst); |
| |
| switch (Opcode) { |
| default: |
| return Fail; |
| case AArch64_STLXRW: |
| case AArch64_STLXRB: |
| case AArch64_STLXRH: |
| case AArch64_STXRW: |
| case AArch64_STXRB: |
| case AArch64_STXRH: |
| DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
| // FALLTHROUGH |
| case AArch64_LDARW: |
| case AArch64_LDARB: |
| case AArch64_LDARH: |
| case AArch64_LDAXRW: |
| case AArch64_LDAXRB: |
| case AArch64_LDAXRH: |
| case AArch64_LDXRW: |
| case AArch64_LDXRB: |
| case AArch64_LDXRH: |
| case AArch64_STLRW: |
| case AArch64_STLRB: |
| case AArch64_STLRH: |
| DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_STLXRX: |
| case AArch64_STXRX: |
| DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
| // FALLTHROUGH |
| case AArch64_LDARX: |
| case AArch64_LDAXRX: |
| case AArch64_LDXRX: |
| case AArch64_STLRX: |
| DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
| break; |
| case AArch64_STLXPW: |
| case AArch64_STXPW: |
| DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
| // FALLTHROUGH |
| case AArch64_LDAXPW: |
| case AArch64_LDXPW: |
| DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
| DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
| break; |
| case AArch64_STLXPX: |
| case AArch64_STXPX: |
| DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
| // FALLTHROUGH |
| case AArch64_LDAXPX: |
| case AArch64_LDXPX: |
| DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
| DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
| break; |
| } |
| |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| |
| // You shouldn't load to the same register twice in an instruction... |
| if ((Opcode == AArch64_LDAXPW || Opcode == AArch64_LDXPW || |
| Opcode == AArch64_LDAXPX || Opcode == AArch64_LDXPX) && |
| Rt == Rt2) |
| return SoftFail; |
| |
| return Success; |
| } |
| |
| static DecodeStatus DecodePairLdStInstruction(MCInst *Inst, uint32_t insn, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Rt = fieldFromInstruction(insn, 0, 5); |
| unsigned Rn = fieldFromInstruction(insn, 5, 5); |
| unsigned Rt2 = fieldFromInstruction(insn, 10, 5); |
| int32_t offset = fieldFromInstruction(insn, 15, 7); |
| bool IsLoad = fieldFromInstruction(insn, 22, 1) != 0; |
| unsigned Opcode = MCInst_getOpcode(Inst); |
| bool NeedsDisjointWritebackTransfer = false; |
| |
| // offset is a 7-bit signed immediate, so sign extend it to |
| // fill the unsigned. |
| if (offset & (1 << (7 - 1))) |
| offset |= ~((1LL << 7) - 1); |
| |
| // First operand is always writeback of base register. |
| switch (Opcode) { |
| default: |
| break; |
| case AArch64_LDPXpost: |
| case AArch64_STPXpost: |
| case AArch64_LDPSWpost: |
| case AArch64_LDPXpre: |
| case AArch64_STPXpre: |
| case AArch64_LDPSWpre: |
| case AArch64_LDPWpost: |
| case AArch64_STPWpost: |
| case AArch64_LDPWpre: |
| case AArch64_STPWpre: |
| case AArch64_LDPQpost: |
| case AArch64_STPQpost: |
| case AArch64_LDPQpre: |
| case AArch64_STPQpre: |
| case AArch64_LDPDpost: |
| case AArch64_STPDpost: |
| case AArch64_LDPDpre: |
| case AArch64_STPDpre: |
| case AArch64_LDPSpost: |
| case AArch64_STPSpost: |
| case AArch64_LDPSpre: |
| case AArch64_STPSpre: |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| break; |
| } |
| |
| switch (Opcode) { |
| default: |
| return Fail; |
| case AArch64_LDPXpost: |
| case AArch64_STPXpost: |
| case AArch64_LDPSWpost: |
| case AArch64_LDPXpre: |
| case AArch64_STPXpre: |
| case AArch64_LDPSWpre: |
| NeedsDisjointWritebackTransfer = true; |
| // Fallthrough |
| case AArch64_LDNPXi: |
| case AArch64_STNPXi: |
| case AArch64_LDPXi: |
| case AArch64_STPXi: |
| case AArch64_LDPSWi: |
| DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
| DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
| break; |
| case AArch64_LDPWpost: |
| case AArch64_STPWpost: |
| case AArch64_LDPWpre: |
| case AArch64_STPWpre: |
| NeedsDisjointWritebackTransfer = true; |
| // Fallthrough |
| case AArch64_LDNPWi: |
| case AArch64_STNPWi: |
| case AArch64_LDPWi: |
| case AArch64_STPWi: |
| DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
| DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
| break; |
| case AArch64_LDNPQi: |
| case AArch64_STNPQi: |
| case AArch64_LDPQpost: |
| case AArch64_STPQpost: |
| case AArch64_LDPQi: |
| case AArch64_STPQi: |
| case AArch64_LDPQpre: |
| case AArch64_STPQpre: |
| DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
| DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder); |
| break; |
| case AArch64_LDNPDi: |
| case AArch64_STNPDi: |
| case AArch64_LDPDpost: |
| case AArch64_STPDpost: |
| case AArch64_LDPDi: |
| case AArch64_STPDi: |
| case AArch64_LDPDpre: |
| case AArch64_STPDpre: |
| DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
| DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
| break; |
| case AArch64_LDNPSi: |
| case AArch64_STNPSi: |
| case AArch64_LDPSpost: |
| case AArch64_STPSpost: |
| case AArch64_LDPSi: |
| case AArch64_STPSi: |
| case AArch64_LDPSpre: |
| case AArch64_STPSpre: |
| DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
| DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
| break; |
| } |
| |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| MCOperand_CreateImm0(Inst, offset); |
| |
| // You shouldn't load to the same register twice in an instruction... |
| if (IsLoad && Rt == Rt2) |
| return SoftFail; |
| |
| // ... or do any operation that writes-back to a transfer register. But note |
| // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different. |
| if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn)) |
| return SoftFail; |
| |
| return Success; |
| } |
| |
| static DecodeStatus DecodeAddSubERegInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Rd, Rn, Rm; |
| unsigned extend = fieldFromInstruction(insn, 10, 6); |
| unsigned shift = extend & 0x7; |
| |
| if (shift > 4) |
| return Fail; |
| |
| Rd = fieldFromInstruction(insn, 0, 5); |
| Rn = fieldFromInstruction(insn, 5, 5); |
| Rm = fieldFromInstruction(insn, 16, 5); |
| |
| switch (MCInst_getOpcode(Inst)) { |
| default: |
| return Fail; |
| case AArch64_ADDWrx: |
| case AArch64_SUBWrx: |
| DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
| DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
| break; |
| case AArch64_ADDSWrx: |
| case AArch64_SUBSWrx: |
| DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
| DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
| break; |
| case AArch64_ADDXrx: |
| case AArch64_SUBXrx: |
| DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
| break; |
| case AArch64_ADDSXrx: |
| case AArch64_SUBSXrx: |
| DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
| break; |
| case AArch64_ADDXrx64: |
| case AArch64_SUBXrx64: |
| DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
| break; |
| case AArch64_SUBSXrx64: |
| case AArch64_ADDSXrx64: |
| DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
| break; |
| } |
| |
| MCOperand_CreateImm0(Inst, extend); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeLogicalImmInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Rd = fieldFromInstruction(insn, 0, 5); |
| unsigned Rn = fieldFromInstruction(insn, 5, 5); |
| unsigned Datasize = fieldFromInstruction(insn, 31, 1); |
| unsigned imm; |
| |
| if (Datasize) { |
| if (MCInst_getOpcode(Inst) == AArch64_ANDSXri) |
| DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
| else |
| DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); |
| imm = fieldFromInstruction(insn, 10, 13); |
| if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 64)) |
| return Fail; |
| } else { |
| if (MCInst_getOpcode(Inst) == AArch64_ANDSWri) |
| DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
| else |
| DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); |
| imm = fieldFromInstruction(insn, 10, 12); |
| if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 32)) |
| return Fail; |
| } |
| |
| MCOperand_CreateImm0(Inst, imm); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeModImmInstruction(MCInst *Inst, uint32_t insn, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Rd = fieldFromInstruction(insn, 0, 5); |
| unsigned cmode = fieldFromInstruction(insn, 12, 4); |
| unsigned imm = fieldFromInstruction(insn, 16, 3) << 5; |
| imm |= fieldFromInstruction(insn, 5, 5); |
| |
| if (MCInst_getOpcode(Inst) == AArch64_MOVID) |
| DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder); |
| else |
| DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
| |
| MCOperand_CreateImm0(Inst, imm); |
| |
| switch (MCInst_getOpcode(Inst)) { |
| default: |
| break; |
| case AArch64_MOVIv4i16: |
| case AArch64_MOVIv8i16: |
| case AArch64_MVNIv4i16: |
| case AArch64_MVNIv8i16: |
| case AArch64_MOVIv2i32: |
| case AArch64_MOVIv4i32: |
| case AArch64_MVNIv2i32: |
| case AArch64_MVNIv4i32: |
| MCOperand_CreateImm0(Inst, (cmode & 6) << 2); |
| break; |
| case AArch64_MOVIv2s_msl: |
| case AArch64_MOVIv4s_msl: |
| case AArch64_MVNIv2s_msl: |
| case AArch64_MVNIv4s_msl: |
| MCOperand_CreateImm0(Inst, cmode & 1 ? 0x110 : 0x108); |
| break; |
| } |
| |
| return Success; |
| } |
| |
| static DecodeStatus DecodeModImmTiedInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Addr, |
| void *Decoder) |
| { |
| unsigned Rd = fieldFromInstruction(insn, 0, 5); |
| unsigned cmode = fieldFromInstruction(insn, 12, 4); |
| unsigned imm = fieldFromInstruction(insn, 16, 3) << 5; |
| imm |= fieldFromInstruction(insn, 5, 5); |
| |
| // Tied operands added twice. |
| DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
| |
| MCOperand_CreateImm0(Inst, imm); |
| MCOperand_CreateImm0(Inst, (cmode & 6) << 2); |
| |
| return Success; |
| } |
| |
| static DecodeStatus DecodeAdrInstruction(MCInst *Inst, uint32_t insn, |
| uint64_t Addr, void *Decoder) |
| { |
| unsigned Rd = fieldFromInstruction(insn, 0, 5); |
| int32_t imm = fieldFromInstruction(insn, 5, 19) << 2; |
| |
| imm |= fieldFromInstruction(insn, 29, 2); |
| |
| // Sign-extend the 21-bit immediate. |
| if (imm & (1 << (21 - 1))) |
| imm |= ~((1LL << 21) - 1); |
| |
| DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
| //if (!Dis->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 4)) |
| MCOperand_CreateImm0(Inst, imm); |
| |
| return Success; |
| } |
| |
| static DecodeStatus DecodeBaseAddSubImm(MCInst *Inst, uint32_t insn, |
| uint64_t Addr, void *Decoder) |
| { |
| unsigned Rd = fieldFromInstruction(insn, 0, 5); |
| unsigned Rn = fieldFromInstruction(insn, 5, 5); |
| unsigned Imm = fieldFromInstruction(insn, 10, 14); |
| unsigned S = fieldFromInstruction(insn, 29, 1); |
| unsigned Datasize = fieldFromInstruction(insn, 31, 1); |
| |
| unsigned ShifterVal = (Imm >> 12) & 3; |
| unsigned ImmVal = Imm & 0xFFF; |
| |
| if (ShifterVal != 0 && ShifterVal != 1) |
| return Fail; |
| |
| if (Datasize) { |
| if (Rd == 31 && !S) |
| DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
| else |
| DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
| } else { |
| if (Rd == 31 && !S) |
| DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
| else |
| DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
| DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
| } |
| |
| //if (!Dis->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 4)) |
| MCOperand_CreateImm0(Inst, ImmVal); |
| MCOperand_CreateImm0(Inst, 12 * ShifterVal); |
| return Success; |
| } |
| |
| static DecodeStatus DecodeUnconditionalBranch(MCInst *Inst, uint32_t insn, |
| uint64_t Addr, |
| void *Decoder) |
| { |
| int32_t imm = fieldFromInstruction(insn, 0, 26); |
| |
| // Sign-extend the 26-bit immediate. |
| if (imm & (1 << (26 - 1))) |
| imm |= ~((1LL << 26) - 1); |
| |
| // if (!Dis->tryAddingSymbolicOperand(Inst, imm << 2, Addr, true, 0, 4)) |
| MCOperand_CreateImm0(Inst, imm); |
| |
| return Success; |
| } |
| |
| static DecodeStatus DecodeSystemPStateInstruction(MCInst *Inst, |
| uint32_t insn, uint64_t Addr, |
| void *Decoder) |
| { |
| uint32_t op1 = fieldFromInstruction(insn, 16, 3); |
| uint32_t op2 = fieldFromInstruction(insn, 5, 3); |
| uint32_t crm = fieldFromInstruction(insn, 8, 4); |
| bool ValidNamed; |
| uint32_t pstate_field = (op1 << 3) | op2; |
| |
| MCOperand_CreateImm0(Inst, pstate_field); |
| MCOperand_CreateImm0(Inst, crm); |
| |
| A64NamedImmMapper_toString(&A64PState_PStateMapper, pstate_field, &ValidNamed); |
| |
| return ValidNamed ? Success : Fail; |
| } |
| |
| static DecodeStatus DecodeTestAndBranch(MCInst *Inst, uint32_t insn, |
| uint64_t Addr, void *Decoder) |
| { |
| uint32_t Rt = fieldFromInstruction(insn, 0, 5); |
| uint32_t bit = fieldFromInstruction(insn, 31, 1) << 5; |
| int32_t dst = fieldFromInstruction(insn, 5, 14); |
| |
| bit |= fieldFromInstruction(insn, 19, 5); |
| |
| // Sign-extend 14-bit immediate. |
| if (dst & (1 << (14 - 1))) |
| dst |= ~((1LL << 14) - 1); |
| |
| if (fieldFromInstruction(insn, 31, 1) == 0) |
| DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
| else |
| DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
| |
| MCOperand_CreateImm0(Inst, bit); |
| //if (!Dis->tryAddingSymbolicOperand(Inst, dst << 2, Addr, true, 0, 4)) |
| MCOperand_CreateImm0(Inst, dst); |
| |
| return Success; |
| } |
| |
| void AArch64_init(MCRegisterInfo *MRI) |
| { |
| /* |
| InitMCRegisterInfo(AArch64RegDesc, 420, |
| RA, PC, |
| AArch64MCRegisterClasses, 43, |
| AArch64RegUnitRoots, 66, AArch64RegDiffLists, |
| AArch64RegStrings, |
| AArch64SubRegIdxLists, 53, |
| AArch64SubRegIdxRanges, |
| AArch64RegEncodingTable); |
| */ |
| |
| MCRegisterInfo_InitMCRegisterInfo(MRI, AArch64RegDesc, 420, |
| 0, 0, |
| AArch64MCRegisterClasses, 43, |
| 0, 0, AArch64RegDiffLists, |
| 0, |
| AArch64SubRegIdxLists, 53, |
| 0); |
| } |
| |
| #endif |