Skip to content

Conversation

@jurahul
Copy link
Contributor

@jurahul jurahul commented Aug 21, 2025

Extract fixed functions generated by decoder emitter into a new MCDecoder.h header.

@jurahul jurahul force-pushed the decoder_common_header branch 2 times, most recently from 47c8ff0 to 0b636c8 Compare August 21, 2025 17:41
@jurahul
Copy link
Contributor Author

jurahul commented Aug 21, 2025

Linux failure seems unrelated:
FAIL: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test_moduleSymbols (TestDAP_moduleSymbols.TestDAP_moduleSymbols.test_moduleSymbols)

Will rebase and trigger another run

@llvmbot
Copy link
Member

llvmbot commented Aug 21, 2025

@llvm/pr-subscribers-backend-systemz
@llvm/pr-subscribers-backend-arm
@llvm/pr-subscribers-backend-mips
@llvm/pr-subscribers-backend-xtensa

@llvm/pr-subscribers-backend-loongarch

Author: Rahul Joshi (jurahul)

Changes

Extract fixed functions generated by decoder emitter into a new MCDecoder.h header.


Patch is 23.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154802.diff

23 Files Affected:

  • (added) llvm/include/llvm/MC/MCDecoder.h (+67)
  • (modified) llvm/include/llvm/MC/MCDecoderOps.h (+2-2)
  • (modified) llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+1)
  • (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+10-81)
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h new file mode 100644 index 0000000000000..0eefde02bbb18 --- /dev/null +++ b/llvm/include/llvm/MC/MCDecoder.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Disassembler decoder helper functions. +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCDECODER_H +#define LLVM_MC_MCDECODER_H + +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/Support/MathExtras.h" +#include <cassert> + +namespace llvm::MCD { + +// Helper to propagate SoftFail status. Returns false if the status is Fail; +// callers are expected to early-exit in that condition. (Note, the '&' operator +// is correct to propagate the values of this enum; see comment on 'enum +// DecodeStatus'.) +inline bool Check(MCDisassembler::DecodeStatus &Out, + MCDisassembler::DecodeStatus In) { + Out = static_cast<MCDisassembler::DecodeStatus>(Out & In); + return Out != MCDisassembler::Fail; +} + +// fieldFromInstruction - Extracts a given span of bits from the instruction +// bits and return it as an integer. +template <typename IntType> +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(noinline) +#endif +inline std::enable_if_t<std::is_integral_v<IntType>, IntType> +fieldFromInstruction(const IntType &Insn, unsigned StartBit, unsigned NumBits) { + assert(StartBit + NumBits <= 64 && "Cannot support >64-bit extractions!"); + assert(StartBit + NumBits <= (sizeof(IntType) * 8) && + "Instruction field out of bounds!"); + const IntType Mask = maskTrailingOnes<IntType>(NumBits); + return (Insn >> StartBit) & Mask; +} + +template <typename InsnType> +inline std::enable_if_t<!std::is_integral_v<InsnType>, uint64_t> +fieldFromInstruction(const InsnType &Insn, unsigned StartBit, + unsigned NumBits) { + return Insn.extractBitsAsZExtValue(NumBits, StartBit); +} + +// Helper function for inserting bits extracted from an encoded instruction into +// an integer-typed field. +template <typename IntType> +static std::enable_if_t<std::is_integral_v<IntType>, void> +insertBits(IntType &field, IntType bits, unsigned startBit, unsigned numBits) { + // Check that no bit beyond numBits is set, so that a simple bitwise | + // is sufficient. + assert((~(((IntType)1 << numBits) - 1) & bits) == 0 && + "bits has more than numBits bits set"); + assert(startBit + numBits <= sizeof(IntType) * 8); + (void)numBits; + field |= bits << startBit; +} + +} // namespace llvm::MCD + +#endif // LLVM_MC_MCDECODER_H diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h index 50fcf2a40e26d..dea5b6931250f 100644 --- a/llvm/include/llvm/MC/MCDecoderOps.h +++ b/llvm/include/llvm/MC/MCDecoderOps.h @@ -1,11 +1,11 @@ -//===------------ llvm/MC/MCDecoderOps.h - Decoder driver -------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// Disassembler decoder state machine driver. +// Disassembler decoder state machine ops. //===----------------------------------------------------------------------===// #ifndef LLVM_MC_MCDECODEROPS_H #define LLVM_MC_MCDECODEROPS_H diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index ae984be670fc2..323db2a0728eb 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "TargetInfo/AArch64TargetInfo.h" #include "Utils/AArch64BaseInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCRelocationInfo.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include <memory> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "aarch64-disassembler" diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 070de008d4f59..4b891e48ff273 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -27,6 +27,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstrDesc.h" @@ -605,7 +606,7 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, Bytes = Bytes_.slice(0, MaxInstBytesNum); } - if (isGFX11Plus() && Bytes.size() >= 12 ) { + if (isGFX11Plus() && Bytes.size() >= 12) { DecoderUInt128 DecW = eat12Bytes(Bytes); if (isGFX11() && diff --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp index 6181017559045..f28c7d8fe92a5 100644 --- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp +++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp @@ -16,6 +16,7 @@ #include "MCTargetDesc/ARCMCTargetDesc.h" #include "TargetInfo/ARCTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -24,6 +25,7 @@ #include "llvm/MC/TargetRegistry.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arc-disassembler" diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index cbd31beab8299..af08747d578f0 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/ARMTargetInfo.h" #include "Utils/ARMBaseInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -31,6 +32,7 @@ #include <vector> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arm-disassembler" diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index c7a584868f4e6..948588cb9a754 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -26,6 +27,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "avr-disassembler" diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp index 4dfae81e90191..b5bb1c08c5644 100644 --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp index d78d9acc2aa23..749127f4ddc8a 100644 --- a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp +++ b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp @@ -15,6 +15,7 @@ #include "TargetInfo/CSKYTargetInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index bcddb540d35dc..de10092cbe3c8 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/HexagonTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCExpr.h" diff --git a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp index 5d87c3c4d72cf..c24700b896343 100644 --- a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp +++ b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp @@ -16,6 +16,7 @@ #include "LanaiCondCode.h" #include "LanaiInstrInfo.h" #include "TargetInfo/LanaiTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -247,4 +248,4 @@ static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, return MCDisassembler::Fail; Inst.addOperand(MCOperand::createImm(Val)); return MCDisassembler::Success; -} +} \ No newline at end of file diff --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp index 8c4668ec70c7e..735f798afde24 100644 --- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp +++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "TargetInfo/LoongArchTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp index 4ec18fe6bf544..6ca01e598d95d 100644 --- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp +++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "m68k-disassembler" diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp index 4c5b473982f77..c8094a8eeb361 100644 --- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp +++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp @@ -14,6 +14,7 @@ #include "MSP430.h" #include "TargetInfo/MSP430TargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "msp430-disassembler" diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index b3f6cd1609fbb..0c98c4da2ede1 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/MipsTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -29,6 +30,7 @@ #include <cstdint> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "mips-disassembler" diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 71a76142bb389..5e27f06c94f06 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/PPCMCTargetDesc.h" #include "TargetInfo/PowerPCTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 78be55b3a51d3..d72df741ef287 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -14,6 +14,7 @@ #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "TargetInfo/RISCVTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -25,6 +26,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "riscv-disassembler" diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index fab94fb4d40ca..35207d6301e54 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/SparcTargetInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -21,6 +22,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "sparc-disassembler" diff --git a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp index 31b4f1196392c..0b91aba67694f 100644 --- a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp +++ b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/SystemZMCTargetDesc.h" #include "TargetInfo/SystemZTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp index 88200c5fc97eb..d7e1666a7417d 100644 --- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp +++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp @@ -15,6 +15,7 @@ #include "VE.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -22,6 +23,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "ve-disassembler" diff --git a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index d36f18238f7a3..6921f44b700c5 100644 --- a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -15,6 +15,7 @@ #include "XCore.h" #include "XCoreRegisterInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "xcore-disassembler" diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp index 39bec4785c61c..396b00f7b8628 100644 --- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp +++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/XtensaMCTargetDesc.h" #include "TargetInfo/XtensaTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 95522030300a0..406a8d013e690 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -1104,7 +1104,9 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, // Emit a function for each case first. for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << "template <typename InsnType>\n"; - OS << "DecodeStatus decodeFn" << Index << "(" << DecodeParams << ") {\n"; + OS << "static DecodeStatus decodeFn" << Index << "(" << DecodeParams + << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " " << TmpTypeDecl; OS << " [[maybe_unused]] TmpType tmp;\n"; OS << Decoder; @@ -1117,24 +1119,26 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, OS << "template <typename InsnType>\n"; OS << "static DecodeStatus decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " DecodeComplete = true;\n"; if (UseFnTableInDecodeToMCInst) { - // Build a table of function pointers. + // Build a table of function pointers OS << " using DecodeFnTy = DecodeStatus (*)(" << DecodeParams << ");\n"; OS << " static constexpr DecodeFnTy decodeFnTable[] = {\n"; for (size_t Index : llvm::seq(Decoders.size())) OS << " decodeFn" << Index << ",\n"; OS << " };\n"; OS << " if (Idx >= " << Decoders.size() << ")\n"; - OS << " llvm_unreachable(\"Invalid index!\");\n"; + OS << " llvm_unreachable(\"Invalid decoder index!\");\n"; + OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, " "DecodeComplete);\n"; } else { OS << " " << TmpTypeDecl; OS << " TmpType tmp;\n"; OS << " switch (Idx) {\n"; - OS << " default: llvm_unreachable(\"Invalid index!\");\n"; + OS << " default: llvm_unreachable(\"Invalid decoder index!\");\n"; for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << " case " << Index << ":\n"; OS << Decoder; @@ -2126,65 +2130,6 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef, } } -// emitFieldFromInstruction - Emit the templated helper function -// fieldFromInstruction(). -// On Windows we make sure that this function is not inlined when -// using the VS compiler. It has a bug which causes the function -// to be optimized out in some circumstances. See llvm.org/pr38292 -static void emitFieldFromInstruction(formatted_raw_ostream &OS) { - OS << R"( -// Helper functions for extracting fields from encoded instructions. -// InsnType must either be integral or an APInt-like object that must: -// * be default-constructible and copy-constructible -// * Support extractBitsAsZExtValue(numBits, startBit) -// * Support the ~, &, ==, and != operators with other objects of the same type -// * Support the != and bitwise & with uint64_t -template <typename InsnType> -#if defined(_MSC_VER) && !defined(__clang__) -__declspec(noinline) -#endif -static std::enable_if_t<std::is_integral<InsnType>::value, InsnType> -fieldFromInstruction(... [truncated] 
@llvmbot
Copy link
Member

