diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h new file mode 100644 index 0000000000000..70762a4a5ebae --- /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 + +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(Out & In); + return Out != MCDisassembler::Fail; +} + +// Extracts a given span of bits from the instruction bits and return it as an +// integer. +template +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(noinline) +#endif +inline std::enable_if_t, 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(NumBits); + return (Insn >> StartBit) & Mask; +} + +template +inline std::enable_if_t, 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 +static std::enable_if_t, 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 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 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 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 \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 \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 -#if defined(_MSC_VER) && !defined(__clang__) -__declspec(noinline) -#endif -static std::enable_if_t::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 -static std::enable_if_t::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 -static std::enable_if_t, 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(Out & In); - return Out != MCDisassembler::Fail; -} - -)"; -} - /// Collects all HwModes referenced by the target for encoding purposes. void DecoderEmitter::collectHwModesReferencedForEncodings( std::vector &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 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;