[llvm] [NFC][MC][AArch64] Rearrange decode functions in AArch64 disassembler (PR #154990)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 22 10:22:09 PDT 2025
https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/154990
Rearrange decode functions to be before including the generated disassembler code and eliminate forward declarations for most of them. This is possible because `fieldFromInstruction` is now in MCDecoder.h and not in the generated disassembler code.
>From 26f713a7e5e29ee391ab25db9b2bb9adf8fff8a1 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Fri, 22 Aug 2025 10:20:08 -0700
Subject: [PATCH] [NFC][MC][AArch64] Rearrange decode functions in AArch64
disassembler
Rearrange decode functions to be before including the generated disassembler code
and eliminate forward declarations for most of them. This is possible because
`fieldFromInstruction` is now in MCDecoder.h and not in the generated
disassembler code.
---
.../Disassembler/AArch64Disassembler.cpp | 411 +++++-------------
1 file changed, 117 insertions(+), 294 deletions(-)
diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index 323db2a0728eb..23e46b84f6278 100644
--- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -35,308 +35,14 @@ using namespace llvm::MCD;
// Pull DecodeStatus and its enum values into the global namespace.
using DecodeStatus = MCDisassembler::DecodeStatus;
-// Forward declare these because the autogenerated code will reference them.
-// Definitions are further down.
-template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass>
-static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
- const MCDisassembler *Decoder);
-template <unsigned Min, unsigned Max>
-static DecodeStatus DecodeZPRMul2_MinMax(MCInst &Inst, unsigned RegNo,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address,
- const MCDisassembler *Decoder);
-template <unsigned Min, unsigned Max>
-static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
- uint64_t Address,
- const void *Decoder);
-static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,
- uint64_t Address,
- const void *Decoder);
-template <unsigned NumBitsForTile>
-static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
- uint64_t Address,
- const void *Decoder);
-
-static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-
-static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
- const MCDisassembler *Decoder);
template <int Bits>
static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
const MCDisassembler *Decoder);
-template <int ElementWidth>
-static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Addr,
- const MCDisassembler *Decoder);
-static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
- uint64_t Address,
- const MCDisassembler *Decoder);
-
-#include "AArch64GenDisassemblerTables.inc"
-#include "AArch64GenInstrInfo.inc"
#define Success MCDisassembler::Success
#define Fail MCDisassembler::Fail
#define SoftFail MCDisassembler::SoftFail
-static MCDisassembler *createAArch64Disassembler(const Target &T,
- const MCSubtargetInfo &STI,
- MCContext &Ctx) {
-
- return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());
-}
-
-DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
- ArrayRef<uint8_t> Bytes,
- uint64_t Address,
- raw_ostream &CS) const {
- CommentStream = &CS;
-
- Size = 0;
- // We want to read exactly 4 bytes of data.
- if (Bytes.size() < 4)
- return Fail;
- Size = 4;
-
- // Encoded as a small-endian 32-bit word in the stream.
- uint32_t Insn =
- (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
-
- const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
-
- for (const auto *Table : Tables) {
- DecodeStatus Result =
- decodeInstruction(Table, MI, Insn, Address, this, STI);
-
- const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
-
- // For Scalable Matrix Extension (SME) instructions that have an implicit
- // operand for the accumulator (ZA) or implicit immediate zero which isn't
- // encoded, manually insert operand.
- for (unsigned i = 0; i < Desc.getNumOperands(); i++) {
- if (Desc.operands()[i].OperandType == MCOI::OPERAND_REGISTER) {
- switch (Desc.operands()[i].RegClass) {
- default:
- break;
- case AArch64::MPRRegClassID:
- MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZA));
- break;
- case AArch64::MPR8RegClassID:
- MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0));
- break;
- case AArch64::ZTRRegClassID:
- MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0));
- break;
- }
- } else if (Desc.operands()[i].OperandType ==
- AArch64::OPERAND_IMPLICIT_IMM_0) {
- MI.insert(MI.begin() + i, MCOperand::createImm(0));
- }
- }
-
- if (MI.getOpcode() == AArch64::LDR_ZA ||
- MI.getOpcode() == AArch64::STR_ZA) {
- // Spill and fill instructions have a single immediate used for both
- // the vector select offset and optional memory offset. Replicate
- // the decoded immediate.
- const MCOperand &Imm4Op = MI.getOperand(2);
- assert(Imm4Op.isImm() && "Unexpected operand type!");
- MI.addOperand(Imm4Op);
- }
-
- if (Result != MCDisassembler::Fail)
- return Result;
- }
-
- return MCDisassembler::Fail;
-}
-
-uint64_t AArch64Disassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
- uint64_t Address) const {
- // AArch64 instructions are always 4 bytes wide, so there's no point
- // in skipping any smaller number of bytes if an instruction can't
- // be decoded.
- return 4;
-}
-
-static MCSymbolizer *
-createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
- LLVMSymbolLookupCallback SymbolLookUp,
- void *DisInfo, MCContext *Ctx,
- std::unique_ptr<MCRelocationInfo> &&RelInfo) {
- return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,
- SymbolLookUp, DisInfo);
-}
-
-extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
-LLVMInitializeAArch64Disassembler() {
- TargetRegistry::RegisterMCDisassembler(getTheAArch64leTarget(),
- createAArch64Disassembler);
- TargetRegistry::RegisterMCDisassembler(getTheAArch64beTarget(),
- createAArch64Disassembler);
- TargetRegistry::RegisterMCSymbolizer(getTheAArch64leTarget(),
- createAArch64ExternalSymbolizer);
- TargetRegistry::RegisterMCSymbolizer(getTheAArch64beTarget(),
- createAArch64ExternalSymbolizer);
- TargetRegistry::RegisterMCDisassembler(getTheAArch64_32Target(),
- createAArch64Disassembler);
- TargetRegistry::RegisterMCSymbolizer(getTheAArch64_32Target(),
- createAArch64ExternalSymbolizer);
-
- TargetRegistry::RegisterMCDisassembler(getTheARM64Target(),
- createAArch64Disassembler);
- TargetRegistry::RegisterMCSymbolizer(getTheARM64Target(),
- createAArch64ExternalSymbolizer);
- TargetRegistry::RegisterMCDisassembler(getTheARM64_32Target(),
- createAArch64Disassembler);
- TargetRegistry::RegisterMCSymbolizer(getTheARM64_32Target(),
- createAArch64ExternalSymbolizer);
-}
-
template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass>
static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
@@ -1856,3 +1562,120 @@ static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
return Success;
}
+
+#include "AArch64GenDisassemblerTables.inc"
+#include "AArch64GenInstrInfo.inc"
+
+static MCDisassembler *createAArch64Disassembler(const Target &T,
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx) {
+
+ return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());
+}
+
+DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
+ ArrayRef<uint8_t> Bytes,
+ uint64_t Address,
+ raw_ostream &CS) const {
+ CommentStream = &CS;
+
+ Size = 0;
+ // We want to read exactly 4 bytes of data.
+ if (Bytes.size() < 4)
+ return Fail;
+ Size = 4;
+
+ // Encoded as a small-endian 32-bit word in the stream.
+ uint32_t Insn =
+ (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
+
+ const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
+
+ for (const auto *Table : Tables) {
+ DecodeStatus Result =
+ decodeInstruction(Table, MI, Insn, Address, this, STI);
+
+ const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
+
+ // For Scalable Matrix Extension (SME) instructions that have an implicit
+ // operand for the accumulator (ZA) or implicit immediate zero which isn't
+ // encoded, manually insert operand.
+ for (unsigned i = 0; i < Desc.getNumOperands(); i++) {
+ if (Desc.operands()[i].OperandType == MCOI::OPERAND_REGISTER) {
+ switch (Desc.operands()[i].RegClass) {
+ default:
+ break;
+ case AArch64::MPRRegClassID:
+ MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZA));
+ break;
+ case AArch64::MPR8RegClassID:
+ MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0));
+ break;
+ case AArch64::ZTRRegClassID:
+ MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0));
+ break;
+ }
+ } else if (Desc.operands()[i].OperandType ==
+ AArch64::OPERAND_IMPLICIT_IMM_0) {
+ MI.insert(MI.begin() + i, MCOperand::createImm(0));
+ }
+ }
+
+ if (MI.getOpcode() == AArch64::LDR_ZA ||
+ MI.getOpcode() == AArch64::STR_ZA) {
+ // Spill and fill instructions have a single immediate used for both
+ // the vector select offset and optional memory offset. Replicate
+ // the decoded immediate.
+ const MCOperand &Imm4Op = MI.getOperand(2);
+ assert(Imm4Op.isImm() && "Unexpected operand type!");
+ MI.addOperand(Imm4Op);
+ }
+
+ if (Result != MCDisassembler::Fail)
+ return Result;
+ }
+
+ return MCDisassembler::Fail;
+}
+
+uint64_t AArch64Disassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
+ uint64_t Address) const {
+ // AArch64 instructions are always 4 bytes wide, so there's no point
+ // in skipping any smaller number of bytes if an instruction can't
+ // be decoded.
+ return 4;
+}
+
+static MCSymbolizer *
+createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp,
+ void *DisInfo, MCContext *Ctx,
+ std::unique_ptr<MCRelocationInfo> &&RelInfo) {
+ return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,
+ SymbolLookUp, DisInfo);
+}
+
+extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
+LLVMInitializeAArch64Disassembler() {
+ TargetRegistry::RegisterMCDisassembler(getTheAArch64leTarget(),
+ createAArch64Disassembler);
+ TargetRegistry::RegisterMCDisassembler(getTheAArch64beTarget(),
+ createAArch64Disassembler);
+ TargetRegistry::RegisterMCSymbolizer(getTheAArch64leTarget(),
+ createAArch64ExternalSymbolizer);
+ TargetRegistry::RegisterMCSymbolizer(getTheAArch64beTarget(),
+ createAArch64ExternalSymbolizer);
+ TargetRegistry::RegisterMCDisassembler(getTheAArch64_32Target(),
+ createAArch64Disassembler);
+ TargetRegistry::RegisterMCSymbolizer(getTheAArch64_32Target(),
+ createAArch64ExternalSymbolizer);
+
+ TargetRegistry::RegisterMCDisassembler(getTheARM64Target(),
+ createAArch64Disassembler);
+ TargetRegistry::RegisterMCSymbolizer(getTheARM64Target(),
+ createAArch64ExternalSymbolizer);
+ TargetRegistry::RegisterMCDisassembler(getTheARM64_32Target(),
+ createAArch64Disassembler);
+ TargetRegistry::RegisterMCSymbolizer(getTheARM64_32Target(),
+ createAArch64ExternalSymbolizer);
+}
More information about the llvm-commits
mailing list