llvmbot commented Aug 21, 2025

@llvm/pr-subscribers-backend-sparc

Author: Rahul Joshi (jurahul)

Changes

Extract fixed functions generated by decoder emitter into a new MCDecoder.h header.


Patch is 23.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154802.diff

23 Files Affected:

  • (added) llvm/include/llvm/MC/MCDecoder.h (+67)
  • (modified) llvm/include/llvm/MC/MCDecoderOps.h (+2-2)
  • (modified) llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+1)
  • (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+10-81)
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h new file mode 100644 index 0000000000000..0eefde02bbb18 --- /dev/null +++ b/llvm/include/llvm/MC/MCDecoder.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Disassembler decoder helper functions. +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCDECODER_H +#define LLVM_MC_MCDECODER_H + +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/Support/MathExtras.h" +#include <cassert> + +namespace llvm::MCD { + +// Helper to propagate SoftFail status. Returns false if the status is Fail; +// callers are expected to early-exit in that condition. (Note, the '&' operator +// is correct to propagate the values of this enum; see comment on 'enum +// DecodeStatus'.) +inline bool Check(MCDisassembler::DecodeStatus &Out, + MCDisassembler::DecodeStatus In) { + Out = static_cast<MCDisassembler::DecodeStatus>(Out & In); + return Out != MCDisassembler::Fail; +} + +// fieldFromInstruction - Extracts a given span of bits from the instruction +// bits and return it as an integer. +template <typename IntType> +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(noinline) +#endif +inline std::enable_if_t<std::is_integral_v<IntType>, IntType> +fieldFromInstruction(const IntType &Insn, unsigned StartBit, unsigned NumBits) { + assert(StartBit + NumBits <= 64 && "Cannot support >64-bit extractions!"); + assert(StartBit + NumBits <= (sizeof(IntType) * 8) && + "Instruction field out of bounds!"); + const IntType Mask = maskTrailingOnes<IntType>(NumBits); + return (Insn >> StartBit) & Mask; +} + +template <typename InsnType> +inline std::enable_if_t<!std::is_integral_v<InsnType>, uint64_t> +fieldFromInstruction(const InsnType &Insn, unsigned StartBit, + unsigned NumBits) { + return Insn.extractBitsAsZExtValue(NumBits, StartBit); +} + +// Helper function for inserting bits extracted from an encoded instruction into +// an integer-typed field. +template <typename IntType> +static std::enable_if_t<std::is_integral_v<IntType>, void> +insertBits(IntType &field, IntType bits, unsigned startBit, unsigned numBits) { + // Check that no bit beyond numBits is set, so that a simple bitwise | + // is sufficient. + assert((~(((IntType)1 << numBits) - 1) & bits) == 0 && + "bits has more than numBits bits set"); + assert(startBit + numBits <= sizeof(IntType) * 8); + (void)numBits; + field |= bits << startBit; +} + +} // namespace llvm::MCD + +#endif // LLVM_MC_MCDECODER_H diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h index 50fcf2a40e26d..dea5b6931250f 100644 --- a/llvm/include/llvm/MC/MCDecoderOps.h +++ b/llvm/include/llvm/MC/MCDecoderOps.h @@ -1,11 +1,11 @@ -//===------------ llvm/MC/MCDecoderOps.h - Decoder driver -------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// Disassembler decoder state machine driver. +// Disassembler decoder state machine ops. //===----------------------------------------------------------------------===// #ifndef LLVM_MC_MCDECODEROPS_H #define LLVM_MC_MCDECODEROPS_H diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index ae984be670fc2..323db2a0728eb 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "TargetInfo/AArch64TargetInfo.h" #include "Utils/AArch64BaseInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCRelocationInfo.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include <memory> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "aarch64-disassembler" diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 070de008d4f59..4b891e48ff273 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -27,6 +27,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstrDesc.h" @@ -605,7 +606,7 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, Bytes = Bytes_.slice(0, MaxInstBytesNum); } - if (isGFX11Plus() && Bytes.size() >= 12 ) { + if (isGFX11Plus() && Bytes.size() >= 12) { DecoderUInt128 DecW = eat12Bytes(Bytes); if (isGFX11() && diff --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp index 6181017559045..f28c7d8fe92a5 100644 --- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp +++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp @@ -16,6 +16,7 @@ #include "MCTargetDesc/ARCMCTargetDesc.h" #include "TargetInfo/ARCTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -24,6 +25,7 @@ #include "llvm/MC/TargetRegistry.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arc-disassembler" diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index cbd31beab8299..af08747d578f0 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/ARMTargetInfo.h" #include "Utils/ARMBaseInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -31,6 +32,7 @@ #include <vector> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arm-disassembler" diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index c7a584868f4e6..948588cb9a754 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -26,6 +27,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "avr-disassembler" diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp index 4dfae81e90191..b5bb1c08c5644 100644 --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp index d78d9acc2aa23..749127f4ddc8a 100644 --- a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp +++ b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp @@ -15,6 +15,7 @@ #include "TargetInfo/CSKYTargetInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index bcddb540d35dc..de10092cbe3c8 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/HexagonTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCExpr.h" diff --git a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp index 5d87c3c4d72cf..c24700b896343 100644 --- a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp +++ b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp @@ -16,6 +16,7 @@ #include "LanaiCondCode.h" #include "LanaiInstrInfo.h" #include "TargetInfo/LanaiTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -247,4 +248,4 @@ static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, return MCDisassembler::Fail; Inst.addOperand(MCOperand::createImm(Val)); return MCDisassembler::Success; -} +} \ No newline at end of file diff --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp index 8c4668ec70c7e..735f798afde24 100644 --- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp +++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "TargetInfo/LoongArchTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp index 4ec18fe6bf544..6ca01e598d95d 100644 --- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp +++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "m68k-disassembler" diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp index 4c5b473982f77..c8094a8eeb361 100644 --- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp +++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp @@ -14,6 +14,7 @@ #include "MSP430.h" #include "TargetInfo/MSP430TargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "msp430-disassembler" diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index b3f6cd1609fbb..0c98c4da2ede1 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/MipsTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -29,6 +30,7 @@ #include <cstdint> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "mips-disassembler" diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 71a76142bb389..5e27f06c94f06 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/PPCMCTargetDesc.h" #include "TargetInfo/PowerPCTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 78be55b3a51d3..d72df741ef287 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -14,6 +14,7 @@ #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "TargetInfo/RISCVTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -25,6 +26,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "riscv-disassembler" diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index fab94fb4d40ca..35207d6301e54 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/SparcTargetInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -21,6 +22,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "sparc-disassembler" diff --git a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp index 31b4f1196392c..0b91aba67694f 100644 --- a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp +++ b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/SystemZMCTargetDesc.h" #include "TargetInfo/SystemZTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp index 88200c5fc97eb..d7e1666a7417d 100644 --- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp +++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp @@ -15,6 +15,7 @@ #include "VE.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -22,6 +23,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "ve-disassembler" diff --git a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index d36f18238f7a3..6921f44b700c5 100644 --- a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -15,6 +15,7 @@ #include "XCore.h" #include "XCoreRegisterInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "xcore-disassembler" diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp index 39bec4785c61c..396b00f7b8628 100644 --- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp +++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/XtensaMCTargetDesc.h" #include "TargetInfo/XtensaTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 95522030300a0..406a8d013e690 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -1104,7 +1104,9 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, // Emit a function for each case first. for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << "template <typename InsnType>\n"; - OS << "DecodeStatus decodeFn" << Index << "(" << DecodeParams << ") {\n"; + OS << "static DecodeStatus decodeFn" << Index << "(" << DecodeParams + << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " " << TmpTypeDecl; OS << " [[maybe_unused]] TmpType tmp;\n"; OS << Decoder; @@ -1117,24 +1119,26 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, OS << "template <typename InsnType>\n"; OS << "static DecodeStatus decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " DecodeComplete = true;\n"; if (UseFnTableInDecodeToMCInst) { - // Build a table of function pointers. + // Build a table of function pointers OS << " using DecodeFnTy = DecodeStatus (*)(" << DecodeParams << ");\n"; OS << " static constexpr DecodeFnTy decodeFnTable[] = {\n"; for (size_t Index : llvm::seq(Decoders.size())) OS << " decodeFn" << Index << ",\n"; OS << " };\n"; OS << " if (Idx >= " << Decoders.size() << ")\n"; - OS << " llvm_unreachable(\"Invalid index!\");\n"; + OS << " llvm_unreachable(\"Invalid decoder index!\");\n"; + OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, " "DecodeComplete);\n"; } else { OS << " " << TmpTypeDecl; OS << " TmpType tmp;\n"; OS << " switch (Idx) {\n"; - OS << " default: llvm_unreachable(\"Invalid index!\");\n"; + OS << " default: llvm_unreachable(\"Invalid decoder index!\");\n"; for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << " case " << Index << ":\n"; OS << Decoder; @@ -2126,65 +2130,6 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef, } } -// emitFieldFromInstruction - Emit the templated helper function -// fieldFromInstruction(). -// On Windows we make sure that this function is not inlined when -// using the VS compiler. It has a bug which causes the function -// to be optimized out in some circumstances. See llvm.org/pr38292 -static void emitFieldFromInstruction(formatted_raw_ostream &OS) { - OS << R"( -// Helper functions for extracting fields from encoded instructions. -// InsnType must either be integral or an APInt-like object that must: -// * be default-constructible and copy-constructible -// * Support extractBitsAsZExtValue(numBits, startBit) -// * Support the ~, &, ==, and != operators with other objects of the same type -// * Support the != and bitwise & with uint64_t -template <typename InsnType> -#if defined(_MSC_VER) && !defined(__clang__) -__declspec(noinline) -#endif -static std::enable_if_t<std::is_integral<InsnType>::value, InsnType> -fieldFromInstruction(... [truncated] 
@llvmbot
Copy link
Member

llvmbot commented Aug 21, 2025

@llvm/pr-subscribers-backend-msp430

Author: Rahul Joshi (jurahul)

Changes

Extract fixed functions generated by decoder emitter into a new MCDecoder.h header.


Patch is 23.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154802.diff

