10b57cec5SDimitry Andric //===- AArch64Disassembler.cpp - Disassembler for AArch64 -----------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // 100b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "AArch64Disassembler.h" 130b57cec5SDimitry Andric #include "AArch64ExternalSymbolizer.h" 140b57cec5SDimitry Andric #include "MCTargetDesc/AArch64AddressingModes.h" 150b57cec5SDimitry Andric #include "MCTargetDesc/AArch64MCTargetDesc.h" 160b57cec5SDimitry Andric #include "TargetInfo/AArch64TargetInfo.h" 170b57cec5SDimitry Andric #include "Utils/AArch64BaseInfo.h" 180b57cec5SDimitry Andric #include "llvm-c/Disassembler.h" 1981ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCRelocationInfo.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCInst.h" 2281ad6265SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 25349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 260b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 270b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 280b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 290b57cec5SDimitry Andric #include <algorithm> 300b57cec5SDimitry Andric #include <memory> 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric using namespace llvm; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric #define DEBUG_TYPE "aarch64-disassembler" 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric // Pull DecodeStatus and its enum values into the global namespace. 370b57cec5SDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric // Forward declare these because the autogenerated code will reference them. 400b57cec5SDimitry Andric // Definitions are further down. 41*0fca6ea1SDimitry Andric template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass> 42*0fca6ea1SDimitry Andric static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo, 430b57cec5SDimitry Andric uint64_t Address, 4481ad6265SDimitry Andric const MCDisassembler *Decoder); 4581ad6265SDimitry Andric static DecodeStatus 4681ad6265SDimitry Andric DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, 4781ad6265SDimitry Andric const MCDisassembler *Decoder); 48bdd1243dSDimitry Andric static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo, 49bdd1243dSDimitry Andric uint64_t Address, 50bdd1243dSDimitry Andric const void *Decoder); 51bdd1243dSDimitry Andric static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo, 52bdd1243dSDimitry Andric uint64_t Address, 53bdd1243dSDimitry Andric const void *Decoder); 54fe6060f1SDimitry Andric template <unsigned NumBitsForTile> 55fe6060f1SDimitry Andric static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo, 56fe6060f1SDimitry Andric uint64_t Address, 5781ad6265SDimitry Andric const MCDisassembler *Decoder); 5881ad6265SDimitry Andric static DecodeStatus 5981ad6265SDimitry Andric DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask, 6081ad6265SDimitry Andric uint64_t Address, 6181ad6265SDimitry Andric const MCDisassembler *Decoder); 62bdd1243dSDimitry Andric static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo, 63bdd1243dSDimitry Andric uint64_t Address, 64bdd1243dSDimitry Andric const void *Decoder); 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm, 670b57cec5SDimitry Andric uint64_t Address, 6881ad6265SDimitry Andric const MCDisassembler *Decoder); 690b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm, 700b57cec5SDimitry Andric uint64_t Address, 7181ad6265SDimitry Andric const MCDisassembler *Decoder); 72cb14a3feSDimitry Andric static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm, 73cb14a3feSDimitry Andric uint64_t Address, 74cb14a3feSDimitry Andric const MCDisassembler *Decoder); 750b57cec5SDimitry Andric static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm, 760b57cec5SDimitry Andric uint64_t Address, 7781ad6265SDimitry Andric const MCDisassembler *Decoder); 7881ad6265SDimitry Andric static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm, 7981ad6265SDimitry Andric uint64_t Address, 8081ad6265SDimitry Andric const MCDisassembler *Decoder); 8181ad6265SDimitry Andric static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm, 8281ad6265SDimitry Andric uint64_t Address, 8381ad6265SDimitry Andric const MCDisassembler *Decoder); 8481ad6265SDimitry Andric static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm, 8581ad6265SDimitry Andric uint64_t Address, 8681ad6265SDimitry Andric const MCDisassembler *Decoder); 8781ad6265SDimitry Andric static DecodeStatus 8881ad6265SDimitry Andric DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Address, 8981ad6265SDimitry Andric const MCDisassembler *Decoder); 900b57cec5SDimitry Andric static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn, 910b57cec5SDimitry Andric uint64_t Address, 9281ad6265SDimitry Andric const MCDisassembler *Decoder); 9381ad6265SDimitry Andric static DecodeStatus 9481ad6265SDimitry Andric DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Address, 9581ad6265SDimitry Andric const MCDisassembler *Decoder); 960b57cec5SDimitry Andric static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn, 970b57cec5SDimitry Andric uint64_t Address, 9881ad6265SDimitry Andric const MCDisassembler *Decoder); 9981ad6265SDimitry Andric static DecodeStatus 10081ad6265SDimitry Andric DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Address, 10181ad6265SDimitry Andric const MCDisassembler *Decoder); 1020b57cec5SDimitry Andric static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn, 1030b57cec5SDimitry Andric uint64_t Address, 10481ad6265SDimitry Andric const MCDisassembler *Decoder); 1055ffd83dbSDimitry Andric static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn, 1065ffd83dbSDimitry Andric uint64_t Address, 10781ad6265SDimitry Andric const MCDisassembler *Decoder); 1080b57cec5SDimitry Andric static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn, 1090b57cec5SDimitry Andric uint64_t Address, 11081ad6265SDimitry Andric const MCDisassembler *Decoder); 1110b57cec5SDimitry Andric static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn, 1120b57cec5SDimitry Andric uint64_t Address, 11381ad6265SDimitry Andric const MCDisassembler *Decoder); 1140b57cec5SDimitry Andric static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn, 1150b57cec5SDimitry Andric uint64_t Address, 11681ad6265SDimitry Andric const MCDisassembler *Decoder); 1170b57cec5SDimitry Andric static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn, 1180b57cec5SDimitry Andric uint64_t Address, 11981ad6265SDimitry Andric const MCDisassembler *Decoder); 1200b57cec5SDimitry Andric static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn, 12181ad6265SDimitry Andric uint64_t Address, 12281ad6265SDimitry Andric const MCDisassembler *Decoder); 1230b57cec5SDimitry Andric static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn, 12481ad6265SDimitry Andric uint64_t Address, 12581ad6265SDimitry Andric const MCDisassembler *Decoder); 1260b57cec5SDimitry Andric static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn, 1270b57cec5SDimitry Andric uint64_t Address, 12881ad6265SDimitry Andric const MCDisassembler *Decoder); 12981ad6265SDimitry Andric static DecodeStatus 130bdd1243dSDimitry Andric DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn, 131bdd1243dSDimitry Andric uint64_t Address, 132bdd1243dSDimitry Andric const MCDisassembler *Decoder); 133bdd1243dSDimitry Andric static DecodeStatus 134bdd1243dSDimitry Andric DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn, 135bdd1243dSDimitry Andric uint64_t Address, 13681ad6265SDimitry Andric const MCDisassembler *Decoder); 1370b57cec5SDimitry Andric static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn, 13881ad6265SDimitry Andric uint64_t Address, 13981ad6265SDimitry Andric const MCDisassembler *Decoder); 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn, 1420b57cec5SDimitry Andric uint64_t Address, 14381ad6265SDimitry Andric const MCDisassembler *Decoder); 1440b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm, 14581ad6265SDimitry Andric uint64_t Addr, 14681ad6265SDimitry Andric const MCDisassembler *Decoder); 1470b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm, 1480b57cec5SDimitry Andric uint64_t Addr, 14981ad6265SDimitry Andric const MCDisassembler *Decoder); 1500b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm, 15181ad6265SDimitry Andric uint64_t Addr, 15281ad6265SDimitry Andric const MCDisassembler *Decoder); 1530b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm, 1540b57cec5SDimitry Andric uint64_t Addr, 15581ad6265SDimitry Andric const MCDisassembler *Decoder); 1560b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm, 15781ad6265SDimitry Andric uint64_t Addr, 15881ad6265SDimitry Andric const MCDisassembler *Decoder); 1590b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm, 1600b57cec5SDimitry Andric uint64_t Addr, 16181ad6265SDimitry Andric const MCDisassembler *Decoder); 1620b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm, 16381ad6265SDimitry Andric uint64_t Addr, 16481ad6265SDimitry Andric const MCDisassembler *Decoder); 1650b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm, 16681ad6265SDimitry Andric uint64_t Addr, 16781ad6265SDimitry Andric const MCDisassembler *Decoder); 1680b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm, 16981ad6265SDimitry Andric uint64_t Addr, 17081ad6265SDimitry Andric const MCDisassembler *Decoder); 1710b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm, 17281ad6265SDimitry Andric uint64_t Addr, 17381ad6265SDimitry Andric const MCDisassembler *Decoder); 1740b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm, 1750b57cec5SDimitry Andric uint64_t Addr, 17681ad6265SDimitry Andric const MCDisassembler *Decoder); 17781ad6265SDimitry Andric static DecodeStatus 17881ad6265SDimitry Andric DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, 17981ad6265SDimitry Andric const MCDisassembler *Decoder); 18081ad6265SDimitry Andric static DecodeStatus 18181ad6265SDimitry Andric DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, 18281ad6265SDimitry Andric const MCDisassembler *Decoder); 183bdd1243dSDimitry Andric static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn, 184bdd1243dSDimitry Andric uint64_t Addr, 185bdd1243dSDimitry Andric const MCDisassembler *Decoder); 18681ad6265SDimitry Andric static DecodeStatus 18781ad6265SDimitry Andric DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Address, 18881ad6265SDimitry Andric const MCDisassembler *Decoder); 1890b57cec5SDimitry Andric template <int Bits> 190349cc55cSDimitry Andric static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address, 19181ad6265SDimitry Andric const MCDisassembler *Decoder); 1920b57cec5SDimitry Andric template <int ElementWidth> 19381ad6265SDimitry Andric static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr, 19481ad6265SDimitry Andric const MCDisassembler *Decoder); 1950b57cec5SDimitry Andric static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm, 19681ad6265SDimitry Andric uint64_t Addr, 19781ad6265SDimitry Andric const MCDisassembler *Decoder); 198fe6060f1SDimitry Andric static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address, 19981ad6265SDimitry Andric const MCDisassembler *Decoder); 20004eeddc0SDimitry Andric static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn, 20104eeddc0SDimitry Andric uint64_t Addr, 20281ad6265SDimitry Andric const MCDisassembler *Decoder); 20304eeddc0SDimitry Andric static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn, 20404eeddc0SDimitry Andric uint64_t Addr, 20581ad6265SDimitry Andric const MCDisassembler *Decoder); 206bdd1243dSDimitry Andric static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn, 207bdd1243dSDimitry Andric uint64_t Address, 208bdd1243dSDimitry Andric const MCDisassembler *Decoder); 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric #include "AArch64GenDisassemblerTables.inc" 2110b57cec5SDimitry Andric #include "AArch64GenInstrInfo.inc" 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric #define Success MCDisassembler::Success 2140b57cec5SDimitry Andric #define Fail MCDisassembler::Fail 2150b57cec5SDimitry Andric #define SoftFail MCDisassembler::SoftFail 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric static MCDisassembler *createAArch64Disassembler(const Target &T, 2180b57cec5SDimitry Andric const MCSubtargetInfo &STI, 2190b57cec5SDimitry Andric MCContext &Ctx) { 22081ad6265SDimitry Andric 22181ad6265SDimitry Andric return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo()); 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size, 2250b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes, 2260b57cec5SDimitry Andric uint64_t Address, 2270b57cec5SDimitry Andric raw_ostream &CS) const { 2280b57cec5SDimitry Andric CommentStream = &CS; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric Size = 0; 2310b57cec5SDimitry Andric // We want to read exactly 4 bytes of data. 2320b57cec5SDimitry Andric if (Bytes.size() < 4) 2330b57cec5SDimitry Andric return Fail; 2340b57cec5SDimitry Andric Size = 4; 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric // Encoded as a small-endian 32-bit word in the stream. 2370b57cec5SDimitry Andric uint32_t Insn = 2380b57cec5SDimitry Andric (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0); 2390b57cec5SDimitry Andric 240e8d8bef9SDimitry Andric const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32}; 241e8d8bef9SDimitry Andric 242bdd1243dSDimitry Andric for (const auto *Table : Tables) { 243e8d8bef9SDimitry Andric DecodeStatus Result = 244e8d8bef9SDimitry Andric decodeInstruction(Table, MI, Insn, Address, this, STI); 245fe6060f1SDimitry Andric 24681ad6265SDimitry Andric const MCInstrDesc &Desc = MCII->get(MI.getOpcode()); 24781ad6265SDimitry Andric 24881ad6265SDimitry Andric // For Scalable Matrix Extension (SME) instructions that have an implicit 24981ad6265SDimitry Andric // operand for the accumulator (ZA) or implicit immediate zero which isn't 25081ad6265SDimitry Andric // encoded, manually insert operand. 25181ad6265SDimitry Andric for (unsigned i = 0; i < Desc.getNumOperands(); i++) { 252bdd1243dSDimitry Andric if (Desc.operands()[i].OperandType == MCOI::OPERAND_REGISTER) { 253bdd1243dSDimitry Andric switch (Desc.operands()[i].RegClass) { 254fe6060f1SDimitry Andric default: 255fe6060f1SDimitry Andric break; 25681ad6265SDimitry Andric case AArch64::MPRRegClassID: 25781ad6265SDimitry Andric MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZA)); 25881ad6265SDimitry Andric break; 25981ad6265SDimitry Andric case AArch64::MPR8RegClassID: 26081ad6265SDimitry Andric MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0)); 26181ad6265SDimitry Andric break; 262bdd1243dSDimitry Andric case AArch64::ZTRRegClassID: 263bdd1243dSDimitry Andric MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0)); 264bdd1243dSDimitry Andric break; 26581ad6265SDimitry Andric } 266bdd1243dSDimitry Andric } else if (Desc.operands()[i].OperandType == 26781ad6265SDimitry Andric AArch64::OPERAND_IMPLICIT_IMM_0) { 26881ad6265SDimitry Andric MI.insert(MI.begin() + i, MCOperand::createImm(0)); 26981ad6265SDimitry Andric } 27081ad6265SDimitry Andric } 27181ad6265SDimitry Andric 27281ad6265SDimitry Andric if (MI.getOpcode() == AArch64::LDR_ZA || 27381ad6265SDimitry Andric MI.getOpcode() == AArch64::STR_ZA) { 27481ad6265SDimitry Andric // Spill and fill instructions have a single immediate used for both 27581ad6265SDimitry Andric // the vector select offset and optional memory offset. Replicate 27681ad6265SDimitry Andric // the decoded immediate. 277fe6060f1SDimitry Andric const MCOperand &Imm4Op = MI.getOperand(2); 278fe6060f1SDimitry Andric assert(Imm4Op.isImm() && "Unexpected operand type!"); 279fe6060f1SDimitry Andric MI.addOperand(Imm4Op); 280fe6060f1SDimitry Andric } 281fe6060f1SDimitry Andric 282e8d8bef9SDimitry Andric if (Result != MCDisassembler::Fail) 283e8d8bef9SDimitry Andric return Result; 284e8d8bef9SDimitry Andric } 285e8d8bef9SDimitry Andric 286e8d8bef9SDimitry Andric return MCDisassembler::Fail; 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 289972a253aSDimitry Andric uint64_t AArch64Disassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes, 290972a253aSDimitry Andric uint64_t Address) const { 291972a253aSDimitry Andric // AArch64 instructions are always 4 bytes wide, so there's no point 292972a253aSDimitry Andric // in skipping any smaller number of bytes if an instruction can't 293972a253aSDimitry Andric // be decoded. 294972a253aSDimitry Andric return 4; 295972a253aSDimitry Andric } 296972a253aSDimitry Andric 2970b57cec5SDimitry Andric static MCSymbolizer * 2980b57cec5SDimitry Andric createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo, 2990b57cec5SDimitry Andric LLVMSymbolLookupCallback SymbolLookUp, 3000b57cec5SDimitry Andric void *DisInfo, MCContext *Ctx, 3010b57cec5SDimitry Andric std::unique_ptr<MCRelocationInfo> &&RelInfo) { 3020b57cec5SDimitry Andric return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo, 3030b57cec5SDimitry Andric SymbolLookUp, DisInfo); 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 306480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Disassembler() { 3070b57cec5SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheAArch64leTarget(), 3080b57cec5SDimitry Andric createAArch64Disassembler); 3090b57cec5SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheAArch64beTarget(), 3100b57cec5SDimitry Andric createAArch64Disassembler); 3110b57cec5SDimitry Andric TargetRegistry::RegisterMCSymbolizer(getTheAArch64leTarget(), 3120b57cec5SDimitry Andric createAArch64ExternalSymbolizer); 3130b57cec5SDimitry Andric TargetRegistry::RegisterMCSymbolizer(getTheAArch64beTarget(), 3140b57cec5SDimitry Andric createAArch64ExternalSymbolizer); 3150b57cec5SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheAArch64_32Target(), 3160b57cec5SDimitry Andric createAArch64Disassembler); 3170b57cec5SDimitry Andric TargetRegistry::RegisterMCSymbolizer(getTheAArch64_32Target(), 3180b57cec5SDimitry Andric createAArch64ExternalSymbolizer); 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheARM64Target(), 3210b57cec5SDimitry Andric createAArch64Disassembler); 3220b57cec5SDimitry Andric TargetRegistry::RegisterMCSymbolizer(getTheARM64Target(), 3230b57cec5SDimitry Andric createAArch64ExternalSymbolizer); 3240b57cec5SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheARM64_32Target(), 3250b57cec5SDimitry Andric createAArch64Disassembler); 3260b57cec5SDimitry Andric TargetRegistry::RegisterMCSymbolizer(getTheARM64_32Target(), 3270b57cec5SDimitry Andric createAArch64ExternalSymbolizer); 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 330*0fca6ea1SDimitry Andric template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass> 331*0fca6ea1SDimitry Andric static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo, 332*0fca6ea1SDimitry Andric uint64_t Address, 33381ad6265SDimitry Andric const MCDisassembler *Decoder) { 334*0fca6ea1SDimitry Andric if (RegNo > NumRegsInClass - 1) 3350b57cec5SDimitry Andric return Fail; 3360b57cec5SDimitry Andric 337349cc55cSDimitry Andric unsigned Register = 338*0fca6ea1SDimitry Andric AArch64MCRegisterClasses[RegClassID].getRegister(RegNo + FirstReg); 3390b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(Register)); 3400b57cec5SDimitry Andric return Success; 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 34381ad6265SDimitry Andric static DecodeStatus 34481ad6265SDimitry Andric DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, 34581ad6265SDimitry Andric const MCDisassembler *Decoder) { 346e8d8bef9SDimitry Andric if (RegNo > 22) 347e8d8bef9SDimitry Andric return Fail; 348e8d8bef9SDimitry Andric if (RegNo & 1) 349e8d8bef9SDimitry Andric return Fail; 350e8d8bef9SDimitry Andric 351349cc55cSDimitry Andric unsigned Register = 352349cc55cSDimitry Andric AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].getRegister( 353349cc55cSDimitry Andric RegNo >> 1); 354e8d8bef9SDimitry Andric Inst.addOperand(MCOperand::createReg(Register)); 355e8d8bef9SDimitry Andric return Success; 356e8d8bef9SDimitry Andric } 357e8d8bef9SDimitry Andric 358bdd1243dSDimitry Andric static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo, 359bdd1243dSDimitry Andric uint64_t Address, 360bdd1243dSDimitry Andric const void *Decoder) { 361bdd1243dSDimitry Andric if (RegNo * 2 > 30) 362bdd1243dSDimitry Andric return Fail; 363bdd1243dSDimitry Andric unsigned Register = 364bdd1243dSDimitry Andric AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(RegNo * 2); 365bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createReg(Register)); 366bdd1243dSDimitry Andric return Success; 367bdd1243dSDimitry Andric } 368bdd1243dSDimitry Andric 369bdd1243dSDimitry Andric static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo, 370bdd1243dSDimitry Andric uint64_t Address, 371bdd1243dSDimitry Andric const void *Decoder) { 372bdd1243dSDimitry Andric if (RegNo * 4 > 28) 373bdd1243dSDimitry Andric return Fail; 374bdd1243dSDimitry Andric unsigned Register = 375bdd1243dSDimitry Andric AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(RegNo * 4); 376bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createReg(Register)); 377bdd1243dSDimitry Andric return Success; 378bdd1243dSDimitry Andric } 379bdd1243dSDimitry Andric 38081ad6265SDimitry Andric static DecodeStatus 38181ad6265SDimitry Andric DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask, 382fe6060f1SDimitry Andric uint64_t Address, 38381ad6265SDimitry Andric const MCDisassembler *Decoder) { 384fe6060f1SDimitry Andric if (RegMask > 0xFF) 385fe6060f1SDimitry Andric return Fail; 386fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createImm(RegMask)); 387fe6060f1SDimitry Andric return Success; 388fe6060f1SDimitry Andric } 389fe6060f1SDimitry Andric 39006c3fb27SDimitry Andric static const MCPhysReg MatrixZATileDecoderTable[5][16] = { 391fe6060f1SDimitry Andric {AArch64::ZAB0}, 392fe6060f1SDimitry Andric {AArch64::ZAH0, AArch64::ZAH1}, 393fe6060f1SDimitry Andric {AArch64::ZAS0, AArch64::ZAS1, AArch64::ZAS2, AArch64::ZAS3}, 39406c3fb27SDimitry Andric {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3, AArch64::ZAD4, 39506c3fb27SDimitry Andric AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}, 39606c3fb27SDimitry Andric {AArch64::ZAQ0, AArch64::ZAQ1, AArch64::ZAQ2, AArch64::ZAQ3, AArch64::ZAQ4, 39706c3fb27SDimitry Andric AArch64::ZAQ5, AArch64::ZAQ6, AArch64::ZAQ7, AArch64::ZAQ8, AArch64::ZAQ9, 39806c3fb27SDimitry Andric AArch64::ZAQ10, AArch64::ZAQ11, AArch64::ZAQ12, AArch64::ZAQ13, 39906c3fb27SDimitry Andric AArch64::ZAQ14, AArch64::ZAQ15}}; 400fe6060f1SDimitry Andric 401fe6060f1SDimitry Andric template <unsigned NumBitsForTile> 402fe6060f1SDimitry Andric static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo, 40381ad6265SDimitry Andric uint64_t Address, 40481ad6265SDimitry Andric const MCDisassembler *Decoder) { 405fe6060f1SDimitry Andric unsigned LastReg = (1 << NumBitsForTile) - 1; 406fe6060f1SDimitry Andric if (RegNo > LastReg) 407fe6060f1SDimitry Andric return Fail; 408fe6060f1SDimitry Andric Inst.addOperand( 409fe6060f1SDimitry Andric MCOperand::createReg(MatrixZATileDecoderTable[NumBitsForTile][RegNo])); 410fe6060f1SDimitry Andric return Success; 411fe6060f1SDimitry Andric } 412fe6060f1SDimitry Andric 413bdd1243dSDimitry Andric static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo, 414bdd1243dSDimitry Andric uint64_t Address, 415bdd1243dSDimitry Andric const void *Decoder) { 416bdd1243dSDimitry Andric if ((RegNo * 2) > 14) 417bdd1243dSDimitry Andric return Fail; 418bdd1243dSDimitry Andric unsigned Register = 419bdd1243dSDimitry Andric AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(RegNo * 2); 420bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createReg(Register)); 421bdd1243dSDimitry Andric return Success; 422bdd1243dSDimitry Andric } 423bdd1243dSDimitry Andric 4240b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm, 4250b57cec5SDimitry Andric uint64_t Addr, 42681ad6265SDimitry Andric const MCDisassembler *Decoder) { 4270b57cec5SDimitry Andric // scale{5} is asserted as 1 in tblgen. 4280b57cec5SDimitry Andric Imm |= 0x20; 4290b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(64 - Imm)); 4300b57cec5SDimitry Andric return Success; 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm, 4340b57cec5SDimitry Andric uint64_t Addr, 43581ad6265SDimitry Andric const MCDisassembler *Decoder) { 4360b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(64 - Imm)); 4370b57cec5SDimitry Andric return Success; 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric 440cb14a3feSDimitry Andric static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm, 441cb14a3feSDimitry Andric uint64_t Addr, 442cb14a3feSDimitry Andric const MCDisassembler *Decoder) { 443cb14a3feSDimitry Andric // Immediate is encoded as the top 16-bits of an unsigned 18-bit negative 444cb14a3feSDimitry Andric // PC-relative offset. 445cb14a3feSDimitry Andric uint64_t ImmVal = Imm; 446647cbc5dSDimitry Andric if (ImmVal > (1 << 16)) 447cb14a3feSDimitry Andric return Fail; 448cb14a3feSDimitry Andric ImmVal = -ImmVal; 449cb14a3feSDimitry Andric if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal << 2), Addr, 450cb14a3feSDimitry Andric /*IsBranch=*/false, 0, 0, 4)) 451cb14a3feSDimitry Andric Inst.addOperand(MCOperand::createImm(ImmVal)); 452cb14a3feSDimitry Andric return Success; 453cb14a3feSDimitry Andric } 454cb14a3feSDimitry Andric 4550b57cec5SDimitry Andric static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm, 45681ad6265SDimitry Andric uint64_t Addr, 45781ad6265SDimitry Andric const MCDisassembler *Decoder) { 4580b57cec5SDimitry Andric int64_t ImmVal = Imm; 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric // Sign-extend 19-bit immediate. 4610b57cec5SDimitry Andric if (ImmVal & (1 << (19 - 1))) 4620b57cec5SDimitry Andric ImmVal |= ~((1LL << 19) - 1); 4630b57cec5SDimitry Andric 46481ad6265SDimitry Andric if (!Decoder->tryAddingSymbolicOperand( 46581ad6265SDimitry Andric Inst, ImmVal * 4, Addr, Inst.getOpcode() != AArch64::LDRXl, 0, 0, 4)) 4660b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(ImmVal)); 4670b57cec5SDimitry Andric return Success; 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm, 47181ad6265SDimitry Andric uint64_t Address, 47281ad6265SDimitry Andric const MCDisassembler *Decoder) { 4730b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm((Imm >> 1) & 1)); 4740b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm & 1)); 4750b57cec5SDimitry Andric return Success; 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm, 4790b57cec5SDimitry Andric uint64_t Address, 48081ad6265SDimitry Andric const MCDisassembler *Decoder) { 4810b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm)); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric // Every system register in the encoding space is valid with the syntax 4840b57cec5SDimitry Andric // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds. 4850b57cec5SDimitry Andric return Success; 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric 4880b57cec5SDimitry Andric static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm, 4890b57cec5SDimitry Andric uint64_t Address, 49081ad6265SDimitry Andric const MCDisassembler *Decoder) { 4910b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm)); 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric return Success; 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn, 4970b57cec5SDimitry Andric uint64_t Address, 49881ad6265SDimitry Andric const MCDisassembler *Decoder) { 4990b57cec5SDimitry Andric // This decoder exists to add the dummy Lane operand to the MCInst, which must 5000b57cec5SDimitry Andric // be 1 in assembly but has no other real manifestation. 5010b57cec5SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 0, 5); 5020b57cec5SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 5, 5); 5030b57cec5SDimitry Andric unsigned IsToVec = fieldFromInstruction(Insn, 16, 1); 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric if (IsToVec) { 506*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>( 507*0fca6ea1SDimitry Andric Inst, Rd, Address, Decoder); 508*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>( 509*0fca6ea1SDimitry Andric Inst, Rn, Address, Decoder); 5100b57cec5SDimitry Andric } else { 511*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>( 512*0fca6ea1SDimitry Andric Inst, Rd, Address, Decoder); 513*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>( 514*0fca6ea1SDimitry Andric Inst, Rn, Address, Decoder); 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric // Add the lane 5180b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(1)); 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric return Success; 5210b57cec5SDimitry Andric } 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm, 5240b57cec5SDimitry Andric unsigned Add) { 5250b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Add - Imm)); 5260b57cec5SDimitry Andric return Success; 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm, 5300b57cec5SDimitry Andric unsigned Add) { 5310b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm((Imm + Add) & (Add - 1))); 5320b57cec5SDimitry Andric return Success; 5330b57cec5SDimitry Andric } 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm, 53681ad6265SDimitry Andric uint64_t Addr, 53781ad6265SDimitry Andric const MCDisassembler *Decoder) { 5380b57cec5SDimitry Andric return DecodeVecShiftRImm(Inst, Imm, 64); 5390b57cec5SDimitry Andric } 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm, 5420b57cec5SDimitry Andric uint64_t Addr, 54381ad6265SDimitry Andric const MCDisassembler *Decoder) { 5440b57cec5SDimitry Andric return DecodeVecShiftRImm(Inst, Imm | 0x20, 64); 5450b57cec5SDimitry Andric } 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm, 54881ad6265SDimitry Andric uint64_t Addr, 54981ad6265SDimitry Andric const MCDisassembler *Decoder) { 5500b57cec5SDimitry Andric return DecodeVecShiftRImm(Inst, Imm, 32); 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm, 5540b57cec5SDimitry Andric uint64_t Addr, 55581ad6265SDimitry Andric const MCDisassembler *Decoder) { 5560b57cec5SDimitry Andric return DecodeVecShiftRImm(Inst, Imm | 0x10, 32); 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm, 56081ad6265SDimitry Andric uint64_t Addr, 56181ad6265SDimitry Andric const MCDisassembler *Decoder) { 5620b57cec5SDimitry Andric return DecodeVecShiftRImm(Inst, Imm, 16); 5630b57cec5SDimitry Andric } 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm, 5660b57cec5SDimitry Andric uint64_t Addr, 56781ad6265SDimitry Andric const MCDisassembler *Decoder) { 5680b57cec5SDimitry Andric return DecodeVecShiftRImm(Inst, Imm | 0x8, 16); 5690b57cec5SDimitry Andric } 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm, 57281ad6265SDimitry Andric uint64_t Addr, 57381ad6265SDimitry Andric const MCDisassembler *Decoder) { 5740b57cec5SDimitry Andric return DecodeVecShiftRImm(Inst, Imm, 8); 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm, 57881ad6265SDimitry Andric uint64_t Addr, 57981ad6265SDimitry Andric const MCDisassembler *Decoder) { 5800b57cec5SDimitry Andric return DecodeVecShiftLImm(Inst, Imm, 64); 5810b57cec5SDimitry Andric } 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm, 58481ad6265SDimitry Andric uint64_t Addr, 58581ad6265SDimitry Andric const MCDisassembler *Decoder) { 5860b57cec5SDimitry Andric return DecodeVecShiftLImm(Inst, Imm, 32); 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm, 59081ad6265SDimitry Andric uint64_t Addr, 59181ad6265SDimitry Andric const MCDisassembler *Decoder) { 5920b57cec5SDimitry Andric return DecodeVecShiftLImm(Inst, Imm, 16); 5930b57cec5SDimitry Andric } 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm, 59681ad6265SDimitry Andric uint64_t Addr, 59781ad6265SDimitry Andric const MCDisassembler *Decoder) { 5980b57cec5SDimitry Andric return DecodeVecShiftLImm(Inst, Imm, 8); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric 60181ad6265SDimitry Andric static DecodeStatus 60281ad6265SDimitry Andric DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, 60381ad6265SDimitry Andric const MCDisassembler *Decoder) { 6040b57cec5SDimitry Andric unsigned Rd = fieldFromInstruction(insn, 0, 5); 6050b57cec5SDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 6060b57cec5SDimitry Andric unsigned Rm = fieldFromInstruction(insn, 16, 5); 6070b57cec5SDimitry Andric unsigned shiftHi = fieldFromInstruction(insn, 22, 2); 6080b57cec5SDimitry Andric unsigned shiftLo = fieldFromInstruction(insn, 10, 6); 6090b57cec5SDimitry Andric unsigned shift = (shiftHi << 6) | shiftLo; 6100b57cec5SDimitry Andric switch (Inst.getOpcode()) { 6110b57cec5SDimitry Andric default: 6120b57cec5SDimitry Andric return Fail; 6130b57cec5SDimitry Andric case AArch64::ADDWrs: 6140b57cec5SDimitry Andric case AArch64::ADDSWrs: 6150b57cec5SDimitry Andric case AArch64::SUBWrs: 6160b57cec5SDimitry Andric case AArch64::SUBSWrs: 6170b57cec5SDimitry Andric // if shift == '11' then ReservedValue() 6180b57cec5SDimitry Andric if (shiftHi == 0x3) 6190b57cec5SDimitry Andric return Fail; 620bdd1243dSDimitry Andric [[fallthrough]]; 6210b57cec5SDimitry Andric case AArch64::ANDWrs: 6220b57cec5SDimitry Andric case AArch64::ANDSWrs: 6230b57cec5SDimitry Andric case AArch64::BICWrs: 6240b57cec5SDimitry Andric case AArch64::BICSWrs: 6250b57cec5SDimitry Andric case AArch64::ORRWrs: 6260b57cec5SDimitry Andric case AArch64::ORNWrs: 6270b57cec5SDimitry Andric case AArch64::EORWrs: 6280b57cec5SDimitry Andric case AArch64::EONWrs: { 6290b57cec5SDimitry Andric // if sf == '0' and imm6<5> == '1' then ReservedValue() 6300b57cec5SDimitry Andric if (shiftLo >> 5 == 1) 6310b57cec5SDimitry Andric return Fail; 632*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr, 633*0fca6ea1SDimitry Andric Decoder); 634*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rn, Addr, 635*0fca6ea1SDimitry Andric Decoder); 636*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr, 637*0fca6ea1SDimitry Andric Decoder); 6380b57cec5SDimitry Andric break; 6390b57cec5SDimitry Andric } 6400b57cec5SDimitry Andric case AArch64::ADDXrs: 6410b57cec5SDimitry Andric case AArch64::ADDSXrs: 6420b57cec5SDimitry Andric case AArch64::SUBXrs: 6430b57cec5SDimitry Andric case AArch64::SUBSXrs: 6440b57cec5SDimitry Andric // if shift == '11' then ReservedValue() 6450b57cec5SDimitry Andric if (shiftHi == 0x3) 6460b57cec5SDimitry Andric return Fail; 647bdd1243dSDimitry Andric [[fallthrough]]; 6480b57cec5SDimitry Andric case AArch64::ANDXrs: 6490b57cec5SDimitry Andric case AArch64::ANDSXrs: 6500b57cec5SDimitry Andric case AArch64::BICXrs: 6510b57cec5SDimitry Andric case AArch64::BICSXrs: 6520b57cec5SDimitry Andric case AArch64::ORRXrs: 6530b57cec5SDimitry Andric case AArch64::ORNXrs: 6540b57cec5SDimitry Andric case AArch64::EORXrs: 6550b57cec5SDimitry Andric case AArch64::EONXrs: 656*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr, 657*0fca6ea1SDimitry Andric Decoder); 658*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rn, Addr, 659*0fca6ea1SDimitry Andric Decoder); 660*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr, 661*0fca6ea1SDimitry Andric Decoder); 6620b57cec5SDimitry Andric break; 6630b57cec5SDimitry Andric } 6640b57cec5SDimitry Andric 6650b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(shift)); 6660b57cec5SDimitry Andric return Success; 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric 6690b57cec5SDimitry Andric static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn, 6700b57cec5SDimitry Andric uint64_t Addr, 67181ad6265SDimitry Andric const MCDisassembler *Decoder) { 6720b57cec5SDimitry Andric unsigned Rd = fieldFromInstruction(insn, 0, 5); 6730b57cec5SDimitry Andric unsigned imm = fieldFromInstruction(insn, 5, 16); 6740b57cec5SDimitry Andric unsigned shift = fieldFromInstruction(insn, 21, 2); 6750b57cec5SDimitry Andric shift <<= 4; 6760b57cec5SDimitry Andric switch (Inst.getOpcode()) { 6770b57cec5SDimitry Andric default: 6780b57cec5SDimitry Andric return Fail; 6790b57cec5SDimitry Andric case AArch64::MOVZWi: 6800b57cec5SDimitry Andric case AArch64::MOVNWi: 6810b57cec5SDimitry Andric case AArch64::MOVKWi: 6820b57cec5SDimitry Andric if (shift & (1U << 5)) 6830b57cec5SDimitry Andric return Fail; 684*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr, 685*0fca6ea1SDimitry Andric Decoder); 6860b57cec5SDimitry Andric break; 6870b57cec5SDimitry Andric case AArch64::MOVZXi: 6880b57cec5SDimitry Andric case AArch64::MOVNXi: 6890b57cec5SDimitry Andric case AArch64::MOVKXi: 690*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr, 691*0fca6ea1SDimitry Andric Decoder); 6920b57cec5SDimitry Andric break; 6930b57cec5SDimitry Andric } 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric if (Inst.getOpcode() == AArch64::MOVKWi || 6960b57cec5SDimitry Andric Inst.getOpcode() == AArch64::MOVKXi) 6970b57cec5SDimitry Andric Inst.addOperand(Inst.getOperand(0)); 6980b57cec5SDimitry Andric 6990b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(imm)); 7000b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(shift)); 7010b57cec5SDimitry Andric return Success; 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric 70481ad6265SDimitry Andric static DecodeStatus 70581ad6265SDimitry Andric DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, 70681ad6265SDimitry Andric const MCDisassembler *Decoder) { 7070b57cec5SDimitry Andric unsigned Rt = fieldFromInstruction(insn, 0, 5); 7080b57cec5SDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 7090b57cec5SDimitry Andric unsigned offset = fieldFromInstruction(insn, 10, 12); 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric switch (Inst.getOpcode()) { 7120b57cec5SDimitry Andric default: 7130b57cec5SDimitry Andric return Fail; 7140b57cec5SDimitry Andric case AArch64::PRFMui: 7150b57cec5SDimitry Andric // Rt is an immediate in prefetch. 7160b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Rt)); 7170b57cec5SDimitry Andric break; 7180b57cec5SDimitry Andric case AArch64::STRBBui: 7190b57cec5SDimitry Andric case AArch64::LDRBBui: 7200b57cec5SDimitry Andric case AArch64::LDRSBWui: 7210b57cec5SDimitry Andric case AArch64::STRHHui: 7220b57cec5SDimitry Andric case AArch64::LDRHHui: 7230b57cec5SDimitry Andric case AArch64::LDRSHWui: 7240b57cec5SDimitry Andric case AArch64::STRWui: 7250b57cec5SDimitry Andric case AArch64::LDRWui: 726*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr, 727*0fca6ea1SDimitry Andric Decoder); 7280b57cec5SDimitry Andric break; 7290b57cec5SDimitry Andric case AArch64::LDRSBXui: 7300b57cec5SDimitry Andric case AArch64::LDRSHXui: 7310b57cec5SDimitry Andric case AArch64::LDRSWui: 7320b57cec5SDimitry Andric case AArch64::STRXui: 7330b57cec5SDimitry Andric case AArch64::LDRXui: 734*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr, 735*0fca6ea1SDimitry Andric Decoder); 7360b57cec5SDimitry Andric break; 7370b57cec5SDimitry Andric case AArch64::LDRQui: 7380b57cec5SDimitry Andric case AArch64::STRQui: 739*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr, 740*0fca6ea1SDimitry Andric Decoder); 7410b57cec5SDimitry Andric break; 7420b57cec5SDimitry Andric case AArch64::LDRDui: 7430b57cec5SDimitry Andric case AArch64::STRDui: 744*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr, 745*0fca6ea1SDimitry Andric Decoder); 7460b57cec5SDimitry Andric break; 7470b57cec5SDimitry Andric case AArch64::LDRSui: 7480b57cec5SDimitry Andric case AArch64::STRSui: 749*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr, 750*0fca6ea1SDimitry Andric Decoder); 7510b57cec5SDimitry Andric break; 7520b57cec5SDimitry Andric case AArch64::LDRHui: 7530b57cec5SDimitry Andric case AArch64::STRHui: 754*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>(Inst, Rt, Addr, 755*0fca6ea1SDimitry Andric Decoder); 7560b57cec5SDimitry Andric break; 7570b57cec5SDimitry Andric case AArch64::LDRBui: 7580b57cec5SDimitry Andric case AArch64::STRBui: 759*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>(Inst, Rt, Addr, 760*0fca6ea1SDimitry Andric Decoder); 7610b57cec5SDimitry Andric break; 7620b57cec5SDimitry Andric } 7630b57cec5SDimitry Andric 764*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 765*0fca6ea1SDimitry Andric Decoder); 76681ad6265SDimitry Andric if (!Decoder->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 0, 4)) 7670b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(offset)); 7680b57cec5SDimitry Andric return Success; 7690b57cec5SDimitry Andric } 7700b57cec5SDimitry Andric 7710b57cec5SDimitry Andric static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn, 7720b57cec5SDimitry Andric uint64_t Addr, 77381ad6265SDimitry Andric const MCDisassembler *Decoder) { 7740b57cec5SDimitry Andric unsigned Rt = fieldFromInstruction(insn, 0, 5); 7750b57cec5SDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 7760b57cec5SDimitry Andric int64_t offset = fieldFromInstruction(insn, 12, 9); 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric // offset is a 9-bit signed immediate, so sign extend it to 7790b57cec5SDimitry Andric // fill the unsigned. 7800b57cec5SDimitry Andric if (offset & (1 << (9 - 1))) 7810b57cec5SDimitry Andric offset |= ~((1LL << 9) - 1); 7820b57cec5SDimitry Andric 7830b57cec5SDimitry Andric // First operand is always the writeback to the address register, if needed. 7840b57cec5SDimitry Andric switch (Inst.getOpcode()) { 7850b57cec5SDimitry Andric default: 7860b57cec5SDimitry Andric break; 7870b57cec5SDimitry Andric case AArch64::LDRSBWpre: 7880b57cec5SDimitry Andric case AArch64::LDRSHWpre: 7890b57cec5SDimitry Andric case AArch64::STRBBpre: 7900b57cec5SDimitry Andric case AArch64::LDRBBpre: 7910b57cec5SDimitry Andric case AArch64::STRHHpre: 7920b57cec5SDimitry Andric case AArch64::LDRHHpre: 7930b57cec5SDimitry Andric case AArch64::STRWpre: 7940b57cec5SDimitry Andric case AArch64::LDRWpre: 7950b57cec5SDimitry Andric case AArch64::LDRSBWpost: 7960b57cec5SDimitry Andric case AArch64::LDRSHWpost: 7970b57cec5SDimitry Andric case AArch64::STRBBpost: 7980b57cec5SDimitry Andric case AArch64::LDRBBpost: 7990b57cec5SDimitry Andric case AArch64::STRHHpost: 8000b57cec5SDimitry Andric case AArch64::LDRHHpost: 8010b57cec5SDimitry Andric case AArch64::STRWpost: 8020b57cec5SDimitry Andric case AArch64::LDRWpost: 8030b57cec5SDimitry Andric case AArch64::LDRSBXpre: 8040b57cec5SDimitry Andric case AArch64::LDRSHXpre: 8050b57cec5SDimitry Andric case AArch64::STRXpre: 8060b57cec5SDimitry Andric case AArch64::LDRSWpre: 8070b57cec5SDimitry Andric case AArch64::LDRXpre: 8080b57cec5SDimitry Andric case AArch64::LDRSBXpost: 8090b57cec5SDimitry Andric case AArch64::LDRSHXpost: 8100b57cec5SDimitry Andric case AArch64::STRXpost: 8110b57cec5SDimitry Andric case AArch64::LDRSWpost: 8120b57cec5SDimitry Andric case AArch64::LDRXpost: 8130b57cec5SDimitry Andric case AArch64::LDRQpre: 8140b57cec5SDimitry Andric case AArch64::STRQpre: 8150b57cec5SDimitry Andric case AArch64::LDRQpost: 8160b57cec5SDimitry Andric case AArch64::STRQpost: 8170b57cec5SDimitry Andric case AArch64::LDRDpre: 8180b57cec5SDimitry Andric case AArch64::STRDpre: 8190b57cec5SDimitry Andric case AArch64::LDRDpost: 8200b57cec5SDimitry Andric case AArch64::STRDpost: 8210b57cec5SDimitry Andric case AArch64::LDRSpre: 8220b57cec5SDimitry Andric case AArch64::STRSpre: 8230b57cec5SDimitry Andric case AArch64::LDRSpost: 8240b57cec5SDimitry Andric case AArch64::STRSpost: 8250b57cec5SDimitry Andric case AArch64::LDRHpre: 8260b57cec5SDimitry Andric case AArch64::STRHpre: 8270b57cec5SDimitry Andric case AArch64::LDRHpost: 8280b57cec5SDimitry Andric case AArch64::STRHpost: 8290b57cec5SDimitry Andric case AArch64::LDRBpre: 8300b57cec5SDimitry Andric case AArch64::STRBpre: 8310b57cec5SDimitry Andric case AArch64::LDRBpost: 8320b57cec5SDimitry Andric case AArch64::STRBpost: 833*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 834*0fca6ea1SDimitry Andric Decoder); 8350b57cec5SDimitry Andric break; 8360b57cec5SDimitry Andric } 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andric switch (Inst.getOpcode()) { 8390b57cec5SDimitry Andric default: 8400b57cec5SDimitry Andric return Fail; 8410b57cec5SDimitry Andric case AArch64::PRFUMi: 8420b57cec5SDimitry Andric // Rt is an immediate in prefetch. 8430b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Rt)); 8440b57cec5SDimitry Andric break; 8450b57cec5SDimitry Andric case AArch64::STURBBi: 8460b57cec5SDimitry Andric case AArch64::LDURBBi: 8470b57cec5SDimitry Andric case AArch64::LDURSBWi: 8480b57cec5SDimitry Andric case AArch64::STURHHi: 8490b57cec5SDimitry Andric case AArch64::LDURHHi: 8500b57cec5SDimitry Andric case AArch64::LDURSHWi: 8510b57cec5SDimitry Andric case AArch64::STURWi: 8520b57cec5SDimitry Andric case AArch64::LDURWi: 8530b57cec5SDimitry Andric case AArch64::LDTRSBWi: 8540b57cec5SDimitry Andric case AArch64::LDTRSHWi: 8550b57cec5SDimitry Andric case AArch64::STTRWi: 8560b57cec5SDimitry Andric case AArch64::LDTRWi: 8570b57cec5SDimitry Andric case AArch64::STTRHi: 8580b57cec5SDimitry Andric case AArch64::LDTRHi: 8590b57cec5SDimitry Andric case AArch64::LDTRBi: 8600b57cec5SDimitry Andric case AArch64::STTRBi: 8610b57cec5SDimitry Andric case AArch64::LDRSBWpre: 8620b57cec5SDimitry Andric case AArch64::LDRSHWpre: 8630b57cec5SDimitry Andric case AArch64::STRBBpre: 8640b57cec5SDimitry Andric case AArch64::LDRBBpre: 8650b57cec5SDimitry Andric case AArch64::STRHHpre: 8660b57cec5SDimitry Andric case AArch64::LDRHHpre: 8670b57cec5SDimitry Andric case AArch64::STRWpre: 8680b57cec5SDimitry Andric case AArch64::LDRWpre: 8690b57cec5SDimitry Andric case AArch64::LDRSBWpost: 8700b57cec5SDimitry Andric case AArch64::LDRSHWpost: 8710b57cec5SDimitry Andric case AArch64::STRBBpost: 8720b57cec5SDimitry Andric case AArch64::LDRBBpost: 8730b57cec5SDimitry Andric case AArch64::STRHHpost: 8740b57cec5SDimitry Andric case AArch64::LDRHHpost: 8750b57cec5SDimitry Andric case AArch64::STRWpost: 8760b57cec5SDimitry Andric case AArch64::LDRWpost: 8770b57cec5SDimitry Andric case AArch64::STLURBi: 8780b57cec5SDimitry Andric case AArch64::STLURHi: 8790b57cec5SDimitry Andric case AArch64::STLURWi: 8800b57cec5SDimitry Andric case AArch64::LDAPURBi: 8810b57cec5SDimitry Andric case AArch64::LDAPURSBWi: 8820b57cec5SDimitry Andric case AArch64::LDAPURHi: 8830b57cec5SDimitry Andric case AArch64::LDAPURSHWi: 8840b57cec5SDimitry Andric case AArch64::LDAPURi: 885*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr, 886*0fca6ea1SDimitry Andric Decoder); 8870b57cec5SDimitry Andric break; 8880b57cec5SDimitry Andric case AArch64::LDURSBXi: 8890b57cec5SDimitry Andric case AArch64::LDURSHXi: 8900b57cec5SDimitry Andric case AArch64::LDURSWi: 8910b57cec5SDimitry Andric case AArch64::STURXi: 8920b57cec5SDimitry Andric case AArch64::LDURXi: 8930b57cec5SDimitry Andric case AArch64::LDTRSBXi: 8940b57cec5SDimitry Andric case AArch64::LDTRSHXi: 8950b57cec5SDimitry Andric case AArch64::LDTRSWi: 8960b57cec5SDimitry Andric case AArch64::STTRXi: 8970b57cec5SDimitry Andric case AArch64::LDTRXi: 8980b57cec5SDimitry Andric case AArch64::LDRSBXpre: 8990b57cec5SDimitry Andric case AArch64::LDRSHXpre: 9000b57cec5SDimitry Andric case AArch64::STRXpre: 9010b57cec5SDimitry Andric case AArch64::LDRSWpre: 9020b57cec5SDimitry Andric case AArch64::LDRXpre: 9030b57cec5SDimitry Andric case AArch64::LDRSBXpost: 9040b57cec5SDimitry Andric case AArch64::LDRSHXpost: 9050b57cec5SDimitry Andric case AArch64::STRXpost: 9060b57cec5SDimitry Andric case AArch64::LDRSWpost: 9070b57cec5SDimitry Andric case AArch64::LDRXpost: 9080b57cec5SDimitry Andric case AArch64::LDAPURSWi: 9090b57cec5SDimitry Andric case AArch64::LDAPURSHXi: 9100b57cec5SDimitry Andric case AArch64::LDAPURSBXi: 9110b57cec5SDimitry Andric case AArch64::STLURXi: 9120b57cec5SDimitry Andric case AArch64::LDAPURXi: 913*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr, 914*0fca6ea1SDimitry Andric Decoder); 9150b57cec5SDimitry Andric break; 9160b57cec5SDimitry Andric case AArch64::LDURQi: 9170b57cec5SDimitry Andric case AArch64::STURQi: 9180b57cec5SDimitry Andric case AArch64::LDRQpre: 9190b57cec5SDimitry Andric case AArch64::STRQpre: 9200b57cec5SDimitry Andric case AArch64::LDRQpost: 9210b57cec5SDimitry Andric case AArch64::STRQpost: 922*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr, 923*0fca6ea1SDimitry Andric Decoder); 9240b57cec5SDimitry Andric break; 9250b57cec5SDimitry Andric case AArch64::LDURDi: 9260b57cec5SDimitry Andric case AArch64::STURDi: 9270b57cec5SDimitry Andric case AArch64::LDRDpre: 9280b57cec5SDimitry Andric case AArch64::STRDpre: 9290b57cec5SDimitry Andric case AArch64::LDRDpost: 9300b57cec5SDimitry Andric case AArch64::STRDpost: 931*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr, 932*0fca6ea1SDimitry Andric Decoder); 9330b57cec5SDimitry Andric break; 9340b57cec5SDimitry Andric case AArch64::LDURSi: 9350b57cec5SDimitry Andric case AArch64::STURSi: 9360b57cec5SDimitry Andric case AArch64::LDRSpre: 9370b57cec5SDimitry Andric case AArch64::STRSpre: 9380b57cec5SDimitry Andric case AArch64::LDRSpost: 9390b57cec5SDimitry Andric case AArch64::STRSpost: 940*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr, 941*0fca6ea1SDimitry Andric Decoder); 9420b57cec5SDimitry Andric break; 9430b57cec5SDimitry Andric case AArch64::LDURHi: 9440b57cec5SDimitry Andric case AArch64::STURHi: 9450b57cec5SDimitry Andric case AArch64::LDRHpre: 9460b57cec5SDimitry Andric case AArch64::STRHpre: 9470b57cec5SDimitry Andric case AArch64::LDRHpost: 9480b57cec5SDimitry Andric case AArch64::STRHpost: 949*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>(Inst, Rt, Addr, 950*0fca6ea1SDimitry Andric Decoder); 9510b57cec5SDimitry Andric break; 9520b57cec5SDimitry Andric case AArch64::LDURBi: 9530b57cec5SDimitry Andric case AArch64::STURBi: 9540b57cec5SDimitry Andric case AArch64::LDRBpre: 9550b57cec5SDimitry Andric case AArch64::STRBpre: 9560b57cec5SDimitry Andric case AArch64::LDRBpost: 9570b57cec5SDimitry Andric case AArch64::STRBpost: 958*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>(Inst, Rt, Addr, 959*0fca6ea1SDimitry Andric Decoder); 9600b57cec5SDimitry Andric break; 9610b57cec5SDimitry Andric } 9620b57cec5SDimitry Andric 963*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 964*0fca6ea1SDimitry Andric Decoder); 9650b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(offset)); 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric bool IsLoad = fieldFromInstruction(insn, 22, 1); 9680b57cec5SDimitry Andric bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0; 9690b57cec5SDimitry Andric bool IsFP = fieldFromInstruction(insn, 26, 1); 9700b57cec5SDimitry Andric 9710b57cec5SDimitry Andric // Cannot write back to a transfer register (but xzr != sp). 9720b57cec5SDimitry Andric if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn) 9730b57cec5SDimitry Andric return SoftFail; 9740b57cec5SDimitry Andric 9750b57cec5SDimitry Andric return Success; 9760b57cec5SDimitry Andric } 9770b57cec5SDimitry Andric 97881ad6265SDimitry Andric static DecodeStatus 97981ad6265SDimitry Andric DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, 98081ad6265SDimitry Andric const MCDisassembler *Decoder) { 9810b57cec5SDimitry Andric unsigned Rt = fieldFromInstruction(insn, 0, 5); 9820b57cec5SDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 9830b57cec5SDimitry Andric unsigned Rt2 = fieldFromInstruction(insn, 10, 5); 9840b57cec5SDimitry Andric unsigned Rs = fieldFromInstruction(insn, 16, 5); 9850b57cec5SDimitry Andric 9860b57cec5SDimitry Andric unsigned Opcode = Inst.getOpcode(); 9870b57cec5SDimitry Andric switch (Opcode) { 9880b57cec5SDimitry Andric default: 9890b57cec5SDimitry Andric return Fail; 9900b57cec5SDimitry Andric case AArch64::STLXRW: 9910b57cec5SDimitry Andric case AArch64::STLXRB: 9920b57cec5SDimitry Andric case AArch64::STLXRH: 9930b57cec5SDimitry Andric case AArch64::STXRW: 9940b57cec5SDimitry Andric case AArch64::STXRB: 9950b57cec5SDimitry Andric case AArch64::STXRH: 996*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr, 997*0fca6ea1SDimitry Andric Decoder); 998bdd1243dSDimitry Andric [[fallthrough]]; 9990b57cec5SDimitry Andric case AArch64::LDARW: 10000b57cec5SDimitry Andric case AArch64::LDARB: 10010b57cec5SDimitry Andric case AArch64::LDARH: 10020b57cec5SDimitry Andric case AArch64::LDAXRW: 10030b57cec5SDimitry Andric case AArch64::LDAXRB: 10040b57cec5SDimitry Andric case AArch64::LDAXRH: 10050b57cec5SDimitry Andric case AArch64::LDXRW: 10060b57cec5SDimitry Andric case AArch64::LDXRB: 10070b57cec5SDimitry Andric case AArch64::LDXRH: 10080b57cec5SDimitry Andric case AArch64::STLRW: 10090b57cec5SDimitry Andric case AArch64::STLRB: 10100b57cec5SDimitry Andric case AArch64::STLRH: 10110b57cec5SDimitry Andric case AArch64::STLLRW: 10120b57cec5SDimitry Andric case AArch64::STLLRB: 10130b57cec5SDimitry Andric case AArch64::STLLRH: 10140b57cec5SDimitry Andric case AArch64::LDLARW: 10150b57cec5SDimitry Andric case AArch64::LDLARB: 10160b57cec5SDimitry Andric case AArch64::LDLARH: 1017*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr, 1018*0fca6ea1SDimitry Andric Decoder); 10190b57cec5SDimitry Andric break; 10200b57cec5SDimitry Andric case AArch64::STLXRX: 10210b57cec5SDimitry Andric case AArch64::STXRX: 1022*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr, 1023*0fca6ea1SDimitry Andric Decoder); 1024bdd1243dSDimitry Andric [[fallthrough]]; 10250b57cec5SDimitry Andric case AArch64::LDARX: 10260b57cec5SDimitry Andric case AArch64::LDAXRX: 10270b57cec5SDimitry Andric case AArch64::LDXRX: 10280b57cec5SDimitry Andric case AArch64::STLRX: 10290b57cec5SDimitry Andric case AArch64::LDLARX: 10300b57cec5SDimitry Andric case AArch64::STLLRX: 1031*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr, 1032*0fca6ea1SDimitry Andric Decoder); 10330b57cec5SDimitry Andric break; 10340b57cec5SDimitry Andric case AArch64::STLXPW: 10350b57cec5SDimitry Andric case AArch64::STXPW: 1036*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr, 1037*0fca6ea1SDimitry Andric Decoder); 1038bdd1243dSDimitry Andric [[fallthrough]]; 10390b57cec5SDimitry Andric case AArch64::LDAXPW: 10400b57cec5SDimitry Andric case AArch64::LDXPW: 1041*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr, 1042*0fca6ea1SDimitry Andric Decoder); 1043*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt2, Addr, 1044*0fca6ea1SDimitry Andric Decoder); 10450b57cec5SDimitry Andric break; 10460b57cec5SDimitry Andric case AArch64::STLXPX: 10470b57cec5SDimitry Andric case AArch64::STXPX: 1048*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr, 1049*0fca6ea1SDimitry Andric Decoder); 1050bdd1243dSDimitry Andric [[fallthrough]]; 10510b57cec5SDimitry Andric case AArch64::LDAXPX: 10520b57cec5SDimitry Andric case AArch64::LDXPX: 1053*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr, 1054*0fca6ea1SDimitry Andric Decoder); 1055*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt2, Addr, 1056*0fca6ea1SDimitry Andric Decoder); 10570b57cec5SDimitry Andric break; 10580b57cec5SDimitry Andric } 10590b57cec5SDimitry Andric 1060*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 1061*0fca6ea1SDimitry Andric Decoder); 10620b57cec5SDimitry Andric 10630b57cec5SDimitry Andric // You shouldn't load to the same register twice in an instruction... 10640b57cec5SDimitry Andric if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW || 10650b57cec5SDimitry Andric Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) && 10660b57cec5SDimitry Andric Rt == Rt2) 10670b57cec5SDimitry Andric return SoftFail; 10680b57cec5SDimitry Andric 10690b57cec5SDimitry Andric return Success; 10700b57cec5SDimitry Andric } 10710b57cec5SDimitry Andric 10720b57cec5SDimitry Andric static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn, 10730b57cec5SDimitry Andric uint64_t Addr, 107481ad6265SDimitry Andric const MCDisassembler *Decoder) { 10750b57cec5SDimitry Andric unsigned Rt = fieldFromInstruction(insn, 0, 5); 10760b57cec5SDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 10770b57cec5SDimitry Andric unsigned Rt2 = fieldFromInstruction(insn, 10, 5); 10780b57cec5SDimitry Andric int64_t offset = fieldFromInstruction(insn, 15, 7); 10790b57cec5SDimitry Andric bool IsLoad = fieldFromInstruction(insn, 22, 1); 10800b57cec5SDimitry Andric 10810b57cec5SDimitry Andric // offset is a 7-bit signed immediate, so sign extend it to 10820b57cec5SDimitry Andric // fill the unsigned. 10830b57cec5SDimitry Andric if (offset & (1 << (7 - 1))) 10840b57cec5SDimitry Andric offset |= ~((1LL << 7) - 1); 10850b57cec5SDimitry Andric 10860b57cec5SDimitry Andric unsigned Opcode = Inst.getOpcode(); 10870b57cec5SDimitry Andric bool NeedsDisjointWritebackTransfer = false; 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andric // First operand is always writeback of base register. 10900b57cec5SDimitry Andric switch (Opcode) { 10910b57cec5SDimitry Andric default: 10920b57cec5SDimitry Andric break; 10930b57cec5SDimitry Andric case AArch64::LDPXpost: 10940b57cec5SDimitry Andric case AArch64::STPXpost: 10950b57cec5SDimitry Andric case AArch64::LDPSWpost: 10960b57cec5SDimitry Andric case AArch64::LDPXpre: 10970b57cec5SDimitry Andric case AArch64::STPXpre: 10980b57cec5SDimitry Andric case AArch64::LDPSWpre: 10990b57cec5SDimitry Andric case AArch64::LDPWpost: 11000b57cec5SDimitry Andric case AArch64::STPWpost: 11010b57cec5SDimitry Andric case AArch64::LDPWpre: 11020b57cec5SDimitry Andric case AArch64::STPWpre: 11030b57cec5SDimitry Andric case AArch64::LDPQpost: 11040b57cec5SDimitry Andric case AArch64::STPQpost: 11050b57cec5SDimitry Andric case AArch64::LDPQpre: 11060b57cec5SDimitry Andric case AArch64::STPQpre: 11070b57cec5SDimitry Andric case AArch64::LDPDpost: 11080b57cec5SDimitry Andric case AArch64::STPDpost: 11090b57cec5SDimitry Andric case AArch64::LDPDpre: 11100b57cec5SDimitry Andric case AArch64::STPDpre: 11110b57cec5SDimitry Andric case AArch64::LDPSpost: 11120b57cec5SDimitry Andric case AArch64::STPSpost: 11130b57cec5SDimitry Andric case AArch64::LDPSpre: 11140b57cec5SDimitry Andric case AArch64::STPSpre: 11150b57cec5SDimitry Andric case AArch64::STGPpre: 11160b57cec5SDimitry Andric case AArch64::STGPpost: 1117*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 1118*0fca6ea1SDimitry Andric Decoder); 11190b57cec5SDimitry Andric break; 11200b57cec5SDimitry Andric } 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric switch (Opcode) { 11230b57cec5SDimitry Andric default: 11240b57cec5SDimitry Andric return Fail; 11250b57cec5SDimitry Andric case AArch64::LDPXpost: 11260b57cec5SDimitry Andric case AArch64::STPXpost: 11270b57cec5SDimitry Andric case AArch64::LDPSWpost: 11280b57cec5SDimitry Andric case AArch64::LDPXpre: 11290b57cec5SDimitry Andric case AArch64::STPXpre: 11300b57cec5SDimitry Andric case AArch64::LDPSWpre: 11310b57cec5SDimitry Andric case AArch64::STGPpre: 11320b57cec5SDimitry Andric case AArch64::STGPpost: 11330b57cec5SDimitry Andric NeedsDisjointWritebackTransfer = true; 1134bdd1243dSDimitry Andric [[fallthrough]]; 11350b57cec5SDimitry Andric case AArch64::LDNPXi: 11360b57cec5SDimitry Andric case AArch64::STNPXi: 11370b57cec5SDimitry Andric case AArch64::LDPXi: 11380b57cec5SDimitry Andric case AArch64::STPXi: 11390b57cec5SDimitry Andric case AArch64::LDPSWi: 11400b57cec5SDimitry Andric case AArch64::STGPi: 1141*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr, 1142*0fca6ea1SDimitry Andric Decoder); 1143*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt2, Addr, 1144*0fca6ea1SDimitry Andric Decoder); 11450b57cec5SDimitry Andric break; 11460b57cec5SDimitry Andric case AArch64::LDPWpost: 11470b57cec5SDimitry Andric case AArch64::STPWpost: 11480b57cec5SDimitry Andric case AArch64::LDPWpre: 11490b57cec5SDimitry Andric case AArch64::STPWpre: 11500b57cec5SDimitry Andric NeedsDisjointWritebackTransfer = true; 1151bdd1243dSDimitry Andric [[fallthrough]]; 11520b57cec5SDimitry Andric case AArch64::LDNPWi: 11530b57cec5SDimitry Andric case AArch64::STNPWi: 11540b57cec5SDimitry Andric case AArch64::LDPWi: 11550b57cec5SDimitry Andric case AArch64::STPWi: 1156*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr, 1157*0fca6ea1SDimitry Andric Decoder); 1158*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt2, Addr, 1159*0fca6ea1SDimitry Andric Decoder); 11600b57cec5SDimitry Andric break; 11610b57cec5SDimitry Andric case AArch64::LDNPQi: 11620b57cec5SDimitry Andric case AArch64::STNPQi: 11630b57cec5SDimitry Andric case AArch64::LDPQpost: 11640b57cec5SDimitry Andric case AArch64::STPQpost: 11650b57cec5SDimitry Andric case AArch64::LDPQi: 11660b57cec5SDimitry Andric case AArch64::STPQi: 11670b57cec5SDimitry Andric case AArch64::LDPQpre: 11680b57cec5SDimitry Andric case AArch64::STPQpre: 1169*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr, 1170*0fca6ea1SDimitry Andric Decoder); 1171*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt2, Addr, 1172*0fca6ea1SDimitry Andric Decoder); 11730b57cec5SDimitry Andric break; 11740b57cec5SDimitry Andric case AArch64::LDNPDi: 11750b57cec5SDimitry Andric case AArch64::STNPDi: 11760b57cec5SDimitry Andric case AArch64::LDPDpost: 11770b57cec5SDimitry Andric case AArch64::STPDpost: 11780b57cec5SDimitry Andric case AArch64::LDPDi: 11790b57cec5SDimitry Andric case AArch64::STPDi: 11800b57cec5SDimitry Andric case AArch64::LDPDpre: 11810b57cec5SDimitry Andric case AArch64::STPDpre: 1182*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr, 1183*0fca6ea1SDimitry Andric Decoder); 1184*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt2, Addr, 1185*0fca6ea1SDimitry Andric Decoder); 11860b57cec5SDimitry Andric break; 11870b57cec5SDimitry Andric case AArch64::LDNPSi: 11880b57cec5SDimitry Andric case AArch64::STNPSi: 11890b57cec5SDimitry Andric case AArch64::LDPSpost: 11900b57cec5SDimitry Andric case AArch64::STPSpost: 11910b57cec5SDimitry Andric case AArch64::LDPSi: 11920b57cec5SDimitry Andric case AArch64::STPSi: 11930b57cec5SDimitry Andric case AArch64::LDPSpre: 11940b57cec5SDimitry Andric case AArch64::STPSpre: 1195*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr, 1196*0fca6ea1SDimitry Andric Decoder); 1197*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt2, Addr, 1198*0fca6ea1SDimitry Andric Decoder); 11990b57cec5SDimitry Andric break; 12000b57cec5SDimitry Andric } 12010b57cec5SDimitry Andric 1202*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 1203*0fca6ea1SDimitry Andric Decoder); 12040b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(offset)); 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric // You shouldn't load to the same register twice in an instruction... 12070b57cec5SDimitry Andric if (IsLoad && Rt == Rt2) 12080b57cec5SDimitry Andric return SoftFail; 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andric // ... or do any operation that writes-back to a transfer register. But note 12110b57cec5SDimitry Andric // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different. 12120b57cec5SDimitry Andric if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn)) 12130b57cec5SDimitry Andric return SoftFail; 12140b57cec5SDimitry Andric 12150b57cec5SDimitry Andric return Success; 12160b57cec5SDimitry Andric } 12170b57cec5SDimitry Andric 12185ffd83dbSDimitry Andric static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn, 12195ffd83dbSDimitry Andric uint64_t Addr, 122081ad6265SDimitry Andric const MCDisassembler *Decoder) { 12215ffd83dbSDimitry Andric unsigned Rt = fieldFromInstruction(insn, 0, 5); 12225ffd83dbSDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 12235ffd83dbSDimitry Andric uint64_t offset = fieldFromInstruction(insn, 22, 1) << 9 | 12245ffd83dbSDimitry Andric fieldFromInstruction(insn, 12, 9); 12255ffd83dbSDimitry Andric unsigned writeback = fieldFromInstruction(insn, 11, 1); 12265ffd83dbSDimitry Andric 12275ffd83dbSDimitry Andric switch (Inst.getOpcode()) { 12285ffd83dbSDimitry Andric default: 12295ffd83dbSDimitry Andric return Fail; 12305ffd83dbSDimitry Andric case AArch64::LDRAAwriteback: 12315ffd83dbSDimitry Andric case AArch64::LDRABwriteback: 1232*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>( 1233*0fca6ea1SDimitry Andric Inst, Rn /* writeback register */, Addr, Decoder); 12345ffd83dbSDimitry Andric break; 12355ffd83dbSDimitry Andric case AArch64::LDRAAindexed: 12365ffd83dbSDimitry Andric case AArch64::LDRABindexed: 12375ffd83dbSDimitry Andric break; 12385ffd83dbSDimitry Andric } 12395ffd83dbSDimitry Andric 1240*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr, 1241*0fca6ea1SDimitry Andric Decoder); 1242*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 1243*0fca6ea1SDimitry Andric Decoder); 12445ffd83dbSDimitry Andric DecodeSImm<10>(Inst, offset, Addr, Decoder); 12455ffd83dbSDimitry Andric 12465ffd83dbSDimitry Andric if (writeback && Rt == Rn && Rn != 31) { 12475ffd83dbSDimitry Andric return SoftFail; 12485ffd83dbSDimitry Andric } 12495ffd83dbSDimitry Andric 12505ffd83dbSDimitry Andric return Success; 12515ffd83dbSDimitry Andric } 12525ffd83dbSDimitry Andric 12530b57cec5SDimitry Andric static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn, 12540b57cec5SDimitry Andric uint64_t Addr, 125581ad6265SDimitry Andric const MCDisassembler *Decoder) { 12560b57cec5SDimitry Andric unsigned Rd = fieldFromInstruction(insn, 0, 5); 12570b57cec5SDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 12580b57cec5SDimitry Andric unsigned Rm = fieldFromInstruction(insn, 16, 5); 12590b57cec5SDimitry Andric unsigned extend = fieldFromInstruction(insn, 10, 6); 12600b57cec5SDimitry Andric 12610b57cec5SDimitry Andric unsigned shift = extend & 0x7; 12620b57cec5SDimitry Andric if (shift > 4) 12630b57cec5SDimitry Andric return Fail; 12640b57cec5SDimitry Andric 12650b57cec5SDimitry Andric switch (Inst.getOpcode()) { 12660b57cec5SDimitry Andric default: 12670b57cec5SDimitry Andric return Fail; 12680b57cec5SDimitry Andric case AArch64::ADDWrx: 12690b57cec5SDimitry Andric case AArch64::SUBWrx: 1270*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rd, Addr, 1271*0fca6ea1SDimitry Andric Decoder); 1272*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr, 1273*0fca6ea1SDimitry Andric Decoder); 1274*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr, 1275*0fca6ea1SDimitry Andric Decoder); 12760b57cec5SDimitry Andric break; 12770b57cec5SDimitry Andric case AArch64::ADDSWrx: 12780b57cec5SDimitry Andric case AArch64::SUBSWrx: 1279*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr, 1280*0fca6ea1SDimitry Andric Decoder); 1281*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr, 1282*0fca6ea1SDimitry Andric Decoder); 1283*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr, 1284*0fca6ea1SDimitry Andric Decoder); 12850b57cec5SDimitry Andric break; 12860b57cec5SDimitry Andric case AArch64::ADDXrx: 12870b57cec5SDimitry Andric case AArch64::SUBXrx: 1288*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rd, Addr, 1289*0fca6ea1SDimitry Andric Decoder); 1290*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 1291*0fca6ea1SDimitry Andric Decoder); 1292*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr, 1293*0fca6ea1SDimitry Andric Decoder); 12940b57cec5SDimitry Andric break; 12950b57cec5SDimitry Andric case AArch64::ADDSXrx: 12960b57cec5SDimitry Andric case AArch64::SUBSXrx: 1297*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr, 1298*0fca6ea1SDimitry Andric Decoder); 1299*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 1300*0fca6ea1SDimitry Andric Decoder); 1301*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr, 1302*0fca6ea1SDimitry Andric Decoder); 13030b57cec5SDimitry Andric break; 13040b57cec5SDimitry Andric case AArch64::ADDXrx64: 13050b57cec5SDimitry Andric case AArch64::SUBXrx64: 1306*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rd, Addr, 1307*0fca6ea1SDimitry Andric Decoder); 1308*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 1309*0fca6ea1SDimitry Andric Decoder); 1310*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr, 1311*0fca6ea1SDimitry Andric Decoder); 13120b57cec5SDimitry Andric break; 13130b57cec5SDimitry Andric case AArch64::SUBSXrx64: 13140b57cec5SDimitry Andric case AArch64::ADDSXrx64: 1315*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr, 1316*0fca6ea1SDimitry Andric Decoder); 1317*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 1318*0fca6ea1SDimitry Andric Decoder); 1319*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr, 1320*0fca6ea1SDimitry Andric Decoder); 13210b57cec5SDimitry Andric break; 13220b57cec5SDimitry Andric } 13230b57cec5SDimitry Andric 13240b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(extend)); 13250b57cec5SDimitry Andric return Success; 13260b57cec5SDimitry Andric } 13270b57cec5SDimitry Andric 13280b57cec5SDimitry Andric static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn, 13290b57cec5SDimitry Andric uint64_t Addr, 133081ad6265SDimitry Andric const MCDisassembler *Decoder) { 13310b57cec5SDimitry Andric unsigned Rd = fieldFromInstruction(insn, 0, 5); 13320b57cec5SDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 13330b57cec5SDimitry Andric unsigned Datasize = fieldFromInstruction(insn, 31, 1); 13340b57cec5SDimitry Andric unsigned imm; 13350b57cec5SDimitry Andric 13360b57cec5SDimitry Andric if (Datasize) { 13370b57cec5SDimitry Andric if (Inst.getOpcode() == AArch64::ANDSXri) 1338*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr, 1339*0fca6ea1SDimitry Andric Decoder); 13400b57cec5SDimitry Andric else 1341*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>( 1342*0fca6ea1SDimitry Andric Inst, Rd, Addr, Decoder); 1343*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rn, Addr, 1344*0fca6ea1SDimitry Andric Decoder); 13450b57cec5SDimitry Andric imm = fieldFromInstruction(insn, 10, 13); 13460b57cec5SDimitry Andric if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64)) 13470b57cec5SDimitry Andric return Fail; 13480b57cec5SDimitry Andric } else { 13490b57cec5SDimitry Andric if (Inst.getOpcode() == AArch64::ANDSWri) 1350*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr, 1351*0fca6ea1SDimitry Andric Decoder); 13520b57cec5SDimitry Andric else 1353*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>( 1354*0fca6ea1SDimitry Andric Inst, Rd, Addr, Decoder); 1355*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rn, Addr, 1356*0fca6ea1SDimitry Andric Decoder); 13570b57cec5SDimitry Andric imm = fieldFromInstruction(insn, 10, 12); 13580b57cec5SDimitry Andric if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 32)) 13590b57cec5SDimitry Andric return Fail; 13600b57cec5SDimitry Andric } 13610b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(imm)); 13620b57cec5SDimitry Andric return Success; 13630b57cec5SDimitry Andric } 13640b57cec5SDimitry Andric 13650b57cec5SDimitry Andric static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn, 13660b57cec5SDimitry Andric uint64_t Addr, 136781ad6265SDimitry Andric const MCDisassembler *Decoder) { 13680b57cec5SDimitry Andric unsigned Rd = fieldFromInstruction(insn, 0, 5); 13690b57cec5SDimitry Andric unsigned cmode = fieldFromInstruction(insn, 12, 4); 13700b57cec5SDimitry Andric unsigned imm = fieldFromInstruction(insn, 16, 3) << 5; 13710b57cec5SDimitry Andric imm |= fieldFromInstruction(insn, 5, 5); 13720b57cec5SDimitry Andric 13730b57cec5SDimitry Andric if (Inst.getOpcode() == AArch64::MOVID) 1374*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rd, Addr, 1375*0fca6ea1SDimitry Andric Decoder); 13760b57cec5SDimitry Andric else 1377*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr, 1378*0fca6ea1SDimitry Andric Decoder); 13790b57cec5SDimitry Andric 13800b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(imm)); 13810b57cec5SDimitry Andric 13820b57cec5SDimitry Andric switch (Inst.getOpcode()) { 13830b57cec5SDimitry Andric default: 13840b57cec5SDimitry Andric break; 13850b57cec5SDimitry Andric case AArch64::MOVIv4i16: 13860b57cec5SDimitry Andric case AArch64::MOVIv8i16: 13870b57cec5SDimitry Andric case AArch64::MVNIv4i16: 13880b57cec5SDimitry Andric case AArch64::MVNIv8i16: 13890b57cec5SDimitry Andric case AArch64::MOVIv2i32: 13900b57cec5SDimitry Andric case AArch64::MOVIv4i32: 13910b57cec5SDimitry Andric case AArch64::MVNIv2i32: 13920b57cec5SDimitry Andric case AArch64::MVNIv4i32: 13930b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm((cmode & 6) << 2)); 13940b57cec5SDimitry Andric break; 13950b57cec5SDimitry Andric case AArch64::MOVIv2s_msl: 13960b57cec5SDimitry Andric case AArch64::MOVIv4s_msl: 13970b57cec5SDimitry Andric case AArch64::MVNIv2s_msl: 13980b57cec5SDimitry Andric case AArch64::MVNIv4s_msl: 13990b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm((cmode & 1) ? 0x110 : 0x108)); 14000b57cec5SDimitry Andric break; 14010b57cec5SDimitry Andric } 14020b57cec5SDimitry Andric 14030b57cec5SDimitry Andric return Success; 14040b57cec5SDimitry Andric } 14050b57cec5SDimitry Andric 14060b57cec5SDimitry Andric static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn, 14070b57cec5SDimitry Andric uint64_t Addr, 140881ad6265SDimitry Andric const MCDisassembler *Decoder) { 14090b57cec5SDimitry Andric unsigned Rd = fieldFromInstruction(insn, 0, 5); 14100b57cec5SDimitry Andric unsigned cmode = fieldFromInstruction(insn, 12, 4); 14110b57cec5SDimitry Andric unsigned imm = fieldFromInstruction(insn, 16, 3) << 5; 14120b57cec5SDimitry Andric imm |= fieldFromInstruction(insn, 5, 5); 14130b57cec5SDimitry Andric 14140b57cec5SDimitry Andric // Tied operands added twice. 1415*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr, 1416*0fca6ea1SDimitry Andric Decoder); 1417*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr, 1418*0fca6ea1SDimitry Andric Decoder); 14190b57cec5SDimitry Andric 14200b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(imm)); 14210b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm((cmode & 6) << 2)); 14220b57cec5SDimitry Andric 14230b57cec5SDimitry Andric return Success; 14240b57cec5SDimitry Andric } 14250b57cec5SDimitry Andric 14260b57cec5SDimitry Andric static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn, 142781ad6265SDimitry Andric uint64_t Addr, 142881ad6265SDimitry Andric const MCDisassembler *Decoder) { 14290b57cec5SDimitry Andric unsigned Rd = fieldFromInstruction(insn, 0, 5); 14300b57cec5SDimitry Andric int64_t imm = fieldFromInstruction(insn, 5, 19) << 2; 14310b57cec5SDimitry Andric imm |= fieldFromInstruction(insn, 29, 2); 14320b57cec5SDimitry Andric 14330b57cec5SDimitry Andric // Sign-extend the 21-bit immediate. 14340b57cec5SDimitry Andric if (imm & (1 << (21 - 1))) 14350b57cec5SDimitry Andric imm |= ~((1LL << 21) - 1); 14360b57cec5SDimitry Andric 1437*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr, 1438*0fca6ea1SDimitry Andric Decoder); 143981ad6265SDimitry Andric if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 0, 4)) 14400b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(imm)); 14410b57cec5SDimitry Andric 14420b57cec5SDimitry Andric return Success; 14430b57cec5SDimitry Andric } 14440b57cec5SDimitry Andric 14450b57cec5SDimitry Andric static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn, 144681ad6265SDimitry Andric uint64_t Addr, 144781ad6265SDimitry Andric const MCDisassembler *Decoder) { 14480b57cec5SDimitry Andric unsigned Rd = fieldFromInstruction(insn, 0, 5); 14490b57cec5SDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 14500b57cec5SDimitry Andric unsigned Imm = fieldFromInstruction(insn, 10, 14); 14510b57cec5SDimitry Andric unsigned S = fieldFromInstruction(insn, 29, 1); 14520b57cec5SDimitry Andric unsigned Datasize = fieldFromInstruction(insn, 31, 1); 14530b57cec5SDimitry Andric 14540b57cec5SDimitry Andric unsigned ShifterVal = (Imm >> 12) & 3; 14550b57cec5SDimitry Andric unsigned ImmVal = Imm & 0xFFF; 14560b57cec5SDimitry Andric 14570b57cec5SDimitry Andric if (ShifterVal != 0 && ShifterVal != 1) 14580b57cec5SDimitry Andric return Fail; 14590b57cec5SDimitry Andric 14600b57cec5SDimitry Andric if (Datasize) { 14610b57cec5SDimitry Andric if (Rd == 31 && !S) 1462*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>( 1463*0fca6ea1SDimitry Andric Inst, Rd, Addr, Decoder); 14640b57cec5SDimitry Andric else 1465*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr, 1466*0fca6ea1SDimitry Andric Decoder); 1467*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 1468*0fca6ea1SDimitry Andric Decoder); 14690b57cec5SDimitry Andric } else { 14700b57cec5SDimitry Andric if (Rd == 31 && !S) 1471*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>( 1472*0fca6ea1SDimitry Andric Inst, Rd, Addr, Decoder); 14730b57cec5SDimitry Andric else 1474*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr, 1475*0fca6ea1SDimitry Andric Decoder); 1476*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr, 1477*0fca6ea1SDimitry Andric Decoder); 14780b57cec5SDimitry Andric } 14790b57cec5SDimitry Andric 148081ad6265SDimitry Andric if (!Decoder->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 0, 4)) 14810b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(ImmVal)); 14820b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(12 * ShifterVal)); 14830b57cec5SDimitry Andric return Success; 14840b57cec5SDimitry Andric } 14850b57cec5SDimitry Andric 14860b57cec5SDimitry Andric static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn, 14870b57cec5SDimitry Andric uint64_t Addr, 148881ad6265SDimitry Andric const MCDisassembler *Decoder) { 14890b57cec5SDimitry Andric int64_t imm = fieldFromInstruction(insn, 0, 26); 14900b57cec5SDimitry Andric 14910b57cec5SDimitry Andric // Sign-extend the 26-bit immediate. 14920b57cec5SDimitry Andric if (imm & (1 << (26 - 1))) 14930b57cec5SDimitry Andric imm |= ~((1LL << 26) - 1); 14940b57cec5SDimitry Andric 149581ad6265SDimitry Andric if (!Decoder->tryAddingSymbolicOperand(Inst, imm * 4, Addr, true, 0, 0, 4)) 14960b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(imm)); 14970b57cec5SDimitry Andric 14980b57cec5SDimitry Andric return Success; 14990b57cec5SDimitry Andric } 15000b57cec5SDimitry Andric 1501bdd1243dSDimitry Andric static bool isInvalidPState(uint64_t Op1, uint64_t Op2) { 1502bdd1243dSDimitry Andric return Op1 == 0b000 && (Op2 == 0b000 || // CFINV 1503bdd1243dSDimitry Andric Op2 == 0b001 || // XAFlag 1504bdd1243dSDimitry Andric Op2 == 0b010); // AXFlag 1505bdd1243dSDimitry Andric } 1506bdd1243dSDimitry Andric 150781ad6265SDimitry Andric static DecodeStatus 1508bdd1243dSDimitry Andric DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr, 150981ad6265SDimitry Andric const MCDisassembler *Decoder) { 15100b57cec5SDimitry Andric uint64_t op1 = fieldFromInstruction(insn, 16, 3); 15110b57cec5SDimitry Andric uint64_t op2 = fieldFromInstruction(insn, 5, 3); 1512bdd1243dSDimitry Andric uint64_t imm = fieldFromInstruction(insn, 8, 4); 15130b57cec5SDimitry Andric uint64_t pstate_field = (op1 << 3) | op2; 15140b57cec5SDimitry Andric 1515bdd1243dSDimitry Andric if (isInvalidPState(op1, op2)) 15160b57cec5SDimitry Andric return Fail; 15170b57cec5SDimitry Andric 15180b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(pstate_field)); 1519bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createImm(imm)); 15200b57cec5SDimitry Andric 1521bdd1243dSDimitry Andric auto PState = AArch64PState::lookupPStateImm0_15ByEncoding(pstate_field); 1522bdd1243dSDimitry Andric if (PState && 1523bdd1243dSDimitry Andric PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits())) 1524bdd1243dSDimitry Andric return Success; 1525bdd1243dSDimitry Andric return Fail; 1526bdd1243dSDimitry Andric } 1527bdd1243dSDimitry Andric 1528bdd1243dSDimitry Andric static DecodeStatus 1529bdd1243dSDimitry Andric DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr, 1530bdd1243dSDimitry Andric const MCDisassembler *Decoder) { 1531bdd1243dSDimitry Andric uint64_t op1 = fieldFromInstruction(insn, 16, 3); 1532bdd1243dSDimitry Andric uint64_t op2 = fieldFromInstruction(insn, 5, 3); 1533bdd1243dSDimitry Andric uint64_t crm_high = fieldFromInstruction(insn, 9, 3); 1534bdd1243dSDimitry Andric uint64_t imm = fieldFromInstruction(insn, 8, 1); 1535bdd1243dSDimitry Andric uint64_t pstate_field = (crm_high << 6) | (op1 << 3) | op2; 1536bdd1243dSDimitry Andric 1537bdd1243dSDimitry Andric if (isInvalidPState(op1, op2)) 1538bdd1243dSDimitry Andric return Fail; 1539bdd1243dSDimitry Andric 1540bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createImm(pstate_field)); 1541bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createImm(imm)); 1542bdd1243dSDimitry Andric 1543bdd1243dSDimitry Andric auto PState = AArch64PState::lookupPStateImm0_1ByEncoding(pstate_field); 154481ad6265SDimitry Andric if (PState && 154581ad6265SDimitry Andric PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits())) 15460b57cec5SDimitry Andric return Success; 15470b57cec5SDimitry Andric return Fail; 15480b57cec5SDimitry Andric } 15490b57cec5SDimitry Andric 15500b57cec5SDimitry Andric static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn, 155181ad6265SDimitry Andric uint64_t Addr, 155281ad6265SDimitry Andric const MCDisassembler *Decoder) { 15530b57cec5SDimitry Andric uint64_t Rt = fieldFromInstruction(insn, 0, 5); 15540b57cec5SDimitry Andric uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5; 15550b57cec5SDimitry Andric bit |= fieldFromInstruction(insn, 19, 5); 15560b57cec5SDimitry Andric int64_t dst = fieldFromInstruction(insn, 5, 14); 15570b57cec5SDimitry Andric 15580b57cec5SDimitry Andric // Sign-extend 14-bit immediate. 15590b57cec5SDimitry Andric if (dst & (1 << (14 - 1))) 15600b57cec5SDimitry Andric dst |= ~((1LL << 14) - 1); 15610b57cec5SDimitry Andric 15620b57cec5SDimitry Andric if (fieldFromInstruction(insn, 31, 1) == 0) 1563*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr, 1564*0fca6ea1SDimitry Andric Decoder); 15650b57cec5SDimitry Andric else 1566*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr, 1567*0fca6ea1SDimitry Andric Decoder); 15680b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(bit)); 156981ad6265SDimitry Andric if (!Decoder->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 0, 4)) 15700b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(dst)); 15710b57cec5SDimitry Andric 15720b57cec5SDimitry Andric return Success; 15730b57cec5SDimitry Andric } 15740b57cec5SDimitry Andric 157581ad6265SDimitry Andric static DecodeStatus 157681ad6265SDimitry Andric DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegClassID, 157781ad6265SDimitry Andric unsigned RegNo, uint64_t Addr, 157881ad6265SDimitry Andric const MCDisassembler *Decoder) { 15790b57cec5SDimitry Andric // Register number must be even (see CASP instruction) 15800b57cec5SDimitry Andric if (RegNo & 0x1) 15810b57cec5SDimitry Andric return Fail; 15820b57cec5SDimitry Andric 15830b57cec5SDimitry Andric unsigned Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2); 15840b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg)); 15850b57cec5SDimitry Andric return Success; 15860b57cec5SDimitry Andric } 15870b57cec5SDimitry Andric 158881ad6265SDimitry Andric static DecodeStatus 158981ad6265SDimitry Andric DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, 159081ad6265SDimitry Andric const MCDisassembler *Decoder) { 1591*0fca6ea1SDimitry Andric return DecodeGPRSeqPairsClassRegisterClass( 1592*0fca6ea1SDimitry Andric Inst, AArch64::WSeqPairsClassRegClassID, RegNo, Addr, Decoder); 15930b57cec5SDimitry Andric } 15940b57cec5SDimitry Andric 159581ad6265SDimitry Andric static DecodeStatus 159681ad6265SDimitry Andric DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, 159781ad6265SDimitry Andric const MCDisassembler *Decoder) { 1598*0fca6ea1SDimitry Andric return DecodeGPRSeqPairsClassRegisterClass( 1599*0fca6ea1SDimitry Andric Inst, AArch64::XSeqPairsClassRegClassID, RegNo, Addr, Decoder); 16000b57cec5SDimitry Andric } 16010b57cec5SDimitry Andric 1602bdd1243dSDimitry Andric static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn, 1603bdd1243dSDimitry Andric uint64_t Addr, 1604bdd1243dSDimitry Andric const MCDisassembler *Decoder) { 1605bdd1243dSDimitry Andric unsigned op1 = fieldFromInstruction(insn, 16, 3); 1606bdd1243dSDimitry Andric unsigned CRn = fieldFromInstruction(insn, 12, 4); 1607bdd1243dSDimitry Andric unsigned CRm = fieldFromInstruction(insn, 8, 4); 1608bdd1243dSDimitry Andric unsigned op2 = fieldFromInstruction(insn, 5, 3); 1609bdd1243dSDimitry Andric unsigned Rt = fieldFromInstruction(insn, 0, 5); 1610bdd1243dSDimitry Andric if (Rt != 0b11111) 1611bdd1243dSDimitry Andric return Fail; 1612bdd1243dSDimitry Andric 1613bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createImm(op1)); 1614bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createImm(CRn)); 1615bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createImm(CRm)); 1616bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createImm(op2)); 1617*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr, 1618*0fca6ea1SDimitry Andric Decoder); 1619bdd1243dSDimitry Andric 1620bdd1243dSDimitry Andric return Success; 1621bdd1243dSDimitry Andric } 1622bdd1243dSDimitry Andric 162381ad6265SDimitry Andric static DecodeStatus 162481ad6265SDimitry Andric DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, 162581ad6265SDimitry Andric const MCDisassembler *Decoder) { 16260b57cec5SDimitry Andric unsigned Zdn = fieldFromInstruction(insn, 0, 5); 16270b57cec5SDimitry Andric unsigned imm = fieldFromInstruction(insn, 5, 13); 16280b57cec5SDimitry Andric if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64)) 16290b57cec5SDimitry Andric return Fail; 16300b57cec5SDimitry Andric 16310b57cec5SDimitry Andric // The same (tied) operand is added twice to the instruction. 1632*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>(Inst, Zdn, Addr, 1633*0fca6ea1SDimitry Andric Decoder); 16340b57cec5SDimitry Andric if (Inst.getOpcode() != AArch64::DUPM_ZI) 1635*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>(Inst, Zdn, Addr, 1636*0fca6ea1SDimitry Andric Decoder); 16370b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(imm)); 16380b57cec5SDimitry Andric return Success; 16390b57cec5SDimitry Andric } 16400b57cec5SDimitry Andric 16410b57cec5SDimitry Andric template <int Bits> 1642349cc55cSDimitry Andric static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address, 164381ad6265SDimitry Andric const MCDisassembler *Decoder) { 16440b57cec5SDimitry Andric if (Imm & ~((1LL << Bits) - 1)) 16450b57cec5SDimitry Andric return Fail; 16460b57cec5SDimitry Andric 16470b57cec5SDimitry Andric // Imm is a signed immediate, so sign extend it. 16480b57cec5SDimitry Andric if (Imm & (1 << (Bits - 1))) 16490b57cec5SDimitry Andric Imm |= ~((1LL << Bits) - 1); 16500b57cec5SDimitry Andric 16510b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm)); 16520b57cec5SDimitry Andric return Success; 16530b57cec5SDimitry Andric } 16540b57cec5SDimitry Andric 16550b57cec5SDimitry Andric // Decode 8-bit signed/unsigned immediate for a given element width. 16560b57cec5SDimitry Andric template <int ElementWidth> 165781ad6265SDimitry Andric static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr, 165881ad6265SDimitry Andric const MCDisassembler *Decoder) { 16590b57cec5SDimitry Andric unsigned Val = (uint8_t)Imm; 16600b57cec5SDimitry Andric unsigned Shift = (Imm & 0x100) ? 8 : 0; 16610b57cec5SDimitry Andric if (ElementWidth == 8 && Shift) 16620b57cec5SDimitry Andric return Fail; 16630b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Val)); 16640b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Shift)); 16650b57cec5SDimitry Andric return Success; 16660b57cec5SDimitry Andric } 16670b57cec5SDimitry Andric 16680b57cec5SDimitry Andric // Decode uimm4 ranged from 1-16. 16690b57cec5SDimitry Andric static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm, 167081ad6265SDimitry Andric uint64_t Addr, 167181ad6265SDimitry Andric const MCDisassembler *Decoder) { 16720b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm + 1)); 16730b57cec5SDimitry Andric return Success; 16740b57cec5SDimitry Andric } 1675fe6060f1SDimitry Andric 1676fe6060f1SDimitry Andric static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address, 167781ad6265SDimitry Andric const MCDisassembler *Decoder) { 1678fe6060f1SDimitry Andric if (AArch64SVCR::lookupSVCRByEncoding(Imm)) { 1679fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm)); 1680fe6060f1SDimitry Andric return Success; 1681fe6060f1SDimitry Andric } 1682fe6060f1SDimitry Andric return Fail; 1683fe6060f1SDimitry Andric } 168404eeddc0SDimitry Andric 168504eeddc0SDimitry Andric static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn, 168604eeddc0SDimitry Andric uint64_t Addr, 168781ad6265SDimitry Andric const MCDisassembler *Decoder) { 168804eeddc0SDimitry Andric unsigned Rd = fieldFromInstruction(insn, 0, 5); 168904eeddc0SDimitry Andric unsigned Rs = fieldFromInstruction(insn, 16, 5); 169004eeddc0SDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 169104eeddc0SDimitry Andric 169204eeddc0SDimitry Andric // None of the registers may alias: if they do, then the instruction is not 169304eeddc0SDimitry Andric // merely unpredictable but actually entirely unallocated. 169404eeddc0SDimitry Andric if (Rd == Rs || Rs == Rn || Rd == Rn) 169504eeddc0SDimitry Andric return MCDisassembler::Fail; 169604eeddc0SDimitry Andric 169704eeddc0SDimitry Andric // All three register operands are written back, so they all appear 169804eeddc0SDimitry Andric // twice in the operand list, once as outputs and once as inputs. 1699*0fca6ea1SDimitry Andric if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>( 1700*0fca6ea1SDimitry Andric Inst, Rd, Addr, Decoder) || 1701*0fca6ea1SDimitry Andric !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>( 1702*0fca6ea1SDimitry Andric Inst, Rs, Addr, Decoder) || 1703*0fca6ea1SDimitry Andric !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>( 1704*0fca6ea1SDimitry Andric Inst, Rn, Addr, Decoder) || 1705*0fca6ea1SDimitry Andric !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>( 1706*0fca6ea1SDimitry Andric Inst, Rd, Addr, Decoder) || 1707*0fca6ea1SDimitry Andric !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>( 1708*0fca6ea1SDimitry Andric Inst, Rs, Addr, Decoder) || 1709*0fca6ea1SDimitry Andric !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>( 1710*0fca6ea1SDimitry Andric Inst, Rn, Addr, Decoder)) 171104eeddc0SDimitry Andric return MCDisassembler::Fail; 171204eeddc0SDimitry Andric 171304eeddc0SDimitry Andric return MCDisassembler::Success; 171404eeddc0SDimitry Andric } 171504eeddc0SDimitry Andric 171604eeddc0SDimitry Andric static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn, 171704eeddc0SDimitry Andric uint64_t Addr, 171881ad6265SDimitry Andric const MCDisassembler *Decoder) { 171904eeddc0SDimitry Andric unsigned Rd = fieldFromInstruction(insn, 0, 5); 172004eeddc0SDimitry Andric unsigned Rm = fieldFromInstruction(insn, 16, 5); 172104eeddc0SDimitry Andric unsigned Rn = fieldFromInstruction(insn, 5, 5); 172204eeddc0SDimitry Andric 172304eeddc0SDimitry Andric // None of the registers may alias: if they do, then the instruction is not 172404eeddc0SDimitry Andric // merely unpredictable but actually entirely unallocated. 172504eeddc0SDimitry Andric if (Rd == Rm || Rm == Rn || Rd == Rn) 172604eeddc0SDimitry Andric return MCDisassembler::Fail; 172704eeddc0SDimitry Andric 172804eeddc0SDimitry Andric // Rd and Rn (not Rm) register operands are written back, so they appear 172904eeddc0SDimitry Andric // twice in the operand list, once as outputs and once as inputs. 1730*0fca6ea1SDimitry Andric if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>( 1731*0fca6ea1SDimitry Andric Inst, Rd, Addr, Decoder) || 1732*0fca6ea1SDimitry Andric !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>( 1733*0fca6ea1SDimitry Andric Inst, Rn, Addr, Decoder) || 1734*0fca6ea1SDimitry Andric !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>( 1735*0fca6ea1SDimitry Andric Inst, Rd, Addr, Decoder) || 1736*0fca6ea1SDimitry Andric !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>( 1737*0fca6ea1SDimitry Andric Inst, Rn, Addr, Decoder) || 1738*0fca6ea1SDimitry Andric !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>( 1739*0fca6ea1SDimitry Andric Inst, Rm, Addr, Decoder)) 174004eeddc0SDimitry Andric return MCDisassembler::Fail; 174104eeddc0SDimitry Andric 174204eeddc0SDimitry Andric return MCDisassembler::Success; 174304eeddc0SDimitry Andric } 1744bdd1243dSDimitry Andric 1745bdd1243dSDimitry Andric static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn, 1746bdd1243dSDimitry Andric uint64_t Addr, 1747bdd1243dSDimitry Andric const MCDisassembler *Decoder) { 1748bdd1243dSDimitry Andric // PRFM with Rt = '11xxx' should be decoded as RPRFM. 1749bdd1243dSDimitry Andric // Fail to decode and defer to fallback decoder table to decode RPRFM. 1750bdd1243dSDimitry Andric unsigned Mask = 0x18; 1751bdd1243dSDimitry Andric uint64_t Rt = fieldFromInstruction(insn, 0, 5); 1752bdd1243dSDimitry Andric if ((Rt & Mask) == Mask) 1753bdd1243dSDimitry Andric return Fail; 1754bdd1243dSDimitry Andric 1755bdd1243dSDimitry Andric uint64_t Rn = fieldFromInstruction(insn, 5, 5); 1756bdd1243dSDimitry Andric uint64_t Shift = fieldFromInstruction(insn, 12, 1); 1757bdd1243dSDimitry Andric uint64_t Extend = fieldFromInstruction(insn, 15, 1); 1758bdd1243dSDimitry Andric uint64_t Rm = fieldFromInstruction(insn, 16, 5); 1759bdd1243dSDimitry Andric 1760bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createImm(Rt)); 1761*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr, 1762*0fca6ea1SDimitry Andric Decoder); 1763bdd1243dSDimitry Andric 1764bdd1243dSDimitry Andric switch (Inst.getOpcode()) { 1765bdd1243dSDimitry Andric default: 1766bdd1243dSDimitry Andric return Fail; 1767bdd1243dSDimitry Andric case AArch64::PRFMroW: 1768*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr, 1769*0fca6ea1SDimitry Andric Decoder); 1770bdd1243dSDimitry Andric break; 1771bdd1243dSDimitry Andric case AArch64::PRFMroX: 1772*0fca6ea1SDimitry Andric DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr, 1773*0fca6ea1SDimitry Andric Decoder); 1774bdd1243dSDimitry Andric break; 1775bdd1243dSDimitry Andric } 1776bdd1243dSDimitry Andric 1777bdd1243dSDimitry Andric DecodeMemExtend(Inst, (Extend << 1) | Shift, Addr, Decoder); 1778bdd1243dSDimitry Andric 1779bdd1243dSDimitry Andric return Success; 1780bdd1243dSDimitry Andric } 1781