[llvm] [NFC][MC][Decoder] Extract fixed pieces of decoder code into new header file (PR #154802)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 21 10:44:25 PDT 2025
https://github.com/jurahul updated https://github.com/llvm/llvm-project/pull/154802
>From 0b636c8edd0ec8d906eb2361793421f97d3e61ef Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Thu, 21 Aug 2025 04:49:06 -0700
Subject: [PATCH 1/2] [NFC][MC][Decoder] Extract fixed pieces of code into new
header file
---
llvm/include/llvm/MC/MCDecoder.h | 71 +++++++++++++++
llvm/include/llvm/MC/MCDecoderOps.h | 4 +-
.../Disassembler/AArch64Disassembler.cpp | 2 +
.../Disassembler/AMDGPUDisassembler.cpp | 3 +-
.../ARC/Disassembler/ARCDisassembler.cpp | 2 +
.../ARM/Disassembler/ARMDisassembler.cpp | 2 +
.../AVR/Disassembler/AVRDisassembler.cpp | 2 +
.../BPF/Disassembler/BPFDisassembler.cpp | 1 +
.../CSKY/Disassembler/CSKYDisassembler.cpp | 1 +
.../Disassembler/HexagonDisassembler.cpp | 1 +
.../Lanai/Disassembler/LanaiDisassembler.cpp | 3 +-
.../Disassembler/LoongArchDisassembler.cpp | 1 +
.../M68k/Disassembler/M68kDisassembler.cpp | 2 +
.../Disassembler/MSP430Disassembler.cpp | 2 +
.../Mips/Disassembler/MipsDisassembler.cpp | 2 +
.../PowerPC/Disassembler/PPCDisassembler.cpp | 1 +
.../RISCV/Disassembler/RISCVDisassembler.cpp | 2 +
.../Sparc/Disassembler/SparcDisassembler.cpp | 2 +
.../Disassembler/SystemZDisassembler.cpp | 1 +
.../Target/VE/Disassembler/VEDisassembler.cpp | 2 +
.../XCore/Disassembler/XCoreDisassembler.cpp | 2 +
.../Disassembler/XtensaDisassembler.cpp | 1 +
llvm/utils/TableGen/DecoderEmitter.cpp | 91 ++-----------------
23 files changed, 116 insertions(+), 85 deletions(-)
create mode 100644 llvm/include/llvm/MC/MCDecoder.h
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h
new file mode 100644
index 0000000000000..e199232c6290e
--- /dev/null
+++ b/llvm/include/llvm/MC/MCDecoder.h
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 {
+class APInt;
+}
+
+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(const InsnType &insn, unsigned startBit,
- unsigned numBits) {
- assert(startBit + numBits <= 64 && "Cannot support >64-bit extractions!");
- assert(startBit + numBits <= (sizeof(InsnType) * 8) &&
- "Instruction field out of bounds!");
- InsnType fieldMask;
- if (numBits == sizeof(InsnType) * 8)
- fieldMask = (InsnType)(-1LL);
- else
- fieldMask = (((InsnType)1 << numBits) - 1) << startBit;
- return (insn & fieldMask) >> startBit;
-}
-
-template <typename InsnType>
-static std::enable_if_t<!std::is_integral<InsnType>::value, uint64_t>
-fieldFromInstruction(const InsnType &insn, unsigned startBit,
- unsigned numBits) {
- return insn.extractBitsAsZExtValue(numBits, startBit);
-}
-)";
-}
-
-// emitInsertBits - Emit the templated helper function insertBits().
-static void emitInsertBits(formatted_raw_ostream &OS) {
- OS << R"(
-// 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;
-}
-)";
-}
-
// emitDecodeInstruction - Emit the templated helper function
// decodeInstruction().
static void emitDecodeInstruction(formatted_raw_ostream &OS, bool IsVarLenInst,
@@ -2218,6 +2163,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
OS << ") {\n";
if (HasCheckPredicate)
OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n";
+ OS << " using namespace llvm::MCD;\n";
OS << R"(
const uint8_t *Ptr = DecodeTable;
@@ -2412,20 +2358,6 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
)";
}
-// 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'.)
-static void emitCheck(formatted_raw_ostream &OS) {
- OS << R"(
-static bool Check(DecodeStatus &Out, DecodeStatus In) {
- Out = static_cast<DecodeStatus>(Out & In);
- return Out != MCDisassembler::Fail;
-}
-
-)";
-}
-
/// Collects all HwModes referenced by the target for encoding purposes.
void DecoderEmitter::collectHwModesReferencedForEncodings(
std::vector<unsigned> &HwModeIDs,
@@ -2610,10 +2542,6 @@ void DecoderEmitter::run(raw_ostream &o) const {
namespace {
)";
- emitFieldFromInstruction(OS);
- emitInsertBits(OS);
- emitCheck(OS);
-
// Do extra bookkeeping for variable-length encodings.
std::vector<unsigned> InstrLen;
bool IsVarLenInst = Target.hasVariableLengthEncodings();
@@ -2643,6 +2571,7 @@ namespace {
DecoderTableInfo TableInfo;
unsigned OpcodeMask = 0;
+
for (const auto &[Key, EncodingIDs] : EncMap) {
auto [DecoderNamespace, HwModeID, Size] = Key;
const unsigned BitWidth = IsVarLenInst ? MaxInstLen : 8 * Size;
>From 70fc32f1176d4be6f83a2048412b4485bf9239df Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Thu, 21 Aug 2025 10:43:42 -0700
Subject: [PATCH 2/2] Review feedback
---
llvm/include/llvm/MC/MCDecoder.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h
index e199232c6290e..0eefde02bbb18 100644
--- a/llvm/include/llvm/MC/MCDecoder.h
+++ b/llvm/include/llvm/MC/MCDecoder.h
@@ -14,10 +14,6 @@
#include "llvm/Support/MathExtras.h"
#include <cassert>
-namespace llvm {
-class APInt;
-}
-
namespace llvm::MCD {
// Helper to propagate SoftFail status. Returns false if the status is Fail;
More information about the llvm-commits
mailing list