23 Files Affected:

  • (added) llvm/include/llvm/MC/MCDecoder.h (+67)
  • (modified) llvm/include/llvm/MC/MCDecoderOps.h (+2-2)
  • (modified) llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+1)
  • (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+10-81)
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h new file mode 100644 index 0000000000000..0eefde02bbb18 --- /dev/null +++ b/llvm/include/llvm/MC/MCDecoder.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Disassembler decoder helper functions. +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCDECODER_H +#define LLVM_MC_MCDECODER_H + +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/Support/MathExtras.h" +#include <cassert> + +namespace llvm::MCD { + +// Helper to propagate SoftFail status. Returns false if the status is Fail; +// callers are expected to early-exit in that condition. (Note, the '&' operator +// is correct to propagate the values of this enum; see comment on 'enum +// DecodeStatus'.) +inline bool Check(MCDisassembler::DecodeStatus &Out, + MCDisassembler::DecodeStatus In) { + Out = static_cast<MCDisassembler::DecodeStatus>(Out & In); + return Out != MCDisassembler::Fail; +} + +// fieldFromInstruction - Extracts a given span of bits from the instruction +// bits and return it as an integer. +template <typename IntType> +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(noinline) +#endif +inline std::enable_if_t<std::is_integral_v<IntType>, IntType> +fieldFromInstruction(const IntType &Insn, unsigned StartBit, unsigned NumBits) { + assert(StartBit + NumBits <= 64 && "Cannot support >64-bit extractions!"); + assert(StartBit + NumBits <= (sizeof(IntType) * 8) && + "Instruction field out of bounds!"); + const IntType Mask = maskTrailingOnes<IntType>(NumBits); + return (Insn >> StartBit) & Mask; +} + +template <typename InsnType> +inline std::enable_if_t<!std::is_integral_v<InsnType>, uint64_t> +fieldFromInstruction(const InsnType &Insn, unsigned StartBit, + unsigned NumBits) { + return Insn.extractBitsAsZExtValue(NumBits, StartBit); +} + +// Helper function for inserting bits extracted from an encoded instruction into +// an integer-typed field. +template <typename IntType> +static std::enable_if_t<std::is_integral_v<IntType>, void> +insertBits(IntType &field, IntType bits, unsigned startBit, unsigned numBits) { + // Check that no bit beyond numBits is set, so that a simple bitwise | + // is sufficient. + assert((~(((IntType)1 << numBits) - 1) & bits) == 0 && + "bits has more than numBits bits set"); + assert(startBit + numBits <= sizeof(IntType) * 8); + (void)numBits; + field |= bits << startBit; +} + +} // namespace llvm::MCD + +#endif // LLVM_MC_MCDECODER_H diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h index 50fcf2a40e26d..dea5b6931250f 100644 --- a/llvm/include/llvm/MC/MCDecoderOps.h +++ b/llvm/include/llvm/MC/MCDecoderOps.h @@ -1,11 +1,11 @@ -//===------------ llvm/MC/MCDecoderOps.h - Decoder driver -------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// Disassembler decoder state machine driver. +// Disassembler decoder state machine ops. //===----------------------------------------------------------------------===// #ifndef LLVM_MC_MCDECODEROPS_H #define LLVM_MC_MCDECODEROPS_H diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index ae984be670fc2..323db2a0728eb 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "TargetInfo/AArch64TargetInfo.h" #include "Utils/AArch64BaseInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCRelocationInfo.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include <memory> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "aarch64-disassembler" diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 070de008d4f59..4b891e48ff273 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -27,6 +27,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstrDesc.h" @@ -605,7 +606,7 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, Bytes = Bytes_.slice(0, MaxInstBytesNum); } - if (isGFX11Plus() && Bytes.size() >= 12 ) { + if (isGFX11Plus() && Bytes.size() >= 12) { DecoderUInt128 DecW = eat12Bytes(Bytes); if (isGFX11() && diff --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp index 6181017559045..f28c7d8fe92a5 100644 --- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp +++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp @@ -16,6 +16,7 @@ #include "MCTargetDesc/ARCMCTargetDesc.h" #include "TargetInfo/ARCTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -24,6 +25,7 @@ #include "llvm/MC/TargetRegistry.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arc-disassembler" diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index cbd31beab8299..af08747d578f0 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/ARMTargetInfo.h" #include "Utils/ARMBaseInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -31,6 +32,7 @@ #include <vector> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arm-disassembler" diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index c7a584868f4e6..948588cb9a754 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -26,6 +27,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "avr-disassembler" diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp index 4dfae81e90191..b5bb1c08c5644 100644 --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp index d78d9acc2aa23..749127f4ddc8a 100644 --- a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp +++ b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp @@ -15,6 +15,7 @@ #include "TargetInfo/CSKYTargetInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index bcddb540d35dc..de10092cbe3c8 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/HexagonTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCExpr.h" diff --git a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp index 5d87c3c4d72cf..c24700b896343 100644 --- a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp +++ b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp @@ -16,6 +16,7 @@ #include "LanaiCondCode.h" #include "LanaiInstrInfo.h" #include "TargetInfo/LanaiTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -247,4 +248,4 @@ static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, return MCDisassembler::Fail; Inst.addOperand(MCOperand::createImm(Val)); return MCDisassembler::Success; -} +} \ No newline at end of file diff --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp index 8c4668ec70c7e..735f798afde24 100644 --- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp +++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "TargetInfo/LoongArchTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp index 4ec18fe6bf544..6ca01e598d95d 100644 --- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp +++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "m68k-disassembler" diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp index 4c5b473982f77..c8094a8eeb361 100644 --- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp +++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp @@ -14,6 +14,7 @@ #include "MSP430.h" #include "TargetInfo/MSP430TargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "msp430-disassembler" diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index b3f6cd1609fbb..0c98c4da2ede1 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/MipsTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -29,6 +30,7 @@ #include <cstdint> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "mips-disassembler" diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 71a76142bb389..5e27f06c94f06 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/PPCMCTargetDesc.h" #include "TargetInfo/PowerPCTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 78be55b3a51d3..d72df741ef287 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -14,6 +14,7 @@ #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "TargetInfo/RISCVTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -25,6 +26,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "riscv-disassembler" diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index fab94fb4d40ca..35207d6301e54 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/SparcTargetInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -21,6 +22,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "sparc-disassembler" diff --git a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp index 31b4f1196392c..0b91aba67694f 100644 --- a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp +++ b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/SystemZMCTargetDesc.h" #include "TargetInfo/SystemZTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp index 88200c5fc97eb..d7e1666a7417d 100644 --- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp +++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp @@ -15,6 +15,7 @@ #include "VE.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -22,6 +23,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "ve-disassembler" diff --git a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index d36f18238f7a3..6921f44b700c5 100644 --- a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -15,6 +15,7 @@ #include "XCore.h" #include "XCoreRegisterInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "xcore-disassembler" diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp index 39bec4785c61c..396b00f7b8628 100644 --- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp +++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/XtensaMCTargetDesc.h" #include "TargetInfo/XtensaTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 95522030300a0..406a8d013e690 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -1104,7 +1104,9 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, // Emit a function for each case first. for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << "template <typename InsnType>\n"; - OS << "DecodeStatus decodeFn" << Index << "(" << DecodeParams << ") {\n"; + OS << "static DecodeStatus decodeFn" << Index << "(" << DecodeParams + << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " " << TmpTypeDecl; OS << " [[maybe_unused]] TmpType tmp;\n"; OS << Decoder; @@ -1117,24 +1119,26 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, OS << "template <typename InsnType>\n"; OS << "static DecodeStatus decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " DecodeComplete = true;\n"; if (UseFnTableInDecodeToMCInst) { - // Build a table of function pointers. + // Build a table of function pointers OS << " using DecodeFnTy = DecodeStatus (*)(" << DecodeParams << ");\n"; OS << " static constexpr DecodeFnTy decodeFnTable[] = {\n"; for (size_t Index : llvm::seq(Decoders.size())) OS << " decodeFn" << Index << ",\n"; OS << " };\n"; OS << " if (Idx >= " << Decoders.size() << ")\n"; - OS << " llvm_unreachable(\"Invalid index!\");\n"; + OS << " llvm_unreachable(\"Invalid decoder index!\");\n"; + OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, " "DecodeComplete);\n"; } else { OS << " " << TmpTypeDecl; OS << " TmpType tmp;\n"; OS << " switch (Idx) {\n"; - OS << " default: llvm_unreachable(\"Invalid index!\");\n"; + OS << " default: llvm_unreachable(\"Invalid decoder index!\");\n"; for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << " case " << Index << ":\n"; OS << Decoder; @@ -2126,65 +2130,6 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef, } } -// emitFieldFromInstruction - Emit the templated helper function -// fieldFromInstruction(). -// On Windows we make sure that this function is not inlined when -// using the VS compiler. It has a bug which causes the function -// to be optimized out in some circumstances. See llvm.org/pr38292 -static void emitFieldFromInstruction(formatted_raw_ostream &OS) { - OS << R"( -// Helper functions for extracting fields from encoded instructions. -// InsnType must either be integral or an APInt-like object that must: -// * be default-constructible and copy-constructible -// * Support extractBitsAsZExtValue(numBits, startBit) -// * Support the ~, &, ==, and != operators with other objects of the same type -// * Support the != and bitwise & with uint64_t -template <typename InsnType> -#if defined(_MSC_VER) && !defined(__clang__) -__declspec(noinline) -#endif -static std::enable_if_t<std::is_integral<InsnType>::value, InsnType> -fieldFromInstruction(... [truncated] 
@llvmbot
Copy link
Member

llvmbot commented Aug 21, 2025

@llvm/pr-subscribers-backend-powerpc

Author: Rahul Joshi (jurahul)

Changes

Extract fixed functions generated by decoder emitter into a new MCDecoder.h header.


Patch is 23.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154802.diff

