diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h index 175f6a9591558..1dcdbcdfd940b 100644 --- a/llvm/include/llvm/MC/MCDecoder.h +++ b/llvm/include/llvm/MC/MCDecoder.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCDECODER_H #define LLVM_MC_MCDECODER_H +#include "llvm/ADT/APInt.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/Support/MathExtras.h" #include @@ -58,6 +59,24 @@ uint64_t fieldFromInstruction(const std::bitset &Insn, unsigned StartBit, return ((Insn >> StartBit) & Mask).to_ullong(); } +template +inline std::enable_if_t, T> extractBits(T Val) { + static_assert(StartBit + NumBits <= std::numeric_limits::digits); + return (Val >> StartBit) & maskTrailingOnes(NumBits); +} + +template +uint64_t extractBits(const std::bitset &Val) { + static_assert(StartBit + NumBits <= N); + std::bitset Mask = maskTrailingOnes(NumBits); + return ((Val >> StartBit) & Mask).to_ullong(); +} + +template +uint64_t extractBits(const APInt &Val) { + return Val.extractBitsAsZExtValue(NumBits, StartBit); +} + } // namespace llvm::MCD #endif // LLVM_MC_MCDECODER_H diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 3a464e01042dc..5a087eefaaf8d 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -1031,8 +1031,7 @@ static void emitBinaryParser(raw_ostream &OS, indent Indent, // One variable part and no/zero constant part. Initialize `tmp` with the // variable part. auto [Base, Width, Offset] = OpInfo.fields().front(); - OS << Indent << "tmp = fieldFromInstruction(insn, " << Base << ", " << Width - << ')'; + OS << Indent << "tmp = extractBits<" << Base << ", " << Width << ">(insn)"; if (Offset) OS << " << " << Offset; OS << ";\n"; @@ -1042,8 +1041,8 @@ static void emitBinaryParser(raw_ostream &OS, indent Indent, OS << Indent << "tmp = " << format_hex(OpInfo.InitValue.value_or(0), 0) << ";\n"; for (auto [Base, Width, Offset] : OpInfo.fields()) { - OS << Indent << "tmp |= fieldFromInstruction(insn, " << Base << ", " - << Width << ')'; + OS << Indent << "tmp |= extractBits<" << Base << ", " << Width + << ">(insn)"; if (Offset) OS << " << " << Offset; OS << ";\n";