llvm/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp
Lang Hames 508bd63046 [MC] Require an MCContext when constructing an MCDisassembler.
This patch re-introduces the MCContext member that was removed from
MCDisassembler in r206063, and requires that an MCContext be passed in at
MCDisassembler construction time. (Previously the MCContext member had been
initialized in an ad-hoc fashion after construction). The MCCContext member
can be used by MCDisassembler sub-classes to construct constant or
target-specific MCExprs.

This patch updates disassemblers for in-tree targets, and provides the
MCRegisterInfo instance that some disassemblers were using through the
MCContext (previously those backends were constructing their own
MCRegisterInfo instances).



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206241 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-15 04:40:56 +00:00

2014 lines
70 KiB
C++

//===- ARM64Disassembler.cpp - Disassembler for ARM64 -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "arm64-disassembler"
#include "ARM64Disassembler.h"
#include "ARM64ExternalSymbolizer.h"
#include "ARM64Subtarget.h"
#include "MCTargetDesc/ARM64AddressingModes.h"
#include "Utils/ARM64BaseInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
// Pull DecodeStatus and its enum values into the global namespace.
typedef llvm::MCDisassembler::DecodeStatus DecodeStatus;
// Forward declare these because the autogenerated code will reference them.
// Definitions are further down.
static DecodeStatus DecodeFPR128RegisterClass(llvm::MCInst &Inst,
unsigned RegNo, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeFPR128_loRegisterClass(llvm::MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeGPR64spRegisterClass(llvm::MCInst &Inst,
unsigned RegNo, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeGPR32spRegisterClass(llvm::MCInst &Inst,
unsigned RegNo, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeQQRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeQQQRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeQQQQRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeDDRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeDDDRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeDDDDRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeFixedPointScaleImm32(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeFixedPointScaleImm64(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeCondBranchTarget(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeThreeAddrSRegInstruction(llvm::MCInst &Inst,
uint32_t insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeMoveImmInstruction(llvm::MCInst &Inst, uint32_t insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeUnsignedLdStInstruction(llvm::MCInst &Inst,
uint32_t insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeSignedLdStInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeExclusiveLdStInstruction(llvm::MCInst &Inst,
uint32_t insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodePairLdStInstruction(llvm::MCInst &Inst, uint32_t insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeRegOffsetLdStInstruction(llvm::MCInst &Inst,
uint32_t insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeAddSubERegInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeLogicalImmInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeModImmInstruction(llvm::MCInst &Inst, uint32_t insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeModImmTiedInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeAdrInstruction(llvm::MCInst &Inst, uint32_t insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeBaseAddSubImm(llvm::MCInst &Inst, uint32_t insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeUnconditionalBranch(llvm::MCInst &Inst, uint32_t insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeSystemCPSRInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeTestAndBranch(llvm::MCInst &Inst, uint32_t insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSIMDLdStPost(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeSIMDLdStSingle(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeSIMDLdStSingleTied(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr,
const void *Decoder);
static DecodeStatus DecodeVecShiftR64Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeVecShiftR64ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr,
const void *Decoder);
static DecodeStatus DecodeVecShiftR32Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeVecShiftR32ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr,
const void *Decoder);
static DecodeStatus DecodeVecShiftR16Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeVecShiftR16ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr,
const void *Decoder);
static DecodeStatus DecodeVecShiftR8Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeVecShiftL64Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeVecShiftL32Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeVecShiftL16Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeVecShiftL8Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
#include "ARM64GenDisassemblerTables.inc"
#include "ARM64GenInstrInfo.inc"
using namespace llvm;
#define Success llvm::MCDisassembler::Success
#define Fail llvm::MCDisassembler::Fail
static MCDisassembler *createARM64Disassembler(const Target &T,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
return new ARM64Disassembler(STI, Ctx);
}
DecodeStatus ARM64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
const MemoryObject &Region,
uint64_t Address,
raw_ostream &os,
raw_ostream &cs) const {
CommentStream = &cs;
uint8_t bytes[4];
Size = 0;
// We want to read exactly 4 bytes of data.
if (Region.readBytes(Address, 4, (uint8_t *)bytes) == -1)
return Fail;
Size = 4;
// Encoded as a small-endian 32-bit word in the stream.
uint32_t insn =
(bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | (bytes[0] << 0);
// Calling the auto-generated decoder function.
DecodeStatus result =
decodeInstruction(DecoderTable32, MI, insn, Address, this, STI);
if (!result)
return Fail;
return Success;
}
static MCSymbolizer *
createARM64ExternalSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp,
void *DisInfo, MCContext *Ctx,
MCRelocationInfo *RelInfo) {
return new llvm::ARM64ExternalSymbolizer(
*Ctx,
std::unique_ptr<MCRelocationInfo>(RelInfo),
GetOpInfo, SymbolLookUp, DisInfo);
}
extern "C" void LLVMInitializeARM64Disassembler() {
TargetRegistry::RegisterMCDisassembler(TheARM64Target,
createARM64Disassembler);
TargetRegistry::RegisterMCSymbolizer(TheARM64Target,
createARM64ExternalSymbolizer);
}
static const unsigned FPR128DecoderTable[] = {
ARM64::Q0, ARM64::Q1, ARM64::Q2, ARM64::Q3, ARM64::Q4, ARM64::Q5,
ARM64::Q6, ARM64::Q7, ARM64::Q8, ARM64::Q9, ARM64::Q10, ARM64::Q11,
ARM64::Q12, ARM64::Q13, ARM64::Q14, ARM64::Q15, ARM64::Q16, ARM64::Q17,
ARM64::Q18, ARM64::Q19, ARM64::Q20, ARM64::Q21, ARM64::Q22, ARM64::Q23,
ARM64::Q24, ARM64::Q25, ARM64::Q26, ARM64::Q27, ARM64::Q28, ARM64::Q29,
ARM64::Q30, ARM64::Q31
};
static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = FPR128DecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static DecodeStatus DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 15)
return Fail;
return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
}
static const unsigned FPR64DecoderTable[] = {
ARM64::D0, ARM64::D1, ARM64::D2, ARM64::D3, ARM64::D4, ARM64::D5,
ARM64::D6, ARM64::D7, ARM64::D8, ARM64::D9, ARM64::D10, ARM64::D11,
ARM64::D12, ARM64::D13, ARM64::D14, ARM64::D15, ARM64::D16, ARM64::D17,
ARM64::D18, ARM64::D19, ARM64::D20, ARM64::D21, ARM64::D22, ARM64::D23,
ARM64::D24, ARM64::D25, ARM64::D26, ARM64::D27, ARM64::D28, ARM64::D29,
ARM64::D30, ARM64::D31
};
static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = FPR64DecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned FPR32DecoderTable[] = {
ARM64::S0, ARM64::S1, ARM64::S2, ARM64::S3, ARM64::S4, ARM64::S5,
ARM64::S6, ARM64::S7, ARM64::S8, ARM64::S9, ARM64::S10, ARM64::S11,
ARM64::S12, ARM64::S13, ARM64::S14, ARM64::S15, ARM64::S16, ARM64::S17,
ARM64::S18, ARM64::S19, ARM64::S20, ARM64::S21, ARM64::S22, ARM64::S23,
ARM64::S24, ARM64::S25, ARM64::S26, ARM64::S27, ARM64::S28, ARM64::S29,
ARM64::S30, ARM64::S31
};
static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = FPR32DecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned FPR16DecoderTable[] = {
ARM64::H0, ARM64::H1, ARM64::H2, ARM64::H3, ARM64::H4, ARM64::H5,
ARM64::H6, ARM64::H7, ARM64::H8, ARM64::H9, ARM64::H10, ARM64::H11,
ARM64::H12, ARM64::H13, ARM64::H14, ARM64::H15, ARM64::H16, ARM64::H17,
ARM64::H18, ARM64::H19, ARM64::H20, ARM64::H21, ARM64::H22, ARM64::H23,
ARM64::H24, ARM64::H25, ARM64::H26, ARM64::H27, ARM64::H28, ARM64::H29,
ARM64::H30, ARM64::H31
};
static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = FPR16DecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned FPR8DecoderTable[] = {
ARM64::B0, ARM64::B1, ARM64::B2, ARM64::B3, ARM64::B4, ARM64::B5,
ARM64::B6, ARM64::B7, ARM64::B8, ARM64::B9, ARM64::B10, ARM64::B11,
ARM64::B12, ARM64::B13, ARM64::B14, ARM64::B15, ARM64::B16, ARM64::B17,
ARM64::B18, ARM64::B19, ARM64::B20, ARM64::B21, ARM64::B22, ARM64::B23,
ARM64::B24, ARM64::B25, ARM64::B26, ARM64::B27, ARM64::B28, ARM64::B29,
ARM64::B30, ARM64::B31
};
static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = FPR8DecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned GPR64DecoderTable[] = {
ARM64::X0, ARM64::X1, ARM64::X2, ARM64::X3, ARM64::X4, ARM64::X5,
ARM64::X6, ARM64::X7, ARM64::X8, ARM64::X9, ARM64::X10, ARM64::X11,
ARM64::X12, ARM64::X13, ARM64::X14, ARM64::X15, ARM64::X16, ARM64::X17,
ARM64::X18, ARM64::X19, ARM64::X20, ARM64::X21, ARM64::X22, ARM64::X23,
ARM64::X24, ARM64::X25, ARM64::X26, ARM64::X27, ARM64::X28, ARM64::FP,
ARM64::LR, ARM64::XZR
};
static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = GPR64DecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = GPR64DecoderTable[RegNo];
if (Register == ARM64::XZR)
Register = ARM64::SP;
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned GPR32DecoderTable[] = {
ARM64::W0, ARM64::W1, ARM64::W2, ARM64::W3, ARM64::W4, ARM64::W5,
ARM64::W6, ARM64::W7, ARM64::W8, ARM64::W9, ARM64::W10, ARM64::W11,
ARM64::W12, ARM64::W13, ARM64::W14, ARM64::W15, ARM64::W16, ARM64::W17,
ARM64::W18, ARM64::W19, ARM64::W20, ARM64::W21, ARM64::W22, ARM64::W23,
ARM64::W24, ARM64::W25, ARM64::W26, ARM64::W27, ARM64::W28, ARM64::W29,
ARM64::W30, ARM64::WZR
};
static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = GPR32DecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = GPR32DecoderTable[RegNo];
if (Register == ARM64::WZR)
Register = ARM64::WSP;
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned VectorDecoderTable[] = {
ARM64::Q0, ARM64::Q1, ARM64::Q2, ARM64::Q3, ARM64::Q4, ARM64::Q5,
ARM64::Q6, ARM64::Q7, ARM64::Q8, ARM64::Q9, ARM64::Q10, ARM64::Q11,
ARM64::Q12, ARM64::Q13, ARM64::Q14, ARM64::Q15, ARM64::Q16, ARM64::Q17,
ARM64::Q18, ARM64::Q19, ARM64::Q20, ARM64::Q21, ARM64::Q22, ARM64::Q23,
ARM64::Q24, ARM64::Q25, ARM64::Q26, ARM64::Q27, ARM64::Q28, ARM64::Q29,
ARM64::Q30, ARM64::Q31
};
static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = VectorDecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned QQDecoderTable[] = {
ARM64::Q0_Q1, ARM64::Q1_Q2, ARM64::Q2_Q3, ARM64::Q3_Q4,
ARM64::Q4_Q5, ARM64::Q5_Q6, ARM64::Q6_Q7, ARM64::Q7_Q8,
ARM64::Q8_Q9, ARM64::Q9_Q10, ARM64::Q10_Q11, ARM64::Q11_Q12,
ARM64::Q12_Q13, ARM64::Q13_Q14, ARM64::Q14_Q15, ARM64::Q15_Q16,
ARM64::Q16_Q17, ARM64::Q17_Q18, ARM64::Q18_Q19, ARM64::Q19_Q20,
ARM64::Q20_Q21, ARM64::Q21_Q22, ARM64::Q22_Q23, ARM64::Q23_Q24,
ARM64::Q24_Q25, ARM64::Q25_Q26, ARM64::Q26_Q27, ARM64::Q27_Q28,
ARM64::Q28_Q29, ARM64::Q29_Q30, ARM64::Q30_Q31, ARM64::Q31_Q0
};
static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr, const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = QQDecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned QQQDecoderTable[] = {
ARM64::Q0_Q1_Q2, ARM64::Q1_Q2_Q3, ARM64::Q2_Q3_Q4,
ARM64::Q3_Q4_Q5, ARM64::Q4_Q5_Q6, ARM64::Q5_Q6_Q7,
ARM64::Q6_Q7_Q8, ARM64::Q7_Q8_Q9, ARM64::Q8_Q9_Q10,
ARM64::Q9_Q10_Q11, ARM64::Q10_Q11_Q12, ARM64::Q11_Q12_Q13,
ARM64::Q12_Q13_Q14, ARM64::Q13_Q14_Q15, ARM64::Q14_Q15_Q16,
ARM64::Q15_Q16_Q17, ARM64::Q16_Q17_Q18, ARM64::Q17_Q18_Q19,
ARM64::Q18_Q19_Q20, ARM64::Q19_Q20_Q21, ARM64::Q20_Q21_Q22,
ARM64::Q21_Q22_Q23, ARM64::Q22_Q23_Q24, ARM64::Q23_Q24_Q25,
ARM64::Q24_Q25_Q26, ARM64::Q25_Q26_Q27, ARM64::Q26_Q27_Q28,
ARM64::Q27_Q28_Q29, ARM64::Q28_Q29_Q30, ARM64::Q29_Q30_Q31,
ARM64::Q30_Q31_Q0, ARM64::Q31_Q0_Q1
};
static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr, const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = QQQDecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned QQQQDecoderTable[] = {
ARM64::Q0_Q1_Q2_Q3, ARM64::Q1_Q2_Q3_Q4, ARM64::Q2_Q3_Q4_Q5,
ARM64::Q3_Q4_Q5_Q6, ARM64::Q4_Q5_Q6_Q7, ARM64::Q5_Q6_Q7_Q8,
ARM64::Q6_Q7_Q8_Q9, ARM64::Q7_Q8_Q9_Q10, ARM64::Q8_Q9_Q10_Q11,
ARM64::Q9_Q10_Q11_Q12, ARM64::Q10_Q11_Q12_Q13, ARM64::Q11_Q12_Q13_Q14,
ARM64::Q12_Q13_Q14_Q15, ARM64::Q13_Q14_Q15_Q16, ARM64::Q14_Q15_Q16_Q17,
ARM64::Q15_Q16_Q17_Q18, ARM64::Q16_Q17_Q18_Q19, ARM64::Q17_Q18_Q19_Q20,
ARM64::Q18_Q19_Q20_Q21, ARM64::Q19_Q20_Q21_Q22, ARM64::Q20_Q21_Q22_Q23,
ARM64::Q21_Q22_Q23_Q24, ARM64::Q22_Q23_Q24_Q25, ARM64::Q23_Q24_Q25_Q26,
ARM64::Q24_Q25_Q26_Q27, ARM64::Q25_Q26_Q27_Q28, ARM64::Q26_Q27_Q28_Q29,
ARM64::Q27_Q28_Q29_Q30, ARM64::Q28_Q29_Q30_Q31, ARM64::Q29_Q30_Q31_Q0,
ARM64::Q30_Q31_Q0_Q1, ARM64::Q31_Q0_Q1_Q2
};
static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = QQQQDecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned DDDecoderTable[] = {
ARM64::D0_D1, ARM64::D1_D2, ARM64::D2_D3, ARM64::D3_D4,
ARM64::D4_D5, ARM64::D5_D6, ARM64::D6_D7, ARM64::D7_D8,
ARM64::D8_D9, ARM64::D9_D10, ARM64::D10_D11, ARM64::D11_D12,
ARM64::D12_D13, ARM64::D13_D14, ARM64::D14_D15, ARM64::D15_D16,
ARM64::D16_D17, ARM64::D17_D18, ARM64::D18_D19, ARM64::D19_D20,
ARM64::D20_D21, ARM64::D21_D22, ARM64::D22_D23, ARM64::D23_D24,
ARM64::D24_D25, ARM64::D25_D26, ARM64::D26_D27, ARM64::D27_D28,
ARM64::D28_D29, ARM64::D29_D30, ARM64::D30_D31, ARM64::D31_D0
};
static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr, const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = DDDecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned DDDDecoderTable[] = {
ARM64::D0_D1_D2, ARM64::D1_D2_D3, ARM64::D2_D3_D4,
ARM64::D3_D4_D5, ARM64::D4_D5_D6, ARM64::D5_D6_D7,
ARM64::D6_D7_D8, ARM64::D7_D8_D9, ARM64::D8_D9_D10,
ARM64::D9_D10_D11, ARM64::D10_D11_D12, ARM64::D11_D12_D13,
ARM64::D12_D13_D14, ARM64::D13_D14_D15, ARM64::D14_D15_D16,
ARM64::D15_D16_D17, ARM64::D16_D17_D18, ARM64::D17_D18_D19,
ARM64::D18_D19_D20, ARM64::D19_D20_D21, ARM64::D20_D21_D22,
ARM64::D21_D22_D23, ARM64::D22_D23_D24, ARM64::D23_D24_D25,
ARM64::D24_D25_D26, ARM64::D25_D26_D27, ARM64::D26_D27_D28,
ARM64::D27_D28_D29, ARM64::D28_D29_D30, ARM64::D29_D30_D31,
ARM64::D30_D31_D0, ARM64::D31_D0_D1
};
static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr, const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = DDDDecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned DDDDDecoderTable[] = {
ARM64::D0_D1_D2_D3, ARM64::D1_D2_D3_D4, ARM64::D2_D3_D4_D5,
ARM64::D3_D4_D5_D6, ARM64::D4_D5_D6_D7, ARM64::D5_D6_D7_D8,
ARM64::D6_D7_D8_D9, ARM64::D7_D8_D9_D10, ARM64::D8_D9_D10_D11,
ARM64::D9_D10_D11_D12, ARM64::D10_D11_D12_D13, ARM64::D11_D12_D13_D14,
ARM64::D12_D13_D14_D15, ARM64::D13_D14_D15_D16, ARM64::D14_D15_D16_D17,
ARM64::D15_D16_D17_D18, ARM64::D16_D17_D18_D19, ARM64::D17_D18_D19_D20,
ARM64::D18_D19_D20_D21, ARM64::D19_D20_D21_D22, ARM64::D20_D21_D22_D23,
ARM64::D21_D22_D23_D24, ARM64::D22_D23_D24_D25, ARM64::D23_D24_D25_D26,
ARM64::D24_D25_D26_D27, ARM64::D25_D26_D27_D28, ARM64::D26_D27_D28_D29,
ARM64::D27_D28_D29_D30, ARM64::D28_D29_D30_D31, ARM64::D29_D30_D31_D0,
ARM64::D30_D31_D0_D1, ARM64::D31_D0_D1_D2
};
static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
if (RegNo > 31)
return Fail;
unsigned Register = DDDDDecoderTable[RegNo];
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static DecodeStatus DecodeFixedPointScaleImm32(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr,
const void *Decoder) {
// scale{5} is asserted as 1 in tblgen.
Imm |= 0x20;
Inst.addOperand(MCOperand::CreateImm(64 - Imm));
return Success;
}
static DecodeStatus DecodeFixedPointScaleImm64(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr,
const void *Decoder) {
Inst.addOperand(MCOperand::CreateImm(64 - Imm));
return Success;
}
static DecodeStatus DecodeCondBranchTarget(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
int64_t ImmVal = Imm;
const ARM64Disassembler *Dis =
static_cast<const ARM64Disassembler *>(Decoder);
// Sign-extend 19-bit immediate.
if (ImmVal & (1 << (19 - 1)))
ImmVal |= ~((1LL << 19) - 1);
if (!Dis->tryAddingSymbolicOperand(Inst, ImmVal << 2, Addr,
Inst.getOpcode() != ARM64::LDRXl, 0, 4))
Inst.addOperand(MCOperand::CreateImm(ImmVal));
return Success;
}
static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address,
const void *Decoder) {
Imm |= 0x8000;
Inst.addOperand(MCOperand::CreateImm(Imm));
bool ValidNamed;
(void)ARM64SysReg::MRSMapper().toString(Imm, ValidNamed);
return ValidNamed ? Success : Fail;
}
static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address,
const void *Decoder) {
Imm |= 0x8000;
Inst.addOperand(MCOperand::CreateImm(Imm));
bool ValidNamed;
(void)ARM64SysReg::MSRMapper().toString(Imm, ValidNamed);
return ValidNamed ? Success : Fail;
}
static DecodeStatus DecodeVecShiftRImm(llvm::MCInst &Inst, unsigned Imm,
unsigned Add) {
Inst.addOperand(MCOperand::CreateImm(Add - Imm));
return Success;
}
static DecodeStatus DecodeVecShiftLImm(llvm::MCInst &Inst, unsigned Imm,
unsigned Add) {
Inst.addOperand(MCOperand::CreateImm((Imm + Add) & (Add - 1)));
return Success;
}
static DecodeStatus DecodeVecShiftR64Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
return DecodeVecShiftRImm(Inst, Imm, 64);
}
static DecodeStatus DecodeVecShiftR64ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr,
const void *Decoder) {
return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);
}
static DecodeStatus DecodeVecShiftR32Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
return DecodeVecShiftRImm(Inst, Imm, 32);
}
static DecodeStatus DecodeVecShiftR32ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr,
const void *Decoder) {
return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);
}
static DecodeStatus DecodeVecShiftR16Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
return DecodeVecShiftRImm(Inst, Imm, 16);
}
static DecodeStatus DecodeVecShiftR16ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr,
const void *Decoder) {
return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);
}
static DecodeStatus DecodeVecShiftR8Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
return DecodeVecShiftRImm(Inst, Imm, 8);
}
static DecodeStatus DecodeVecShiftL64Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
return DecodeVecShiftLImm(Inst, Imm, 64);
}
static DecodeStatus DecodeVecShiftL32Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
return DecodeVecShiftLImm(Inst, Imm, 32);
}
static DecodeStatus DecodeVecShiftL16Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
return DecodeVecShiftLImm(Inst, Imm, 16);
}
static DecodeStatus DecodeVecShiftL8Imm(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
return DecodeVecShiftLImm(Inst, Imm, 8);
}
static DecodeStatus DecodeThreeAddrSRegInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Addr,
const 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 (Inst.getOpcode()) {
default:
return Fail;
case ARM64::ADDWrs:
case ARM64::ADDSWrs:
case ARM64::SUBWrs:
case ARM64::SUBSWrs:
// if shift == '11' then ReservedValue()
if (shiftHi == 0x3)
return Fail;
// Deliberate fallthrough
case ARM64::ANDWrs:
case ARM64::ANDSWrs:
case ARM64::BICWrs:
case ARM64::BICSWrs:
case ARM64::ORRWrs:
case ARM64::ORNWrs:
case ARM64::EORWrs:
case ARM64::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 ARM64::ADDXrs:
case ARM64::ADDSXrs:
case ARM64::SUBXrs:
case ARM64::SUBSXrs:
// if shift == '11' then ReservedValue()
if (shiftHi == 0x3)
return Fail;
// Deliberate fallthrough
case ARM64::ANDXrs:
case ARM64::ANDSXrs:
case ARM64::BICXrs:
case ARM64::BICSXrs:
case ARM64::ORRXrs:
case ARM64::ORNXrs:
case ARM64::EORXrs:
case ARM64::EONXrs:
DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
break;
}
Inst.addOperand(MCOperand::CreateImm(shift));
return Success;
}
static DecodeStatus DecodeMoveImmInstruction(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr,
const void *Decoder) {
unsigned Rd = fieldFromInstruction(insn, 0, 5);
unsigned imm = fieldFromInstruction(insn, 5, 16);
unsigned shift = fieldFromInstruction(insn, 21, 2);
shift <<= 4;
switch (Inst.getOpcode()) {
default:
return Fail;
case ARM64::MOVZWi:
case ARM64::MOVNWi:
case ARM64::MOVKWi:
if (shift & (1U << 5))
return Fail;
DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
break;
case ARM64::MOVZXi:
case ARM64::MOVNXi:
case ARM64::MOVKXi:
DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
break;
}
if (Inst.getOpcode() == ARM64::MOVKWi || Inst.getOpcode() == ARM64::MOVKXi)
Inst.addOperand(Inst.getOperand(0));
Inst.addOperand(MCOperand::CreateImm(imm));
Inst.addOperand(MCOperand::CreateImm(shift));
return Success;
}
static DecodeStatus DecodeUnsignedLdStInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Addr,
const void *Decoder) {
unsigned Rt = fieldFromInstruction(insn, 0, 5);
unsigned Rn = fieldFromInstruction(insn, 5, 5);
unsigned offset = fieldFromInstruction(insn, 10, 12);
const ARM64Disassembler *Dis =
static_cast<const ARM64Disassembler *>(Decoder);
switch (Inst.getOpcode()) {
default:
return Fail;
case ARM64::PRFMui:
// Rt is an immediate in prefetch.
Inst.addOperand(MCOperand::CreateImm(Rt));
break;
case ARM64::STRBBui:
case ARM64::LDRBBui:
case ARM64::LDRSBWui:
case ARM64::STRHHui:
case ARM64::LDRHHui:
case ARM64::LDRSHWui:
case ARM64::STRWui:
case ARM64::LDRWui:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRSBXui:
case ARM64::LDRSHXui:
case ARM64::LDRSWui:
case ARM64::STRXui:
case ARM64::LDRXui:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRQui:
case ARM64::STRQui:
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRDui:
case ARM64::STRDui:
DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRSui:
case ARM64::STRSui:
DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRHui:
case ARM64::STRHui:
DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRBui:
case ARM64::STRBui:
DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
break;
}
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
if (!Dis->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 4))
Inst.addOperand(MCOperand::CreateImm(offset));
return Success;
}
static DecodeStatus DecodeSignedLdStInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Addr,
const void *Decoder) {
unsigned Rt = fieldFromInstruction(insn, 0, 5);
unsigned Rn = fieldFromInstruction(insn, 5, 5);
int64_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);
switch (Inst.getOpcode()) {
default:
return Fail;
case ARM64::PRFUMi:
// Rt is an immediate in prefetch.
Inst.addOperand(MCOperand::CreateImm(Rt));
break;
case ARM64::STURBBi:
case ARM64::LDURBBi:
case ARM64::LDURSBWi:
case ARM64::STURHHi:
case ARM64::LDURHHi:
case ARM64::LDURSHWi:
case ARM64::STURWi:
case ARM64::LDURWi:
case ARM64::LDTRSBWi:
case ARM64::LDTRSHWi:
case ARM64::STTRWi:
case ARM64::LDTRWi:
case ARM64::STTRHi:
case ARM64::LDTRHi:
case ARM64::LDTRBi:
case ARM64::STTRBi:
case ARM64::LDRSBWpre:
case ARM64::LDRSHWpre:
case ARM64::STRBBpre:
case ARM64::LDRBBpre:
case ARM64::STRHHpre:
case ARM64::LDRHHpre:
case ARM64::STRWpre:
case ARM64::LDRWpre:
case ARM64::LDRSBWpost:
case ARM64::LDRSHWpost:
case ARM64::STRBBpost:
case ARM64::LDRBBpost:
case ARM64::STRHHpost:
case ARM64::LDRHHpost:
case ARM64::STRWpost:
case ARM64::LDRWpost:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDURSBXi:
case ARM64::LDURSHXi:
case ARM64::LDURSWi:
case ARM64::STURXi:
case ARM64::LDURXi:
case ARM64::LDTRSBXi:
case ARM64::LDTRSHXi:
case ARM64::LDTRSWi:
case ARM64::STTRXi:
case ARM64::LDTRXi:
case ARM64::LDRSBXpre:
case ARM64::LDRSHXpre:
case ARM64::STRXpre:
case ARM64::LDRSWpre:
case ARM64::LDRXpre:
case ARM64::LDRSBXpost:
case ARM64::LDRSHXpost:
case ARM64::STRXpost:
case ARM64::LDRSWpost:
case ARM64::LDRXpost:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDURQi:
case ARM64::STURQi:
case ARM64::LDRQpre:
case ARM64::STRQpre:
case ARM64::LDRQpost:
case ARM64::STRQpost:
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDURDi:
case ARM64::STURDi:
case ARM64::LDRDpre:
case ARM64::STRDpre:
case ARM64::LDRDpost:
case ARM64::STRDpost:
DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDURSi:
case ARM64::STURSi:
case ARM64::LDRSpre:
case ARM64::STRSpre:
case ARM64::LDRSpost:
case ARM64::STRSpost:
DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDURHi:
case ARM64::STURHi:
case ARM64::LDRHpre:
case ARM64::STRHpre:
case ARM64::LDRHpost:
case ARM64::STRHpost:
DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDURBi:
case ARM64::STURBi:
case ARM64::LDRBpre:
case ARM64::STRBpre:
case ARM64::LDRBpost:
case ARM64::STRBpost:
DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
break;
}
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
Inst.addOperand(MCOperand::CreateImm(offset));
return Success;
}
static DecodeStatus DecodeExclusiveLdStInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Addr,
const 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);
switch (Inst.getOpcode()) {
default:
return Fail;
case ARM64::STLXRW:
case ARM64::STLXRB:
case ARM64::STLXRH:
case ARM64::STXRW:
case ARM64::STXRB:
case ARM64::STXRH:
DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
// FALLTHROUGH
case ARM64::LDARW:
case ARM64::LDARB:
case ARM64::LDARH:
case ARM64::LDAXRW:
case ARM64::LDAXRB:
case ARM64::LDAXRH:
case ARM64::LDXRW:
case ARM64::LDXRB:
case ARM64::LDXRH:
case ARM64::STLRW:
case ARM64::STLRB:
case ARM64::STLRH:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::STLXRX:
case ARM64::STXRX:
DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
// FALLTHROUGH
case ARM64::LDARX:
case ARM64::LDAXRX:
case ARM64::LDXRX:
case ARM64::STLRX:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::STLXPW:
case ARM64::STXPW:
DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
// FALLTHROUGH
case ARM64::LDAXPW:
case ARM64::LDXPW:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
break;
case ARM64::STLXPX:
case ARM64::STXPX:
DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
// FALLTHROUGH
case ARM64::LDAXPX:
case ARM64::LDXPX:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
break;
}
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
return Success;
}
static DecodeStatus DecodePairLdStInstruction(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr,
const void *Decoder) {
unsigned Rt = fieldFromInstruction(insn, 0, 5);
unsigned Rn = fieldFromInstruction(insn, 5, 5);
unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
int64_t offset = fieldFromInstruction(insn, 15, 7);
// offset is a 7-bit signed immediate, so sign extend it to
// fill the unsigned.
if (offset & (1 << (7 - 1)))
offset |= ~((1LL << 7) - 1);
switch (Inst.getOpcode()) {
default:
return Fail;
case ARM64::LDNPXi:
case ARM64::STNPXi:
case ARM64::LDPXpost:
case ARM64::STPXpost:
case ARM64::LDPSWpost:
case ARM64::LDPXi:
case ARM64::STPXi:
case ARM64::LDPSWi:
case ARM64::LDPXpre:
case ARM64::STPXpre:
case ARM64::LDPSWpre:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
break;
case ARM64::LDNPWi:
case ARM64::STNPWi:
case ARM64::LDPWpost:
case ARM64::STPWpost:
case ARM64::LDPWi:
case ARM64::STPWi:
case ARM64::LDPWpre:
case ARM64::STPWpre:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
break;
case ARM64::LDNPQi:
case ARM64::STNPQi:
case ARM64::LDPQpost:
case ARM64::STPQpost:
case ARM64::LDPQi:
case ARM64::STPQi:
case ARM64::LDPQpre:
case ARM64::STPQpre:
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder);
break;
case ARM64::LDNPDi:
case ARM64::STNPDi:
case ARM64::LDPDpost:
case ARM64::STPDpost:
case ARM64::LDPDi:
case ARM64::STPDi:
case ARM64::LDPDpre:
case ARM64::STPDpre:
DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder);
break;
case ARM64::LDNPSi:
case ARM64::STNPSi:
case ARM64::LDPSpost:
case ARM64::STPSpost:
case ARM64::LDPSi:
case ARM64::STPSi:
case ARM64::LDPSpre:
case ARM64::STPSpre:
DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder);
break;
}
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
Inst.addOperand(MCOperand::CreateImm(offset));
return Success;
}
static DecodeStatus DecodeRegOffsetLdStInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Addr,
const void *Decoder) {
unsigned Rt = fieldFromInstruction(insn, 0, 5);
unsigned Rn = fieldFromInstruction(insn, 5, 5);
unsigned Rm = fieldFromInstruction(insn, 16, 5);
unsigned extendHi = fieldFromInstruction(insn, 13, 3);
unsigned extendLo = fieldFromInstruction(insn, 12, 1);
unsigned extend = (extendHi << 1) | extendLo;
// All RO load-store instructions are undefined if option == 00x or 10x.
if (extend >> 2 == 0x0 || extend >> 2 == 0x2)
return Fail;
switch (Inst.getOpcode()) {
default:
return Fail;
case ARM64::LDRSWro:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRXro:
case ARM64::STRXro:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRWro:
case ARM64::STRWro:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRQro:
case ARM64::STRQro:
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRDro:
case ARM64::STRDro:
DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRSro:
case ARM64::STRSro:
DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRHro:
case ARM64::STRHro:
DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRBro:
case ARM64::STRBro:
DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRBBro:
case ARM64::STRBBro:
case ARM64::LDRSBWro:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRHHro:
case ARM64::STRHHro:
case ARM64::LDRSHWro:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRSHXro:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LDRSBXro:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::PRFMro:
Inst.addOperand(MCOperand::CreateImm(Rt));
}
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
if ((extendHi & 0x3) == 0x3)
DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
else
DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
Inst.addOperand(MCOperand::CreateImm(extend));
return Success;
}
static DecodeStatus DecodeAddSubERegInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Addr,
const void *Decoder) {
unsigned Rd = fieldFromInstruction(insn, 0, 5);
unsigned Rn = fieldFromInstruction(insn, 5, 5);
unsigned Rm = fieldFromInstruction(insn, 16, 5);
unsigned extend = fieldFromInstruction(insn, 10, 6);
unsigned shift = extend & 0x7;
if (shift > 4)
return Fail;
switch (Inst.getOpcode()) {
default:
return Fail;
case ARM64::ADDWrx:
case ARM64::SUBWrx:
DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
break;
case ARM64::ADDSWrx:
case ARM64::SUBSWrx:
DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
break;
case ARM64::ADDXrx:
case ARM64::SUBXrx:
DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
break;
case ARM64::ADDSXrx:
case ARM64::SUBSXrx:
DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
break;
case ARM64::ADDXrx64:
case ARM64::SUBXrx64:
DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
break;
case ARM64::SUBSXrx64:
case ARM64::ADDSXrx64:
DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
break;
}
Inst.addOperand(MCOperand::CreateImm(extend));
return Success;
}
static DecodeStatus DecodeLogicalImmInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Addr,
const 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 (Inst.getOpcode() == ARM64::ANDSXri)
DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
else
DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
imm = fieldFromInstruction(insn, 10, 13);
if (!ARM64_AM::isValidDecodeLogicalImmediate(imm, 64))
return Fail;
} else {
if (Inst.getOpcode() == ARM64::ANDSWri)
DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
else
DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
imm = fieldFromInstruction(insn, 10, 12);
if (!ARM64_AM::isValidDecodeLogicalImmediate(imm, 32))
return Fail;
}
Inst.addOperand(MCOperand::CreateImm(imm));
return Success;
}
static DecodeStatus DecodeModImmInstruction(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr,
const 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 (Inst.getOpcode() == ARM64::MOVID)
DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder);
else
DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder);
Inst.addOperand(MCOperand::CreateImm(imm));
switch (Inst.getOpcode()) {
default:
break;
case ARM64::MOVIv4i16:
case ARM64::MOVIv8i16:
case ARM64::MVNIv4i16:
case ARM64::MVNIv8i16:
case ARM64::MOVIv2i32:
case ARM64::MOVIv4i32:
case ARM64::MVNIv2i32:
case ARM64::MVNIv4i32:
Inst.addOperand(MCOperand::CreateImm((cmode & 6) << 2));
break;
case ARM64::MOVIv2s_msl:
case ARM64::MOVIv4s_msl:
case ARM64::MVNIv2s_msl:
case ARM64::MVNIv4s_msl:
Inst.addOperand(MCOperand::CreateImm(cmode & 1 ? 0x110 : 0x108));
break;
}
return Success;
}
static DecodeStatus DecodeModImmTiedInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Addr,
const 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);
Inst.addOperand(MCOperand::CreateImm(imm));
Inst.addOperand(MCOperand::CreateImm((cmode & 6) << 2));
return Success;
}
static DecodeStatus DecodeAdrInstruction(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr, const void *Decoder) {
unsigned Rd = fieldFromInstruction(insn, 0, 5);
int64_t imm = fieldFromInstruction(insn, 5, 19) << 2;
imm |= fieldFromInstruction(insn, 29, 2);
const ARM64Disassembler *Dis =
static_cast<const ARM64Disassembler *>(Decoder);
// 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))
Inst.addOperand(MCOperand::CreateImm(imm));
return Success;
}
static DecodeStatus DecodeBaseAddSubImm(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr, const 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;
const ARM64Disassembler *Dis =
static_cast<const ARM64Disassembler *>(Decoder);
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))
Inst.addOperand(MCOperand::CreateImm(ImmVal));
Inst.addOperand(MCOperand::CreateImm(12 * ShifterVal));
return Success;
}
static DecodeStatus DecodeUnconditionalBranch(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr,
const void *Decoder) {
int64_t imm = fieldFromInstruction(insn, 0, 26);
const ARM64Disassembler *Dis =
static_cast<const ARM64Disassembler *>(Decoder);
// 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))
Inst.addOperand(MCOperand::CreateImm(imm));
return Success;
}
static DecodeStatus DecodeSystemCPSRInstruction(llvm::MCInst &Inst,
uint32_t insn, uint64_t Addr,
const void *Decoder) {
uint64_t op1 = fieldFromInstruction(insn, 16, 3);
uint64_t op2 = fieldFromInstruction(insn, 5, 3);
uint64_t crm = fieldFromInstruction(insn, 8, 4);
uint64_t cpsr_field = (op1 << 3) | op2;
Inst.addOperand(MCOperand::CreateImm(cpsr_field));
Inst.addOperand(MCOperand::CreateImm(crm));
bool ValidNamed;
(void)ARM64PState::PStateMapper().toString(cpsr_field, ValidNamed);
return ValidNamed ? Success : Fail;
}
static DecodeStatus DecodeTestAndBranch(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr, const void *Decoder) {
uint64_t Rt = fieldFromInstruction(insn, 0, 5);
uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;
bit |= fieldFromInstruction(insn, 19, 5);
int64_t dst = fieldFromInstruction(insn, 5, 14);
const ARM64Disassembler *Dis =
static_cast<const ARM64Disassembler *>(Decoder);
// Sign-extend 14-bit immediate.
if (dst & (1 << (14 - 1)))
dst |= ~((1LL << 14) - 1);
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
Inst.addOperand(MCOperand::CreateImm(bit));
if (!Dis->tryAddingSymbolicOperand(Inst, dst << 2, Addr, true, 0, 4))
Inst.addOperand(MCOperand::CreateImm(dst));
return Success;
}
static DecodeStatus DecodeSIMDLdStPost(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr, const void *Decoder) {
uint64_t Rd = fieldFromInstruction(insn, 0, 5);
uint64_t Rn = fieldFromInstruction(insn, 5, 5);
uint64_t Rm = fieldFromInstruction(insn, 16, 5);
switch (Inst.getOpcode()) {
default:
return Fail;
case ARM64::ST1Onev8b_POST:
case ARM64::ST1Onev4h_POST:
case ARM64::ST1Onev2s_POST:
case ARM64::ST1Onev1d_POST:
case ARM64::LD1Onev8b_POST:
case ARM64::LD1Onev4h_POST:
case ARM64::LD1Onev2s_POST:
case ARM64::LD1Onev1d_POST:
DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder);
break;
case ARM64::ST1Onev16b_POST:
case ARM64::ST1Onev8h_POST:
case ARM64::ST1Onev4s_POST:
case ARM64::ST1Onev2d_POST:
case ARM64::LD1Onev16b_POST:
case ARM64::LD1Onev8h_POST:
case ARM64::LD1Onev4s_POST:
case ARM64::LD1Onev2d_POST:
DecodeFPR128RegisterClass(Inst, Rd, Addr, Decoder);
break;
case ARM64::ST1Twov8b_POST:
case ARM64::ST1Twov4h_POST:
case ARM64::ST1Twov2s_POST:
case ARM64::ST1Twov1d_POST:
case ARM64::ST2Twov8b_POST:
case ARM64::ST2Twov4h_POST:
case ARM64::ST2Twov2s_POST:
case ARM64::LD1Twov8b_POST:
case ARM64::LD1Twov4h_POST:
case ARM64::LD1Twov2s_POST:
case ARM64::LD1Twov1d_POST:
case ARM64::LD2Twov8b_POST:
case ARM64::LD2Twov4h_POST:
case ARM64::LD2Twov2s_POST:
DecodeDDRegisterClass(Inst, Rd, Addr, Decoder);
break;
case ARM64::ST1Threev8b_POST:
case ARM64::ST1Threev4h_POST:
case ARM64::ST1Threev2s_POST:
case ARM64::ST1Threev1d_POST:
case ARM64::ST3Threev8b_POST:
case ARM64::ST3Threev4h_POST:
case ARM64::ST3Threev2s_POST:
case ARM64::LD1Threev8b_POST:
case ARM64::LD1Threev4h_POST:
case ARM64::LD1Threev2s_POST:
case ARM64::LD1Threev1d_POST:
case ARM64::LD3Threev8b_POST:
case ARM64::LD3Threev4h_POST:
case ARM64::LD3Threev2s_POST:
DecodeDDDRegisterClass(Inst, Rd, Addr, Decoder);
break;
case ARM64::ST1Fourv8b_POST:
case ARM64::ST1Fourv4h_POST:
case ARM64::ST1Fourv2s_POST:
case ARM64::ST1Fourv1d_POST:
case ARM64::ST4Fourv8b_POST:
case ARM64::ST4Fourv4h_POST:
case ARM64::ST4Fourv2s_POST:
case ARM64::LD1Fourv8b_POST:
case ARM64::LD1Fourv4h_POST:
case ARM64::LD1Fourv2s_POST:
case ARM64::LD1Fourv1d_POST:
case ARM64::LD4Fourv8b_POST:
case ARM64::LD4Fourv4h_POST:
case ARM64::LD4Fourv2s_POST:
DecodeDDDDRegisterClass(Inst, Rd, Addr, Decoder);
break;
case ARM64::ST1Twov16b_POST:
case ARM64::ST1Twov8h_POST:
case ARM64::ST1Twov4s_POST:
case ARM64::ST1Twov2d_POST:
case ARM64::ST2Twov16b_POST:
case ARM64::ST2Twov8h_POST:
case ARM64::ST2Twov4s_POST:
case ARM64::ST2Twov2d_POST:
case ARM64::LD1Twov16b_POST:
case ARM64::LD1Twov8h_POST:
case ARM64::LD1Twov4s_POST:
case ARM64::LD1Twov2d_POST:
case ARM64::LD2Twov16b_POST:
case ARM64::LD2Twov8h_POST:
case ARM64::LD2Twov4s_POST:
case ARM64::LD2Twov2d_POST:
DecodeQQRegisterClass(Inst, Rd, Addr, Decoder);
break;
case ARM64::ST1Threev16b_POST:
case ARM64::ST1Threev8h_POST:
case ARM64::ST1Threev4s_POST:
case ARM64::ST1Threev2d_POST:
case ARM64::ST3Threev16b_POST:
case ARM64::ST3Threev8h_POST:
case ARM64::ST3Threev4s_POST:
case ARM64::ST3Threev2d_POST:
case ARM64::LD1Threev16b_POST:
case ARM64::LD1Threev8h_POST:
case ARM64::LD1Threev4s_POST:
case ARM64::LD1Threev2d_POST:
case ARM64::LD3Threev16b_POST:
case ARM64::LD3Threev8h_POST:
case ARM64::LD3Threev4s_POST:
case ARM64::LD3Threev2d_POST:
DecodeQQQRegisterClass(Inst, Rd, Addr, Decoder);
break;
case ARM64::ST1Fourv16b_POST:
case ARM64::ST1Fourv8h_POST:
case ARM64::ST1Fourv4s_POST:
case ARM64::ST1Fourv2d_POST:
case ARM64::ST4Fourv16b_POST:
case ARM64::ST4Fourv8h_POST:
case ARM64::ST4Fourv4s_POST:
case ARM64::ST4Fourv2d_POST:
case ARM64::LD1Fourv16b_POST:
case ARM64::LD1Fourv8h_POST:
case ARM64::LD1Fourv4s_POST:
case ARM64::LD1Fourv2d_POST:
case ARM64::LD4Fourv16b_POST:
case ARM64::LD4Fourv8h_POST:
case ARM64::LD4Fourv4s_POST:
case ARM64::LD4Fourv2d_POST:
DecodeQQQQRegisterClass(Inst, Rd, Addr, Decoder);
break;
}
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
return Success;
}
static DecodeStatus DecodeSIMDLdStSingle(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr, const void *Decoder) {
uint64_t Rt = fieldFromInstruction(insn, 0, 5);
uint64_t Rn = fieldFromInstruction(insn, 5, 5);
uint64_t Rm = fieldFromInstruction(insn, 16, 5);
uint64_t size = fieldFromInstruction(insn, 10, 2);
uint64_t S = fieldFromInstruction(insn, 12, 1);
uint64_t Q = fieldFromInstruction(insn, 30, 1);
uint64_t index = 0;
switch (Inst.getOpcode()) {
case ARM64::ST1i8:
case ARM64::ST1i8_POST:
case ARM64::ST2i8:
case ARM64::ST2i8_POST:
case ARM64::ST3i8_POST:
case ARM64::ST3i8:
case ARM64::ST4i8_POST:
case ARM64::ST4i8:
index = (Q << 3) | (S << 2) | size;
break;
case ARM64::ST1i16:
case ARM64::ST1i16_POST:
case ARM64::ST2i16:
case ARM64::ST2i16_POST:
case ARM64::ST3i16_POST:
case ARM64::ST3i16:
case ARM64::ST4i16_POST:
case ARM64::ST4i16:
index = (Q << 2) | (S << 1) | (size >> 1);
break;
case ARM64::ST1i32:
case ARM64::ST1i32_POST:
case ARM64::ST2i32:
case ARM64::ST2i32_POST:
case ARM64::ST3i32_POST:
case ARM64::ST3i32:
case ARM64::ST4i32_POST:
case ARM64::ST4i32:
index = (Q << 1) | S;
break;
case ARM64::ST1i64:
case ARM64::ST1i64_POST:
case ARM64::ST2i64:
case ARM64::ST2i64_POST:
case ARM64::ST3i64_POST:
case ARM64::ST3i64:
case ARM64::ST4i64_POST:
case ARM64::ST4i64:
index = Q;
break;
}
switch (Inst.getOpcode()) {
default:
return Fail;
case ARM64::LD1Rv8b:
case ARM64::LD1Rv8b_POST:
case ARM64::LD1Rv4h:
case ARM64::LD1Rv4h_POST:
case ARM64::LD1Rv2s:
case ARM64::LD1Rv2s_POST:
case ARM64::LD1Rv1d:
case ARM64::LD1Rv1d_POST:
DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LD1Rv16b:
case ARM64::LD1Rv16b_POST:
case ARM64::LD1Rv8h:
case ARM64::LD1Rv8h_POST:
case ARM64::LD1Rv4s:
case ARM64::LD1Rv4s_POST:
case ARM64::LD1Rv2d:
case ARM64::LD1Rv2d_POST:
case ARM64::ST1i8:
case ARM64::ST1i8_POST:
case ARM64::ST1i16:
case ARM64::ST1i16_POST:
case ARM64::ST1i32:
case ARM64::ST1i32_POST:
case ARM64::ST1i64:
case ARM64::ST1i64_POST:
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LD2Rv16b:
case ARM64::LD2Rv16b_POST:
case ARM64::LD2Rv8h:
case ARM64::LD2Rv8h_POST:
case ARM64::LD2Rv4s:
case ARM64::LD2Rv4s_POST:
case ARM64::LD2Rv2d:
case ARM64::LD2Rv2d_POST:
case ARM64::ST2i8:
case ARM64::ST2i8_POST:
case ARM64::ST2i16:
case ARM64::ST2i16_POST:
case ARM64::ST2i32:
case ARM64::ST2i32_POST:
case ARM64::ST2i64:
case ARM64::ST2i64_POST:
DecodeQQRegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LD2Rv8b:
case ARM64::LD2Rv8b_POST:
case ARM64::LD2Rv4h:
case ARM64::LD2Rv4h_POST:
case ARM64::LD2Rv2s:
case ARM64::LD2Rv2s_POST:
case ARM64::LD2Rv1d:
case ARM64::LD2Rv1d_POST:
DecodeDDRegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LD3Rv8b:
case ARM64::LD3Rv8b_POST:
case ARM64::LD3Rv4h:
case ARM64::LD3Rv4h_POST:
case ARM64::LD3Rv2s:
case ARM64::LD3Rv2s_POST:
case ARM64::LD3Rv1d:
case ARM64::LD3Rv1d_POST:
DecodeDDDRegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LD3Rv16b:
case ARM64::LD3Rv16b_POST:
case ARM64::LD3Rv8h:
case ARM64::LD3Rv8h_POST:
case ARM64::LD3Rv4s:
case ARM64::LD3Rv4s_POST:
case ARM64::LD3Rv2d:
case ARM64::LD3Rv2d_POST:
case ARM64::ST3i8:
case ARM64::ST3i8_POST:
case ARM64::ST3i16:
case ARM64::ST3i16_POST:
case ARM64::ST3i32:
case ARM64::ST3i32_POST:
case ARM64::ST3i64:
case ARM64::ST3i64_POST:
DecodeQQQRegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LD4Rv8b:
case ARM64::LD4Rv8b_POST:
case ARM64::LD4Rv4h:
case ARM64::LD4Rv4h_POST:
case ARM64::LD4Rv2s:
case ARM64::LD4Rv2s_POST:
case ARM64::LD4Rv1d:
case ARM64::LD4Rv1d_POST:
DecodeDDDDRegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LD4Rv16b:
case ARM64::LD4Rv16b_POST:
case ARM64::LD4Rv8h:
case ARM64::LD4Rv8h_POST:
case ARM64::LD4Rv4s:
case ARM64::LD4Rv4s_POST:
case ARM64::LD4Rv2d:
case ARM64::LD4Rv2d_POST:
case ARM64::ST4i8:
case ARM64::ST4i8_POST:
case ARM64::ST4i16:
case ARM64::ST4i16_POST:
case ARM64::ST4i32:
case ARM64::ST4i32_POST:
case ARM64::ST4i64:
case ARM64::ST4i64_POST:
DecodeQQQQRegisterClass(Inst, Rt, Addr, Decoder);
break;
}
switch (Inst.getOpcode()) {
case ARM64::LD1Rv8b:
case ARM64::LD1Rv8b_POST:
case ARM64::LD1Rv16b:
case ARM64::LD1Rv16b_POST:
case ARM64::LD1Rv4h:
case ARM64::LD1Rv4h_POST:
case ARM64::LD1Rv8h:
case ARM64::LD1Rv8h_POST:
case ARM64::LD1Rv4s:
case ARM64::LD1Rv4s_POST:
case ARM64::LD1Rv2s:
case ARM64::LD1Rv2s_POST:
case ARM64::LD1Rv1d:
case ARM64::LD1Rv1d_POST:
case ARM64::LD1Rv2d:
case ARM64::LD1Rv2d_POST:
case ARM64::LD2Rv8b:
case ARM64::LD2Rv8b_POST:
case ARM64::LD2Rv16b:
case ARM64::LD2Rv16b_POST:
case ARM64::LD2Rv4h:
case ARM64::LD2Rv4h_POST:
case ARM64::LD2Rv8h:
case ARM64::LD2Rv8h_POST:
case ARM64::LD2Rv2s:
case ARM64::LD2Rv2s_POST:
case ARM64::LD2Rv4s:
case ARM64::LD2Rv4s_POST:
case ARM64::LD2Rv2d:
case ARM64::LD2Rv2d_POST:
case ARM64::LD2Rv1d:
case ARM64::LD2Rv1d_POST:
case ARM64::LD3Rv8b:
case ARM64::LD3Rv8b_POST:
case ARM64::LD3Rv16b:
case ARM64::LD3Rv16b_POST:
case ARM64::LD3Rv4h:
case ARM64::LD3Rv4h_POST:
case ARM64::LD3Rv8h:
case ARM64::LD3Rv8h_POST:
case ARM64::LD3Rv2s:
case ARM64::LD3Rv2s_POST:
case ARM64::LD3Rv4s:
case ARM64::LD3Rv4s_POST:
case ARM64::LD3Rv2d:
case ARM64::LD3Rv2d_POST:
case ARM64::LD3Rv1d:
case ARM64::LD3Rv1d_POST:
case ARM64::LD4Rv8b:
case ARM64::LD4Rv8b_POST:
case ARM64::LD4Rv16b:
case ARM64::LD4Rv16b_POST:
case ARM64::LD4Rv4h:
case ARM64::LD4Rv4h_POST:
case ARM64::LD4Rv8h:
case ARM64::LD4Rv8h_POST:
case ARM64::LD4Rv2s:
case ARM64::LD4Rv2s_POST:
case ARM64::LD4Rv4s:
case ARM64::LD4Rv4s_POST:
case ARM64::LD4Rv2d:
case ARM64::LD4Rv2d_POST:
case ARM64::LD4Rv1d:
case ARM64::LD4Rv1d_POST:
break;
default:
Inst.addOperand(MCOperand::CreateImm(index));
}
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
switch (Inst.getOpcode()) {
case ARM64::ST1i8_POST:
case ARM64::ST1i16_POST:
case ARM64::ST1i32_POST:
case ARM64::ST1i64_POST:
case ARM64::LD1Rv8b_POST:
case ARM64::LD1Rv16b_POST:
case ARM64::LD1Rv4h_POST:
case ARM64::LD1Rv8h_POST:
case ARM64::LD1Rv2s_POST:
case ARM64::LD1Rv4s_POST:
case ARM64::LD1Rv1d_POST:
case ARM64::LD1Rv2d_POST:
case ARM64::ST2i8_POST:
case ARM64::ST2i16_POST:
case ARM64::ST2i32_POST:
case ARM64::ST2i64_POST:
case ARM64::LD2Rv8b_POST:
case ARM64::LD2Rv16b_POST:
case ARM64::LD2Rv4h_POST:
case ARM64::LD2Rv8h_POST:
case ARM64::LD2Rv2s_POST:
case ARM64::LD2Rv4s_POST:
case ARM64::LD2Rv2d_POST:
case ARM64::LD2Rv1d_POST:
case ARM64::ST3i8_POST:
case ARM64::ST3i16_POST:
case ARM64::ST3i32_POST:
case ARM64::ST3i64_POST:
case ARM64::LD3Rv8b_POST:
case ARM64::LD3Rv16b_POST:
case ARM64::LD3Rv4h_POST:
case ARM64::LD3Rv8h_POST:
case ARM64::LD3Rv2s_POST:
case ARM64::LD3Rv4s_POST:
case ARM64::LD3Rv2d_POST:
case ARM64::LD3Rv1d_POST:
case ARM64::ST4i8_POST:
case ARM64::ST4i16_POST:
case ARM64::ST4i32_POST:
case ARM64::ST4i64_POST:
case ARM64::LD4Rv8b_POST:
case ARM64::LD4Rv16b_POST:
case ARM64::LD4Rv4h_POST:
case ARM64::LD4Rv8h_POST:
case ARM64::LD4Rv2s_POST:
case ARM64::LD4Rv4s_POST:
case ARM64::LD4Rv2d_POST:
case ARM64::LD4Rv1d_POST:
DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
break;
}
return Success;
}
static DecodeStatus DecodeSIMDLdStSingleTied(llvm::MCInst &Inst, uint32_t insn,
uint64_t Addr,
const void *Decoder) {
uint64_t Rt = fieldFromInstruction(insn, 0, 5);
uint64_t Rn = fieldFromInstruction(insn, 5, 5);
uint64_t Rm = fieldFromInstruction(insn, 16, 5);
uint64_t size = fieldFromInstruction(insn, 10, 2);
uint64_t S = fieldFromInstruction(insn, 12, 1);
uint64_t Q = fieldFromInstruction(insn, 30, 1);
uint64_t index = 0;
switch (Inst.getOpcode()) {
case ARM64::LD1i8:
case ARM64::LD1i8_POST:
case ARM64::LD2i8:
case ARM64::LD2i8_POST:
case ARM64::LD3i8_POST:
case ARM64::LD3i8:
case ARM64::LD4i8_POST:
case ARM64::LD4i8:
index = (Q << 3) | (S << 2) | size;
break;
case ARM64::LD1i16:
case ARM64::LD1i16_POST:
case ARM64::LD2i16:
case ARM64::LD2i16_POST:
case ARM64::LD3i16_POST:
case ARM64::LD3i16:
case ARM64::LD4i16_POST:
case ARM64::LD4i16:
index = (Q << 2) | (S << 1) | (size >> 1);
break;
case ARM64::LD1i32:
case ARM64::LD1i32_POST:
case ARM64::LD2i32:
case ARM64::LD2i32_POST:
case ARM64::LD3i32_POST:
case ARM64::LD3i32:
case ARM64::LD4i32_POST:
case ARM64::LD4i32:
index = (Q << 1) | S;
break;
case ARM64::LD1i64:
case ARM64::LD1i64_POST:
case ARM64::LD2i64:
case ARM64::LD2i64_POST:
case ARM64::LD3i64_POST:
case ARM64::LD3i64:
case ARM64::LD4i64_POST:
case ARM64::LD4i64:
index = Q;
break;
}
switch (Inst.getOpcode()) {
default:
return Fail;
case ARM64::LD1i8:
case ARM64::LD1i8_POST:
case ARM64::LD1i16:
case ARM64::LD1i16_POST:
case ARM64::LD1i32:
case ARM64::LD1i32_POST:
case ARM64::LD1i64:
case ARM64::LD1i64_POST:
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LD2i8:
case ARM64::LD2i8_POST:
case ARM64::LD2i16:
case ARM64::LD2i16_POST:
case ARM64::LD2i32:
case ARM64::LD2i32_POST:
case ARM64::LD2i64:
case ARM64::LD2i64_POST:
DecodeQQRegisterClass(Inst, Rt, Addr, Decoder);
DecodeQQRegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LD3i8:
case ARM64::LD3i8_POST:
case ARM64::LD3i16:
case ARM64::LD3i16_POST:
case ARM64::LD3i32:
case ARM64::LD3i32_POST:
case ARM64::LD3i64:
case ARM64::LD3i64_POST:
DecodeQQQRegisterClass(Inst, Rt, Addr, Decoder);
DecodeQQQRegisterClass(Inst, Rt, Addr, Decoder);
break;
case ARM64::LD4i8:
case ARM64::LD4i8_POST:
case ARM64::LD4i16:
case ARM64::LD4i16_POST:
case ARM64::LD4i32:
case ARM64::LD4i32_POST:
case ARM64::LD4i64:
case ARM64::LD4i64_POST:
DecodeQQQQRegisterClass(Inst, Rt, Addr, Decoder);
DecodeQQQQRegisterClass(Inst, Rt, Addr, Decoder);
break;
}
Inst.addOperand(MCOperand::CreateImm(index));
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
switch (Inst.getOpcode()) {
case ARM64::LD1i8_POST:
case ARM64::LD1i16_POST:
case ARM64::LD1i32_POST:
case ARM64::LD1i64_POST:
case ARM64::LD2i8_POST:
case ARM64::LD2i16_POST:
case ARM64::LD2i32_POST:
case ARM64::LD2i64_POST:
case ARM64::LD3i8_POST:
case ARM64::LD3i16_POST:
case ARM64::LD3i32_POST:
case ARM64::LD3i64_POST:
case ARM64::LD4i8_POST:
case ARM64::LD4i16_POST:
case ARM64::LD4i32_POST:
case ARM64::LD4i64_POST:
DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
break;
}
return Success;
}