23 Files Affected:

  • (added) llvm/include/llvm/MC/MCDecoder.h (+67)
  • (modified) llvm/include/llvm/MC/MCDecoderOps.h (+2-2)
  • (modified) llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+1)
  • (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+10-81)
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h new file mode 100644 index 0000000000000..0eefde02bbb18 --- /dev/null +++ b/llvm/include/llvm/MC/MCDecoder.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Disassembler decoder helper functions. +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCDECODER_H +#define LLVM_MC_MCDECODER_H + +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/Support/MathExtras.h" +#include <cassert> + +namespace llvm::MCD { + +// Helper to propagate SoftFail status. Returns false if the status is Fail; +// callers are expected to early-exit in that condition. (Note, the '&' operator +// is correct to propagate the values of this enum; see comment on 'enum +// DecodeStatus'.) +inline bool Check(MCDisassembler::DecodeStatus &Out, + MCDisassembler::DecodeStatus In) { + Out = static_cast<MCDisassembler::DecodeStatus>(Out & In); + return Out != MCDisassembler::Fail; +} + +// fieldFromInstruction - Extracts a given span of bits from the instruction +// bits and return it as an integer. +template <typename IntType> +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(noinline) +#endif +inline std::enable_if_t<std::is_integral_v<IntType>, IntType> +fieldFromInstruction(const IntType &Insn, unsigned StartBit, unsigned NumBits) { + assert(StartBit + NumBits <= 64 && "Cannot support >64-bit extractions!"); + assert(StartBit + NumBits <= (sizeof(IntType) * 8) && + "Instruction field out of bounds!"); + const IntType Mask = maskTrailingOnes<IntType>(NumBits); + return (Insn >> StartBit) & Mask; +} + +template <typename InsnType> +inline std::enable_if_t<!std::is_integral_v<InsnType>, uint64_t> +fieldFromInstruction(const InsnType &Insn, unsigned StartBit, + unsigned NumBits) { + return Insn.extractBitsAsZExtValue(NumBits, StartBit); +} + +// Helper function for inserting bits extracted from an encoded instruction into +// an integer-typed field. +template <typename IntType> +static std::enable_if_t<std::is_integral_v<IntType>, void> +insertBits(IntType &field, IntType bits, unsigned startBit, unsigned numBits) { + // Check that no bit beyond numBits is set, so that a simple bitwise | + // is sufficient. + assert((~(((IntType)1 << numBits) - 1) & bits) == 0 && + "bits has more than numBits bits set"); + assert(startBit + numBits <= sizeof(IntType) * 8); + (void)numBits; + field |= bits << startBit; +} + +} // namespace llvm::MCD + +#endif // LLVM_MC_MCDECODER_H diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h index 50fcf2a40e26d..dea5b6931250f 100644 --- a/llvm/include/llvm/MC/MCDecoderOps.h +++ b/llvm/include/llvm/MC/MCDecoderOps.h @@ -1,11 +1,11 @@ -//===------------ llvm/MC/MCDecoderOps.h - Decoder driver -------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// Disassembler decoder state machine driver. +// Disassembler decoder state machine ops. //===----------------------------------------------------------------------===// #ifndef LLVM_MC_MCDECODEROPS_H #define LLVM_MC_MCDECODEROPS_H diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index ae984be670fc2..323db2a0728eb 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "TargetInfo/AArch64TargetInfo.h" #include "Utils/AArch64BaseInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCRelocationInfo.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include <memory> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "aarch64-disassembler" diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 070de008d4f59..4b891e48ff273 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -27,6 +27,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstrDesc.h" @@ -605,7 +606,7 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, Bytes = Bytes_.slice(0, MaxInstBytesNum); } - if (isGFX11Plus() && Bytes.size() >= 12 ) { + if (isGFX11Plus() && Bytes.size() >= 12) { DecoderUInt128 DecW = eat12Bytes(Bytes); if (isGFX11() && diff --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp index 6181017559045..f28c7d8fe92a5 100644 --- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp +++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp @@ -16,6 +16,7 @@ #include "MCTargetDesc/ARCMCTargetDesc.h" #include "TargetInfo/ARCTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -24,6 +25,7 @@ #include "llvm/MC/TargetRegistry.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arc-disassembler" diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index cbd31beab8299..af08747d578f0 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/ARMTargetInfo.h" #include "Utils/ARMBaseInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -31,6 +32,7 @@ #include <vector> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arm-disassembler" diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index c7a584868f4e6..948588cb9a754 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -26,6 +27,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "avr-disassembler" diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp index 4dfae81e90191..b5bb1c08c5644 100644 --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp index d78d9acc2aa23..749127f4ddc8a 100644 --- a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp +++ b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp @@ -15,6 +15,7 @@ #include "TargetInfo/CSKYTargetInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index bcddb540d35dc..de10092cbe3c8 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/HexagonTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCExpr.h" diff --git a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp index 5d87c3c4d72cf..c24700b896343 100644 --- a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp +++ b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp @@ -16,6 +16,7 @@ #include "LanaiCondCode.h" #include "LanaiInstrInfo.h" #include "TargetInfo/LanaiTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -247,4 +248,4 @@ static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, return MCDisassembler::Fail; Inst.addOperand(MCOperand::createImm(Val)); return MCDisassembler::Success; -} +} \ No newline at end of file diff --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp index 8c4668ec70c7e..735f798afde24 100644 --- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp +++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "TargetInfo/LoongArchTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp index 4ec18fe6bf544..6ca01e598d95d 100644 --- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp +++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "m68k-disassembler" diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp index 4c5b473982f77..c8094a8eeb361 100644 --- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp +++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp @@ -14,6 +14,7 @@ #include "MSP430.h" #include "TargetInfo/MSP430TargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "msp430-disassembler" diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index b3f6cd1609fbb..0c98c4da2ede1 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/MipsTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -29,6 +30,7 @@ #include <cstdint> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "mips-disassembler" diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 71a76142bb389..5e27f06c94f06 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/PPCMCTargetDesc.h" #include "TargetInfo/PowerPCTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 78be55b3a51d3..d72df741ef287 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -14,6 +14,7 @@ #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "TargetInfo/RISCVTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -25,6 +26,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "riscv-disassembler" diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index fab94fb4d40ca..35207d6301e54 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/SparcTargetInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -21,6 +22,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "sparc-disassembler" diff --git a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp index 31b4f1196392c..0b91aba67694f 100644 --- a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp +++ b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/SystemZMCTargetDesc.h" #include "TargetInfo/SystemZTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp index 88200c5fc97eb..d7e1666a7417d 100644 --- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp +++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp @@ -15,6 +15,7 @@ #include "VE.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -22,6 +23,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "ve-disassembler" diff --git a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index d36f18238f7a3..6921f44b700c5 100644 --- a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -15,6 +15,7 @@ #include "XCore.h" #include "XCoreRegisterInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "xcore-disassembler" diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp index 39bec4785c61c..396b00f7b8628 100644 --- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp +++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/XtensaMCTargetDesc.h" #include "TargetInfo/XtensaTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 95522030300a0..406a8d013e690 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -1104,7 +1104,9 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, // Emit a function for each case first. for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << "template <typename InsnType>\n"; - OS << "DecodeStatus decodeFn" << Index << "(" << DecodeParams << ") {\n"; + OS << "static DecodeStatus decodeFn" << Index << "(" << DecodeParams + << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " " << TmpTypeDecl; OS << " [[maybe_unused]] TmpType tmp;\n"; OS << Decoder; @@ -1117,24 +1119,26 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, OS << "template <typename InsnType>\n"; OS << "static DecodeStatus decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " DecodeComplete = true;\n"; if (UseFnTableInDecodeToMCInst) { - // Build a table of function pointers. + // Build a table of function pointers OS << " using DecodeFnTy = DecodeStatus (*)(" << DecodeParams << ");\n"; OS << " static constexpr DecodeFnTy decodeFnTable[] = {\n"; for (size_t Index : llvm::seq(Decoders.size())) OS << " decodeFn" << Index << ",\n"; OS << " };\n"; OS << " if (Idx >= " << Decoders.size() << ")\n"; - OS << " llvm_unreachable(\"Invalid index!\");\n"; + OS << " llvm_unreachable(\"Invalid decoder index!\");\n"; + OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, " "DecodeComplete);\n"; } else { OS << " " << TmpTypeDecl; OS << " TmpType tmp;\n"; OS << " switch (Idx) {\n"; - OS << " default: llvm_unreachable(\"Invalid index!\");\n"; + OS << " default: llvm_unreachable(\"Invalid decoder index!\");\n"; for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << " case " << Index << ":\n"; OS << Decoder; @@ -2126,65 +2130,6 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef, } } -// emitFieldFromInstruction - Emit the templated helper function -// fieldFromInstruction(). -// On Windows we make sure that this function is not inlined when -// using the VS compiler. It has a bug which causes the function -// to be optimized out in some circumstances. See llvm.org/pr38292 -static void emitFieldFromInstruction(formatted_raw_ostream &OS) { - OS << R"( -// Helper functions for extracting fields from encoded instructions. -// InsnType must either be integral or an APInt-like object that must: -// * be default-constructible and copy-constructible -// * Support extractBitsAsZExtValue(numBits, startBit) -// * Support the ~, &, ==, and != operators with other objects of the same type -// * Support the != and bitwise & with uint64_t -template <typename InsnType> -#if defined(_MSC_VER) && !defined(__clang__) -__declspec(noinline) -#endif -static std::enable_if_t<std::is_integral<InsnType>::value, InsnType> -fieldFromInstruction(... [truncated] 
@llvmbot
Copy link
Member

llvmbot commented Aug 21, 2025

@llvm/pr-subscribers-backend-m68k

Author: Rahul Joshi (jurahul)

Changes

Extract fixed functions generated by decoder emitter into a new MCDecoder.h header.


Patch is 23.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154802.diff

