[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