23 Files Affected:

  • (added) llvm/include/llvm/MC/MCDecoder.h (+67)
  • (modified) llvm/include/llvm/MC/MCDecoderOps.h (+2-2)
  • (modified) llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+1)
  • (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+10-81)
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h new file mode 100644 index 0000000000000..0eefde02bbb18 --- /dev/null +++ b/llvm/include/llvm/MC/MCDecoder.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Disassembler decoder helper functions. +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCDECODER_H +#define LLVM_MC_MCDECODER_H + +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/Support/MathExtras.h" +#include <cassert> + +namespace llvm::MCD { + +// Helper to propagate SoftFail status. Returns false if the status is Fail; +// callers are expected to early-exit in that condition. (Note, the '&' operator +// is correct to propagate the values of this enum; see comment on 'enum +// DecodeStatus'.) +inline bool Check(MCDisassembler::DecodeStatus &Out, + MCDisassembler::DecodeStatus In) { + Out = static_cast<MCDisassembler::DecodeStatus>(Out & In); + return Out != MCDisassembler::Fail; +} + +// fieldFromInstruction - Extracts a given span of bits from the instruction +// bits and return it as an integer. +template <typename IntType> +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(noinline) +#endif +inline std::enable_if_t<std::is_integral_v<IntType>, IntType> +fieldFromInstruction(const IntType &Insn, unsigned StartBit, unsigned NumBits) { + assert(StartBit + NumBits <= 64 && "Cannot support >64-bit extractions!"); + assert(StartBit + NumBits <= (sizeof(IntType) * 8) && + "Instruction field out of bounds!"); + const IntType Mask = maskTrailingOnes<IntType>(NumBits); + return (Insn >> StartBit) & Mask; +} + +template <typename InsnType> +inline std::enable_if_t<!std::is_integral_v<InsnType>, uint64_t> +fieldFromInstruction(const InsnType &Insn, unsigned StartBit, + unsigned NumBits) { + return Insn.extractBitsAsZExtValue(NumBits, StartBit); +} + +// Helper function for inserting bits extracted from an encoded instruction into +// an integer-typed field. +template <typename IntType> +static std::enable_if_t<std::is_integral_v<IntType>, void> +insertBits(IntType &field, IntType bits, unsigned startBit, unsigned numBits) { + // Check that no bit beyond numBits is set, so that a simple bitwise | + // is sufficient. + assert((~(((IntType)1 << numBits) - 1) & bits) == 0 && + "bits has more than numBits bits set"); + assert(startBit + numBits <= sizeof(IntType) * 8); + (void)numBits; + field |= bits << startBit; +} + +} // namespace llvm::MCD + +#endif // LLVM_MC_MCDECODER_H diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h index 50fcf2a40e26d..dea5b6931250f 100644 --- a/llvm/include/llvm/MC/MCDecoderOps.h +++ b/llvm/include/llvm/MC/MCDecoderOps.h @@ -1,11 +1,11 @@ -//===------------ llvm/MC/MCDecoderOps.h - Decoder driver -------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// Disassembler decoder state machine driver. +// Disassembler decoder state machine ops. //===----------------------------------------------------------------------===// #ifndef LLVM_MC_MCDECODEROPS_H #define LLVM_MC_MCDECODEROPS_H diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index ae984be670fc2..323db2a0728eb 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "TargetInfo/AArch64TargetInfo.h" #include "Utils/AArch64BaseInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCRelocationInfo.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include <memory> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "aarch64-disassembler" diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 070de008d4f59..4b891e48ff273 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -27,6 +27,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstrDesc.h" @@ -605,7 +606,7 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, Bytes = Bytes_.slice(0, MaxInstBytesNum); } - if (isGFX11Plus() && Bytes.size() >= 12 ) { + if (isGFX11Plus() && Bytes.size() >= 12) { DecoderUInt128 DecW = eat12Bytes(Bytes); if (isGFX11() && diff --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp index 6181017559045..f28c7d8fe92a5 100644 --- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp +++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp @@ -16,6 +16,7 @@ #include "MCTargetDesc/ARCMCTargetDesc.h" #include "TargetInfo/ARCTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -24,6 +25,7 @@ #include "llvm/MC/TargetRegistry.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arc-disassembler" diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index cbd31beab8299..af08747d578f0 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/ARMTargetInfo.h" #include "Utils/ARMBaseInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -31,6 +32,7 @@ #include <vector> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arm-disassembler" diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index c7a584868f4e6..948588cb9a754 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -26,6 +27,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "avr-disassembler" diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp index 4dfae81e90191..b5bb1c08c5644 100644 --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp index d78d9acc2aa23..749127f4ddc8a 100644 --- a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp +++ b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp @@ -15,6 +15,7 @@ #include "TargetInfo/CSKYTargetInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index bcddb540d35dc..de10092cbe3c8 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/HexagonTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCExpr.h" diff --git a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp index 5d87c3c4d72cf..c24700b896343 100644 --- a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp +++ b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp @@ -16,6 +16,7 @@ #include "LanaiCondCode.h" #include "LanaiInstrInfo.h" #include "TargetInfo/LanaiTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -247,4 +248,4 @@ static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, return MCDisassembler::Fail; Inst.addOperand(MCOperand::createImm(Val)); return MCDisassembler::Success; -} +} \ No newline at end of file diff --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp index 8c4668ec70c7e..735f798afde24 100644 --- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp +++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "TargetInfo/LoongArchTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp index 4ec18fe6bf544..6ca01e598d95d 100644 --- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp +++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "m68k-disassembler" diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp index 4c5b473982f77..c8094a8eeb361 100644 --- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp +++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp @@ -14,6 +14,7 @@ #include "MSP430.h" #include "TargetInfo/MSP430TargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "msp430-disassembler" diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index b3f6cd1609fbb..0c98c4da2ede1 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/MipsTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -29,6 +30,7 @@ #include <cstdint> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "mips-disassembler" diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 71a76142bb389..5e27f06c94f06 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/PPCMCTargetDesc.h" #include "TargetInfo/PowerPCTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 78be55b3a51d3..d72df741ef287 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -14,6 +14,7 @@ #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "TargetInfo/RISCVTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -25,6 +26,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "riscv-disassembler" diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index fab94fb4d40ca..35207d6301e54 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/SparcTargetInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -21,6 +22,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "sparc-disassembler" diff --git a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp index 31b4f1196392c..0b91aba67694f 100644 --- a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp +++ b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/SystemZMCTargetDesc.h" #include "TargetInfo/SystemZTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp index 88200c5fc97eb..d7e1666a7417d 100644 --- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp +++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp @@ -15,6 +15,7 @@ #include "VE.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -22,6 +23,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "ve-disassembler" diff --git a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index d36f18238f7a3..6921f44b700c5 100644 --- a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -15,6 +15,7 @@ #include "XCore.h" #include "XCoreRegisterInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "xcore-disassembler" diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp index 39bec4785c61c..396b00f7b8628 100644 --- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp +++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/XtensaMCTargetDesc.h" #include "TargetInfo/XtensaTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 95522030300a0..406a8d013e690 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -1104,7 +1104,9 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, // Emit a function for each case first. for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << "template <typename InsnType>\n"; - OS << "DecodeStatus decodeFn" << Index << "(" << DecodeParams << ") {\n"; + OS << "static DecodeStatus decodeFn" << Index << "(" << DecodeParams + << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " " << TmpTypeDecl; OS << " [[maybe_unused]] TmpType tmp;\n"; OS << Decoder; @@ -1117,24 +1119,26 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, OS << "template <typename InsnType>\n"; OS << "static DecodeStatus decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " DecodeComplete = true;\n"; if (UseFnTableInDecodeToMCInst) { - // Build a table of function pointers. + // Build a table of function pointers OS << " using DecodeFnTy = DecodeStatus (*)(" << DecodeParams << ");\n"; OS << " static constexpr DecodeFnTy decodeFnTable[] = {\n"; for (size_t Index : llvm::seq(Decoders.size())) OS << " decodeFn" << Index << ",\n"; OS << " };\n"; OS << " if (Idx >= " << Decoders.size() << ")\n"; - OS << " llvm_unreachable(\"Invalid index!\");\n"; + OS << " llvm_unreachable(\"Invalid decoder index!\");\n"; + OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, " "DecodeComplete);\n"; } else { OS << " " << TmpTypeDecl; OS << " TmpType tmp;\n"; OS << " switch (Idx) {\n"; - OS << " default: llvm_unreachable(\"Invalid index!\");\n"; + OS << " default: llvm_unreachable(\"Invalid decoder index!\");\n"; for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << " case " << Index << ":\n"; OS << Decoder; @@ -2126,65 +2130,6 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef, } } -// emitFieldFromInstruction - Emit the templated helper function -// fieldFromInstruction(). -// On Windows we make sure that this function is not inlined when -// using the VS compiler. It has a bug which causes the function -// to be optimized out in some circumstances. See llvm.org/pr38292 -static void emitFieldFromInstruction(formatted_raw_ostream &OS) { - OS << R"( -// Helper functions for extracting fields from encoded instructions. -// InsnType must either be integral or an APInt-like object that must: -// * be default-constructible and copy-constructible -// * Support extractBitsAsZExtValue(numBits, startBit) -// * Support the ~, &, ==, and != operators with other objects of the same type -// * Support the != and bitwise & with uint64_t -template <typename InsnType> -#if defined(_MSC_VER) && !defined(__clang__) -__declspec(noinline) -#endif -static std::enable_if_t<std::is_integral<InsnType>::value, InsnType> -fieldFromInstruction(... [truncated] 
@llvmbot
Copy link
Member

llvmbot commented Aug 21, 2025

@llvm/pr-subscribers-backend-aarch64

Author: Rahul Joshi (jurahul)

Changes

Extract fixed functions generated by decoder emitter into a new MCDecoder.h header.


Patch is 23.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154802.diff

23 Files Affected:

  • (added) llvm/include/llvm/MC/MCDecoder.h (+67)
  • (modified) llvm/include/llvm/MC/MCDecoderOps.h (+2-2)
  • (modified) llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+1)
  • (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+10-81)
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h new file mode 100644 index 0000000000000..0eefde02bbb18 --- /dev/null +++ b/llvm/include/llvm/MC/MCDecoder.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Disassembler decoder helper functions. +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCDECODER_H +#define LLVM_MC_MCDECODER_H + +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/Support/MathExtras.h" +#include <cassert> + +namespace llvm::MCD { + +// Helper to propagate SoftFail status. Returns false if the status is Fail; +// callers are expected to early-exit in that condition. (Note, the '&' operator +// is correct to propagate the values of this enum; see comment on 'enum +// DecodeStatus'.) +inline bool Check(MCDisassembler::DecodeStatus &Out, + MCDisassembler::DecodeStatus In) { + Out = static_cast<MCDisassembler::DecodeStatus>(Out & In); + return Out != MCDisassembler::Fail; +} + +// fieldFromInstruction - Extracts a given span of bits from the instruction +// bits and return it as an integer. +template <typename IntType> +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(noinline) +#endif +inline std::enable_if_t<std::is_integral_v<IntType>, IntType> +fieldFromInstruction(const IntType &Insn, unsigned StartBit, unsigned NumBits) { + assert(StartBit + NumBits <= 64 && "Cannot support >64-bit extractions!"); + assert(StartBit + NumBits <= (sizeof(IntType) * 8) && + "Instruction field out of bounds!"); + const IntType Mask = maskTrailingOnes<IntType>(NumBits); + return (Insn >> StartBit) & Mask; +} + +template <typename InsnType> +inline std::enable_if_t<!std::is_integral_v<InsnType>, uint64_t> +fieldFromInstruction(const InsnType &Insn, unsigned StartBit, + unsigned NumBits) { + return Insn.extractBitsAsZExtValue(NumBits, StartBit); +} + +// Helper function for inserting bits extracted from an encoded instruction into +// an integer-typed field. +template <typename IntType> +static std::enable_if_t<std::is_integral_v<IntType>, void> +insertBits(IntType &field, IntType bits, unsigned startBit, unsigned numBits) { + // Check that no bit beyond numBits is set, so that a simple bitwise | + // is sufficient. + assert((~(((IntType)1 << numBits) - 1) & bits) == 0 && + "bits has more than numBits bits set"); + assert(startBit + numBits <= sizeof(IntType) * 8); + (void)numBits; + field |= bits << startBit; +} + +} // namespace llvm::MCD + +#endif // LLVM_MC_MCDECODER_H diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h index 50fcf2a40e26d..dea5b6931250f 100644 --- a/llvm/include/llvm/MC/MCDecoderOps.h +++ b/llvm/include/llvm/MC/MCDecoderOps.h @@ -1,11 +1,11 @@ -//===------------ llvm/MC/MCDecoderOps.h - Decoder driver -------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// Disassembler decoder state machine driver. +// Disassembler decoder state machine ops. //===----------------------------------------------------------------------===// #ifndef LLVM_MC_MCDECODEROPS_H #define LLVM_MC_MCDECODEROPS_H diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index ae984be670fc2..323db2a0728eb 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "TargetInfo/AArch64TargetInfo.h" #include "Utils/AArch64BaseInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCRelocationInfo.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include <memory> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "aarch64-disassembler" diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 070de008d4f59..4b891e48ff273 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -27,6 +27,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstrDesc.h" @@ -605,7 +606,7 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, Bytes = Bytes_.slice(0, MaxInstBytesNum); } - if (isGFX11Plus() && Bytes.size() >= 12 ) { + if (isGFX11Plus() && Bytes.size() >= 12) { DecoderUInt128 DecW = eat12Bytes(Bytes); if (isGFX11() && diff --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp index 6181017559045..f28c7d8fe92a5 100644 --- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp +++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp @@ -16,6 +16,7 @@ #include "MCTargetDesc/ARCMCTargetDesc.h" #include "TargetInfo/ARCTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -24,6 +25,7 @@ #include "llvm/MC/TargetRegistry.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arc-disassembler" diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index cbd31beab8299..af08747d578f0 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/ARMTargetInfo.h" #include "Utils/ARMBaseInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -31,6 +32,7 @@ #include <vector> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arm-disassembler" diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index c7a584868f4e6..948588cb9a754 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -26,6 +27,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "avr-disassembler" diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp index 4dfae81e90191..b5bb1c08c5644 100644 --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp index d78d9acc2aa23..749127f4ddc8a 100644 --- a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp +++ b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp @@ -15,6 +15,7 @@ #include "TargetInfo/CSKYTargetInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index bcddb540d35dc..de10092cbe3c8 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/HexagonTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCExpr.h" diff --git a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp index 5d87c3c4d72cf..c24700b896343 100644 --- a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp +++ b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp @@ -16,6 +16,7 @@ #include "LanaiCondCode.h" #include "LanaiInstrInfo.h" #include "TargetInfo/LanaiTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -247,4 +248,4 @@ static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, return MCDisassembler::Fail; Inst.addOperand(MCOperand::createImm(Val)); return MCDisassembler::Success; -} +} \ No newline at end of file diff --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp index 8c4668ec70c7e..735f798afde24 100644 --- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp +++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "TargetInfo/LoongArchTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp index 4ec18fe6bf544..6ca01e598d95d 100644 --- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp +++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "m68k-disassembler" diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp index 4c5b473982f77..c8094a8eeb361 100644 --- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp +++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp @@ -14,6 +14,7 @@ #include "MSP430.h" #include "TargetInfo/MSP430TargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "msp430-disassembler" diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index b3f6cd1609fbb..0c98c4da2ede1 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/MipsTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -29,6 +30,7 @@ #include <cstdint> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "mips-disassembler" diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 71a76142bb389..5e27f06c94f06 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/PPCMCTargetDesc.h" #include "TargetInfo/PowerPCTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 78be55b3a51d3..d72df741ef287 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -14,6 +14,7 @@ #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "TargetInfo/RISCVTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -25,6 +26,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "riscv-disassembler" diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index fab94fb4d40ca..35207d6301e54 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/SparcTargetInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -21,6 +22,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "sparc-disassembler" diff --git a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp index 31b4f1196392c..0b91aba67694f 100644 --- a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp +++ b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/SystemZMCTargetDesc.h" #include "TargetInfo/SystemZTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp index 88200c5fc97eb..d7e1666a7417d 100644 --- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp +++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp @@ -15,6 +15,7 @@ #include "VE.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -22,6 +23,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "ve-disassembler" diff --git a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index d36f18238f7a3..6921f44b700c5 100644 --- a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -15,6 +15,7 @@ #include "XCore.h" #include "XCoreRegisterInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "xcore-disassembler" diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp index 39bec4785c61c..396b00f7b8628 100644 --- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp +++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/XtensaMCTargetDesc.h" #include "TargetInfo/XtensaTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 95522030300a0..406a8d013e690 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -1104,7 +1104,9 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, // Emit a function for each case first. for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << "template <typename InsnType>\n"; - OS << "DecodeStatus decodeFn" << Index << "(" << DecodeParams << ") {\n"; + OS << "static DecodeStatus decodeFn" << Index << "(" << DecodeParams + << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " " << TmpTypeDecl; OS << " [[maybe_unused]] TmpType tmp;\n"; OS << Decoder; @@ -1117,24 +1119,26 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, OS << "template <typename InsnType>\n"; OS << "static DecodeStatus decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " DecodeComplete = true;\n"; if (UseFnTableInDecodeToMCInst) { - // Build a table of function pointers. + // Build a table of function pointers OS << " using DecodeFnTy = DecodeStatus (*)(" << DecodeParams << ");\n"; OS << " static constexpr DecodeFnTy decodeFnTable[] = {\n"; for (size_t Index : llvm::seq(Decoders.size())) OS << " decodeFn" << Index << ",\n"; OS << " };\n"; OS << " if (Idx >= " << Decoders.size() << ")\n"; - OS << " llvm_unreachable(\"Invalid index!\");\n"; + OS << " llvm_unreachable(\"Invalid decoder index!\");\n"; + OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, " "DecodeComplete);\n"; } else { OS << " " << TmpTypeDecl; OS << " TmpType tmp;\n"; OS << " switch (Idx) {\n"; - OS << " default: llvm_unreachable(\"Invalid index!\");\n"; + OS << " default: llvm_unreachable(\"Invalid decoder index!\");\n"; for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << " case " << Index << ":\n"; OS << Decoder; @@ -2126,65 +2130,6 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef, } } -// emitFieldFromInstruction - Emit the templated helper function -// fieldFromInstruction(). -// On Windows we make sure that this function is not inlined when -// using the VS compiler. It has a bug which causes the function -// to be optimized out in some circumstances. See llvm.org/pr38292 -static void emitFieldFromInstruction(formatted_raw_ostream &OS) { - OS << R"( -// Helper functions for extracting fields from encoded instructions. -// InsnType must either be integral or an APInt-like object that must: -// * be default-constructible and copy-constructible -// * Support extractBitsAsZExtValue(numBits, startBit) -// * Support the ~, &, ==, and != operators with other objects of the same type -// * Support the != and bitwise & with uint64_t -template <typename InsnType> -#if defined(_MSC_VER) && !defined(__clang__) -__declspec(noinline) -#endif -static std::enable_if_t<std::is_integral<InsnType>::value, InsnType> -fieldFromInstruction(... [truncated] 
@llvmbot
Copy link
Member

llvmbot commented Aug 21, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Rahul Joshi (jurahul)

Changes

Extract fixed functions generated by decoder emitter into a new MCDecoder.h header.


Patch is 23.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154802.diff

23 Files Affected:

  • (added) llvm/include/llvm/MC/MCDecoder.h (+67)
  • (modified) llvm/include/llvm/MC/MCDecoderOps.h (+2-2)
  • (modified) llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+1)
  • (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+10-81)
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h new file mode 100644 index 0000000000000..0eefde02bbb18 --- /dev/null +++ b/llvm/include/llvm/MC/MCDecoder.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Disassembler decoder helper functions. +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCDECODER_H +#define LLVM_MC_MCDECODER_H + +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/Support/MathExtras.h" +#include <cassert> + +namespace llvm::MCD { + +// Helper to propagate SoftFail status. Returns false if the status is Fail; +// callers are expected to early-exit in that condition. (Note, the '&' operator +// is correct to propagate the values of this enum; see comment on 'enum +// DecodeStatus'.) +inline bool Check(MCDisassembler::DecodeStatus &Out, + MCDisassembler::DecodeStatus In) { + Out = static_cast<MCDisassembler::DecodeStatus>(Out & In); + return Out != MCDisassembler::Fail; +} + +// fieldFromInstruction - Extracts a given span of bits from the instruction +// bits and return it as an integer. +template <typename IntType> +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(noinline) +#endif +inline std::enable_if_t<std::is_integral_v<IntType>, IntType> +fieldFromInstruction(const IntType &Insn, unsigned StartBit, unsigned NumBits) { + assert(StartBit + NumBits <= 64 && "Cannot support >64-bit extractions!"); + assert(StartBit + NumBits <= (sizeof(IntType) * 8) && + "Instruction field out of bounds!"); + const IntType Mask = maskTrailingOnes<IntType>(NumBits); + return (Insn >> StartBit) & Mask; +} + +template <typename InsnType> +inline std::enable_if_t<!std::is_integral_v<InsnType>, uint64_t> +fieldFromInstruction(const InsnType &Insn, unsigned StartBit, + unsigned NumBits) { + return Insn.extractBitsAsZExtValue(NumBits, StartBit); +} + +// Helper function for inserting bits extracted from an encoded instruction into +// an integer-typed field. +template <typename IntType> +static std::enable_if_t<std::is_integral_v<IntType>, void> +insertBits(IntType &field, IntType bits, unsigned startBit, unsigned numBits) { + // Check that no bit beyond numBits is set, so that a simple bitwise | + // is sufficient. + assert((~(((IntType)1 << numBits) - 1) & bits) == 0 && + "bits has more than numBits bits set"); + assert(startBit + numBits <= sizeof(IntType) * 8); + (void)numBits; + field |= bits << startBit; +} + +} // namespace llvm::MCD + +#endif // LLVM_MC_MCDECODER_H diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h index 50fcf2a40e26d..dea5b6931250f 100644 --- a/llvm/include/llvm/MC/MCDecoderOps.h +++ b/llvm/include/llvm/MC/MCDecoderOps.h @@ -1,11 +1,11 @@ -//===------------ llvm/MC/MCDecoderOps.h - Decoder driver -------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// Disassembler decoder state machine driver. +// Disassembler decoder state machine ops. //===----------------------------------------------------------------------===// #ifndef LLVM_MC_MCDECODEROPS_H #define LLVM_MC_MCDECODEROPS_H diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index ae984be670fc2..323db2a0728eb 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "TargetInfo/AArch64TargetInfo.h" #include "Utils/AArch64BaseInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCRelocationInfo.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include <memory> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "aarch64-disassembler" diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 070de008d4f59..4b891e48ff273 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -27,6 +27,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstrDesc.h" @@ -605,7 +606,7 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, Bytes = Bytes_.slice(0, MaxInstBytesNum); } - if (isGFX11Plus() && Bytes.size() >= 12 ) { + if (isGFX11Plus() && Bytes.size() >= 12) { DecoderUInt128 DecW = eat12Bytes(Bytes); if (isGFX11() && diff --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp index 6181017559045..f28c7d8fe92a5 100644 --- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp +++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp @@ -16,6 +16,7 @@ #include "MCTargetDesc/ARCMCTargetDesc.h" #include "TargetInfo/ARCTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -24,6 +25,7 @@ #include "llvm/MC/TargetRegistry.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arc-disassembler" diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index cbd31beab8299..af08747d578f0 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/ARMTargetInfo.h" #include "Utils/ARMBaseInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -31,6 +32,7 @@ #include <vector> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arm-disassembler" diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index c7a584868f4e6..948588cb9a754 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -26,6 +27,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "avr-disassembler" diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp index 4dfae81e90191..b5bb1c08c5644 100644 --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp index d78d9acc2aa23..749127f4ddc8a 100644 --- a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp +++ b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp @@ -15,6 +15,7 @@ #include "TargetInfo/CSKYTargetInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index bcddb540d35dc..de10092cbe3c8 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/HexagonTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCExpr.h" diff --git a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp index 5d87c3c4d72cf..c24700b896343 100644 --- a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp +++ b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp @@ -16,6 +16,7 @@ #include "LanaiCondCode.h" #include "LanaiInstrInfo.h" #include "TargetInfo/LanaiTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -247,4 +248,4 @@ static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, return MCDisassembler::Fail; Inst.addOperand(MCOperand::createImm(Val)); return MCDisassembler::Success; -} +} \ No newline at end of file diff --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp index 8c4668ec70c7e..735f798afde24 100644 --- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp +++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "TargetInfo/LoongArchTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp index 4ec18fe6bf544..6ca01e598d95d 100644 --- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp +++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "m68k-disassembler" diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp index 4c5b473982f77..c8094a8eeb361 100644 --- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp +++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp @@ -14,6 +14,7 @@ #include "MSP430.h" #include "TargetInfo/MSP430TargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "msp430-disassembler" diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index b3f6cd1609fbb..0c98c4da2ede1 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/MipsTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -29,6 +30,7 @@ #include <cstdint> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "mips-disassembler" diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 71a76142bb389..5e27f06c94f06 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/PPCMCTargetDesc.h" #include "TargetInfo/PowerPCTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 78be55b3a51d3..d72df741ef287 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -14,6 +14,7 @@ #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "TargetInfo/RISCVTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -25,6 +26,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "riscv-disassembler" diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index fab94fb4d40ca..35207d6301e54 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/SparcTargetInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -21,6 +22,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "sparc-disassembler" diff --git a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp index 31b4f1196392c..0b91aba67694f 100644 --- a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp +++ b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/SystemZMCTargetDesc.h" #include "TargetInfo/SystemZTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp index 88200c5fc97eb..d7e1666a7417d 100644 --- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp +++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp @@ -15,6 +15,7 @@ #include "VE.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -22,6 +23,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "ve-disassembler" diff --git a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index d36f18238f7a3..6921f44b700c5 100644 --- a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -15,6 +15,7 @@ #include "XCore.h" #include "XCoreRegisterInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "xcore-disassembler" diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp index 39bec4785c61c..396b00f7b8628 100644 --- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp +++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/XtensaMCTargetDesc.h" #include "TargetInfo/XtensaTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 95522030300a0..406a8d013e690 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -1104,7 +1104,9 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, // Emit a function for each case first. for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << "template <typename InsnType>\n"; - OS << "DecodeStatus decodeFn" << Index << "(" << DecodeParams << ") {\n"; + OS << "static DecodeStatus decodeFn" << Index << "(" << DecodeParams + << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " " << TmpTypeDecl; OS << " [[maybe_unused]] TmpType tmp;\n"; OS << Decoder; @@ -1117,24 +1119,26 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, OS << "template <typename InsnType>\n"; OS << "static DecodeStatus decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " DecodeComplete = true;\n"; if (UseFnTableInDecodeToMCInst) { - // Build a table of function pointers. + // Build a table of function pointers OS << " using DecodeFnTy = DecodeStatus (*)(" << DecodeParams << ");\n"; OS << " static constexpr DecodeFnTy decodeFnTable[] = {\n"; for (size_t Index : llvm::seq(Decoders.size())) OS << " decodeFn" << Index << ",\n"; OS << " };\n"; OS << " if (Idx >= " << Decoders.size() << ")\n"; - OS << " llvm_unreachable(\"Invalid index!\");\n"; + OS << " llvm_unreachable(\"Invalid decoder index!\");\n"; + OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, " "DecodeComplete);\n"; } else { OS << " " << TmpTypeDecl; OS << " TmpType tmp;\n"; OS << " switch (Idx) {\n"; - OS << " default: llvm_unreachable(\"Invalid index!\");\n"; + OS << " default: llvm_unreachable(\"Invalid decoder index!\");\n"; for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << " case " << Index << ":\n"; OS << Decoder; @@ -2126,65 +2130,6 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef, } } -// emitFieldFromInstruction - Emit the templated helper function -// fieldFromInstruction(). -// On Windows we make sure that this function is not inlined when -// using the VS compiler. It has a bug which causes the function -// to be optimized out in some circumstances. See llvm.org/pr38292 -static void emitFieldFromInstruction(formatted_raw_ostream &OS) { - OS << R"( -// Helper functions for extracting fields from encoded instructions. -// InsnType must either be integral or an APInt-like object that must: -// * be default-constructible and copy-constructible -// * Support extractBitsAsZExtValue(numBits, startBit) -// * Support the ~, &, ==, and != operators with other objects of the same type -// * Support the != and bitwise & with uint64_t -template <typename InsnType> -#if defined(_MSC_VER) && !defined(__clang__) -__declspec(noinline) -#endif -static std::enable_if_t<std::is_integral<InsnType>::value, InsnType> -fieldFromInstruction(... [truncated] 
@llvmbot
Copy link
Member

llvmbot commented Aug 21, 2025

@llvm/pr-subscribers-backend-amdgpu

Author: Rahul Joshi (jurahul)

Changes

Extract fixed functions generated by decoder emitter into a new MCDecoder.h header.


Patch is 23.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154802.diff

23 Files Affected:

  • (added) llvm/include/llvm/MC/MCDecoder.h (+67)
  • (modified) llvm/include/llvm/MC/MCDecoderOps.h (+2-2)
  • (modified) llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp (+2-1)
  • (modified) llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp (+2)
  • (modified) llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp (+1)
  • (modified) llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+1)
  • (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+10-81)
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h new file mode 100644 index 0000000000000..0eefde02bbb18 --- /dev/null +++ b/llvm/include/llvm/MC/MCDecoder.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Disassembler decoder helper functions. +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCDECODER_H +#define LLVM_MC_MCDECODER_H + +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/Support/MathExtras.h" +#include <cassert> + +namespace llvm::MCD { + +// Helper to propagate SoftFail status. Returns false if the status is Fail; +// callers are expected to early-exit in that condition. (Note, the '&' operator +// is correct to propagate the values of this enum; see comment on 'enum +// DecodeStatus'.) +inline bool Check(MCDisassembler::DecodeStatus &Out, + MCDisassembler::DecodeStatus In) { + Out = static_cast<MCDisassembler::DecodeStatus>(Out & In); + return Out != MCDisassembler::Fail; +} + +// fieldFromInstruction - Extracts a given span of bits from the instruction +// bits and return it as an integer. +template <typename IntType> +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(noinline) +#endif +inline std::enable_if_t<std::is_integral_v<IntType>, IntType> +fieldFromInstruction(const IntType &Insn, unsigned StartBit, unsigned NumBits) { + assert(StartBit + NumBits <= 64 && "Cannot support >64-bit extractions!"); + assert(StartBit + NumBits <= (sizeof(IntType) * 8) && + "Instruction field out of bounds!"); + const IntType Mask = maskTrailingOnes<IntType>(NumBits); + return (Insn >> StartBit) & Mask; +} + +template <typename InsnType> +inline std::enable_if_t<!std::is_integral_v<InsnType>, uint64_t> +fieldFromInstruction(const InsnType &Insn, unsigned StartBit, + unsigned NumBits) { + return Insn.extractBitsAsZExtValue(NumBits, StartBit); +} + +// Helper function for inserting bits extracted from an encoded instruction into +// an integer-typed field. +template <typename IntType> +static std::enable_if_t<std::is_integral_v<IntType>, void> +insertBits(IntType &field, IntType bits, unsigned startBit, unsigned numBits) { + // Check that no bit beyond numBits is set, so that a simple bitwise | + // is sufficient. + assert((~(((IntType)1 << numBits) - 1) & bits) == 0 && + "bits has more than numBits bits set"); + assert(startBit + numBits <= sizeof(IntType) * 8); + (void)numBits; + field |= bits << startBit; +} + +} // namespace llvm::MCD + +#endif // LLVM_MC_MCDECODER_H diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h index 50fcf2a40e26d..dea5b6931250f 100644 --- a/llvm/include/llvm/MC/MCDecoderOps.h +++ b/llvm/include/llvm/MC/MCDecoderOps.h @@ -1,11 +1,11 @@ -//===------------ llvm/MC/MCDecoderOps.h - Decoder driver -------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// Disassembler decoder state machine driver. +// Disassembler decoder state machine ops. //===----------------------------------------------------------------------===// #ifndef LLVM_MC_MCDECODEROPS_H #define LLVM_MC_MCDECODEROPS_H diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index ae984be670fc2..323db2a0728eb 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "TargetInfo/AArch64TargetInfo.h" #include "Utils/AArch64BaseInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCRelocationInfo.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include <memory> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "aarch64-disassembler" diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 070de008d4f59..4b891e48ff273 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -27,6 +27,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstrDesc.h" @@ -605,7 +606,7 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, Bytes = Bytes_.slice(0, MaxInstBytesNum); } - if (isGFX11Plus() && Bytes.size() >= 12 ) { + if (isGFX11Plus() && Bytes.size() >= 12) { DecoderUInt128 DecW = eat12Bytes(Bytes); if (isGFX11() && diff --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp index 6181017559045..f28c7d8fe92a5 100644 --- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp +++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp @@ -16,6 +16,7 @@ #include "MCTargetDesc/ARCMCTargetDesc.h" #include "TargetInfo/ARCTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -24,6 +25,7 @@ #include "llvm/MC/TargetRegistry.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arc-disassembler" diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index cbd31beab8299..af08747d578f0 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/ARMTargetInfo.h" #include "Utils/ARMBaseInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -31,6 +32,7 @@ #include <vector> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "arm-disassembler" diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index c7a584868f4e6..948588cb9a754 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -26,6 +27,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "avr-disassembler" diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp index 4dfae81e90191..b5bb1c08c5644 100644 --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp index d78d9acc2aa23..749127f4ddc8a 100644 --- a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp +++ b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp @@ -15,6 +15,7 @@ #include "TargetInfo/CSKYTargetInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index bcddb540d35dc..de10092cbe3c8 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -13,6 +13,7 @@ #include "TargetInfo/HexagonTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCExpr.h" diff --git a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp index 5d87c3c4d72cf..c24700b896343 100644 --- a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp +++ b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp @@ -16,6 +16,7 @@ #include "LanaiCondCode.h" #include "LanaiInstrInfo.h" #include "TargetInfo/LanaiTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -247,4 +248,4 @@ static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, return MCDisassembler::Fail; Inst.addOperand(MCOperand::createImm(Val)); return MCDisassembler::Success; -} +} \ No newline at end of file diff --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp index 8c4668ec70c7e..735f798afde24 100644 --- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp +++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "TargetInfo/LoongArchTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp index 4ec18fe6bf544..6ca01e598d95d 100644 --- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp +++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -27,6 +28,7 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "m68k-disassembler" diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp index 4c5b473982f77..c8094a8eeb361 100644 --- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp +++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp @@ -14,6 +14,7 @@ #include "MSP430.h" #include "TargetInfo/MSP430TargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "msp430-disassembler" diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index b3f6cd1609fbb..0c98c4da2ede1 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/MipsTargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -29,6 +30,7 @@ #include <cstdint> using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "mips-disassembler" diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 71a76142bb389..5e27f06c94f06 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/PPCMCTargetDesc.h" #include "TargetInfo/PowerPCTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 78be55b3a51d3..d72df741ef287 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -14,6 +14,7 @@ #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "TargetInfo/RISCVTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -25,6 +26,7 @@ #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "riscv-disassembler" diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index fab94fb4d40ca..35207d6301e54 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -14,6 +14,7 @@ #include "TargetInfo/SparcTargetInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -21,6 +22,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "sparc-disassembler" diff --git a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp index 31b4f1196392c..0b91aba67694f 100644 --- a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp +++ b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/SystemZMCTargetDesc.h" #include "TargetInfo/SystemZTargetInfo.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp index 88200c5fc97eb..d7e1666a7417d 100644 --- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp +++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp @@ -15,6 +15,7 @@ #include "VE.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -22,6 +23,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "ve-disassembler" diff --git a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index d36f18238f7a3..6921f44b700c5 100644 --- a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -15,6 +15,7 @@ #include "XCore.h" #include "XCoreRegisterInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -23,6 +24,7 @@ #include "llvm/Support/Compiler.h" using namespace llvm; +using namespace llvm::MCD; #define DEBUG_TYPE "xcore-disassembler" diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp index 39bec4785c61c..396b00f7b8628 100644 --- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp +++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/XtensaMCTargetDesc.h" #include "TargetInfo/XtensaTargetInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDecoder.h" #include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 95522030300a0..406a8d013e690 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -1104,7 +1104,9 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, // Emit a function for each case first. for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << "template <typename InsnType>\n"; - OS << "DecodeStatus decodeFn" << Index << "(" << DecodeParams << ") {\n"; + OS << "static DecodeStatus decodeFn" << Index << "(" << DecodeParams + << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " " << TmpTypeDecl; OS << " [[maybe_unused]] TmpType tmp;\n"; OS << Decoder; @@ -1117,24 +1119,26 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, OS << "template <typename InsnType>\n"; OS << "static DecodeStatus decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n"; + OS << " using namespace llvm::MCD;\n"; OS << " DecodeComplete = true;\n"; if (UseFnTableInDecodeToMCInst) { - // Build a table of function pointers. + // Build a table of function pointers OS << " using DecodeFnTy = DecodeStatus (*)(" << DecodeParams << ");\n"; OS << " static constexpr DecodeFnTy decodeFnTable[] = {\n"; for (size_t Index : llvm::seq(Decoders.size())) OS << " decodeFn" << Index << ",\n"; OS << " };\n"; OS << " if (Idx >= " << Decoders.size() << ")\n"; - OS << " llvm_unreachable(\"Invalid index!\");\n"; + OS << " llvm_unreachable(\"Invalid decoder index!\");\n"; + OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, " "DecodeComplete);\n"; } else { OS << " " << TmpTypeDecl; OS << " TmpType tmp;\n"; OS << " switch (Idx) {\n"; - OS << " default: llvm_unreachable(\"Invalid index!\");\n"; + OS << " default: llvm_unreachable(\"Invalid decoder index!\");\n"; for (const auto &[Index, Decoder] : enumerate(Decoders)) { OS << " case " << Index << ":\n"; OS << Decoder; @@ -2126,65 +2130,6 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef, } } -// emitFieldFromInstruction - Emit the templated helper function -// fieldFromInstruction(). -// On Windows we make sure that this function is not inlined when -// using the VS compiler. It has a bug which causes the function -// to be optimized out in some circumstances. See llvm.org/pr38292 -static void emitFieldFromInstruction(formatted_raw_ostream &OS) { - OS << R"( -// Helper functions for extracting fields from encoded instructions. -// InsnType must either be integral or an APInt-like object that must: -// * be default-constructible and copy-constructible -// * Support extractBitsAsZExtValue(numBits, startBit) -// * Support the ~, &, ==, and != operators with other objects of the same type -// * Support the != and bitwise & with uint64_t -template <typename InsnType> -#if defined(_MSC_VER) && !defined(__clang__) -__declspec(noinline) -#endif -static std::enable_if_t<std::is_integral<InsnType>::value, InsnType> -fieldFromInstruction(... [truncated] 
@jurahul jurahul force-pushed the decoder_common_header branch from 6767361 to e041e43 Compare August 21, 2025 20:21
Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@s-barannikov s-barannikov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jurahul jurahul merged commit 22f8693 into llvm:main Aug 21, 2025
9 checks passed
@jurahul jurahul deleted the decoder_common_header branch August 21, 2025 22:06
OS << ") {\n";
if (HasCheckPredicate)
OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n";
OS << " using namespace llvm::MCD;\n";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is overindented by 1 position

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixing it here: #154855

@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 21, 2025

LLVM Buildbot has detected a new failure on builder ml-opt-dev-x86-64 running on ml-opt-dev-x86-64-b2 while building llvm at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/137/builds/24029

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure) ... 131.170 [21/9/3878] Linking CXX executable bin/llc 131.480 [21/8/3879] Linking CXX executable bin/opt 131.712 [21/7/3880] Linking CXX executable bin/llvm-dwarfutil 131.744 [21/6/3881] Linking CXX executable bin/bugpoint 131.757 [20/6/3882] Building CXX object tools/bugpoint-passes/CMakeFiles/BugpointPasses.dir/TestPasses.cpp.o 131.781 [19/6/3883] Linking CXX shared module lib/BugpointPasses.so 131.859 [19/5/3884] Linking CXX executable bin/llvm-lto2 131.976 [19/4/3885] Linking CXX executable bin/llvm-opt-fuzzer 132.727 [19/3/3886] Linking CXX executable bin/llvm-reduce 132.776 [19/2/3887] Linking CXX executable bin/llvm-lto command timed out: 1200 seconds without output running [b'ninja', b'-j', b'64'], attempting to kill process killed by signal 9 program finished with exit code -1 elapsedTime=1332.884971 
@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 21, 2025

LLVM Buildbot has detected a new failure on builder ml-opt-devrel-x86-64 running on ml-opt-devrel-x86-64-b1 while building llvm at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/175/builds/23880

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure) ... 163.787 [21/9/3911] Linking CXX executable bin/llc 164.083 [21/8/3912] Linking CXX executable bin/llvm-split 164.139 [21/7/3913] Linking CXX executable bin/opt 164.346 [21/6/3914] Linking CXX executable bin/bugpoint 164.360 [20/6/3915] Building CXX object tools/bugpoint-passes/CMakeFiles/BugpointPasses.dir/TestPasses.cpp.o 164.385 [19/6/3916] Linking CXX shared module lib/BugpointPasses.so 164.398 [19/5/3917] Linking CXX executable bin/llvm-lto2 165.081 [19/4/3918] Linking CXX executable bin/llvm-reduce 165.167 [19/3/3919] Linking CXX executable bin/llvm-opt-fuzzer 165.381 [19/2/3920] Linking CXX executable bin/llvm-lto command timed out: 1200 seconds without output running [b'ninja', b'-j', b'64'], attempting to kill process killed by signal 9 program finished with exit code -1 elapsedTime=1365.439103 
@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 21, 2025

LLVM Buildbot has detected a new failure on builder ml-opt-rel-x86-64 running on ml-opt-rel-x86-64-b1 while building llvm at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/185/builds/23873

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure) ... 163.825 [19/11/3911] Linking CXX executable bin/llvm-split 164.018 [19/10/3912] Linking CXX executable bin/llvm-isel-fuzzer 164.019 [19/9/3913] Linking CXX executable bin/llvm-opt-fuzzer 164.275 [19/8/3914] Linking CXX executable bin/llvm-dwp 164.340 [19/7/3915] Linking CXX executable bin/dsymutil 164.463 [19/6/3916] Linking CXX executable bin/opt 164.468 [19/5/3917] Linking CXX executable bin/llvm-lto2 164.762 [19/4/3918] Linking CXX executable bin/llvm-reduce 164.920 [19/3/3919] Linking CXX executable bin/llvm-dwarfutil 165.387 [19/2/3920] Linking CXX executable bin/llvm-lto command timed out: 1200 seconds without output running [b'ninja', b'-j', b'64'], attempting to kill process killed by signal 9 program finished with exit code -1 elapsedTime=1365.409432 
@jurahul
Copy link
Contributor Author

jurahul commented Aug 21, 2025

@mtrofin Can you help identify if these ml-opt-devrel build failures are related. I am not sure how, but all these builds are failing with a timeout which I am not sure how my change triggered:

command timed out: 1200 seconds without output running [b'ninja', b'-j', b'64'], attempting to kill 
Copy link
Member

mtrofin commented Aug 21, 2025

Let's wait one more build to make sure this isn't some spurious.

@jurahul
Copy link
Contributor Author

jurahul commented Aug 22, 2025

@mtrofin
Copy link
Member

mtrofin commented Aug 22, 2025

Looks like its fixed now: https://lab.llvm.org/buildbot/#/builders/185/builds/23879

Ya - @boomanaiden154 figured the problem and fixed it. Basically your change probably increased build time but the buildbots were using distro-default gcc and gold. So switched to clang-20 and lld.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment