[llvm] [TableGen][DecoderEmitter] Rework table construction/emission (PR #155889)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 16 11:00:15 PDT 2025
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/155889
>From dd7e04881e925badd8bbe15288875d4cf2aef7a3 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 16 Sep 2025 06:55:34 +0300
Subject: [PATCH 1/3] tmp
---
llvm/include/llvm/MC/MCDecoderOps.h | 20 +-
llvm/utils/TableGen/DecoderEmitter.cpp | 1179 +++++++++++++-----------
2 files changed, 670 insertions(+), 529 deletions(-)
diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h
index 790ff3eb4f333..4e06deb0eacee 100644
--- a/llvm/include/llvm/MC/MCDecoderOps.h
+++ b/llvm/include/llvm/MC/MCDecoderOps.h
@@ -13,19 +13,15 @@
namespace llvm::MCD {
// Disassembler state machine opcodes.
-// nts_t is either uint16_t or uint24_t based on whether large decoder table is
-// enabled.
enum DecoderOps {
- OPC_Scope = 1, // OPC_Scope(nts_t NumToSkip)
- OPC_ExtractField, // OPC_ExtractField(uleb128 Start, uint8_t Len)
- OPC_FilterValueOrSkip, // OPC_FilterValueOrSkip(uleb128 Val, nts_t NumToSkip)
- OPC_FilterValue, // OPC_FilterValue(uleb128 Val)
- OPC_CheckField, // OPC_CheckField(uleb128 Start, uint8_t Len,
- // uleb128 Val)
- OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx)
- OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
- OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx)
- OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
+ OPC_Scope = 1, // OPC_Scope(uleb128 Size)
+ OPC_SwitchField, // OPC_SwitchField(uleb128 Start, uint8_t Len,
+ // [uleb128 Val, uleb128 Size]...)
+ OPC_CheckField, // OPC_CheckField(uleb128 Start, uint8_t Len, uleb128 Val)
+ OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx)
+ OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
+ OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx)
+ OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
};
} // namespace llvm::MCD
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 9aa7d31c62693..4b81a23b2cfc8 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -30,7 +30,6 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/MC/MCDecoderOps.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -56,7 +55,6 @@
#include <vector>
using namespace llvm;
-using namespace llvm::MCD;
#define DEBUG_TYPE "decoder-emitter"
@@ -84,12 +82,6 @@ static cl::opt<SuppressLevel> DecoderEmitterSuppressDuplicates(
"significantly reducing Table Duplications")),
cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat));
-static cl::opt<bool> LargeTable(
- "large-decoder-table",
- cl::desc("Use large decoder table format. This uses 24 bits for offset\n"
- "in the table instead of the default 16 bits."),
- cl::init(false), cl::cat(DisassemblerEmitterCat));
-
static cl::opt<bool> UseFnTableInDecodeToMCInst(
"use-fn-table-in-decode-to-mcinst",
cl::desc(
@@ -127,8 +119,6 @@ STATISTIC(NumInstructions, "Number of instructions considered");
STATISTIC(NumEncodingsSupported, "Number of encodings supported");
STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");
-static unsigned getNumToSkipInBytes() { return LargeTable ? 3 : 2; }
-
/// Similar to KnownBits::print(), but allows you to specify a character to use
/// to print unknown bits.
static void printKnownBits(raw_ostream &OS, const KnownBits &Bits,
@@ -163,67 +153,7 @@ class LessEncodingIDByWidth {
using PredicateSet = SetVector<CachedHashString>;
using DecoderSet = SetVector<CachedHashString>;
-class DecoderTable {
-public:
- DecoderTable() { Data.reserve(16384); }
-
- void clear() { Data.clear(); }
- size_t size() const { return Data.size(); }
- const uint8_t *data() const { return Data.data(); }
-
- using const_iterator = std::vector<uint8_t>::const_iterator;
- const_iterator begin() const { return Data.begin(); }
- const_iterator end() const { return Data.end(); }
-
- /// Inserts a state machine opcode into the table.
- void insertOpcode(DecoderOps Opcode) { Data.push_back(Opcode); }
-
- /// Inserts a uint8 encoded value into the table.
- void insertUInt8(unsigned Value) {
- assert(isUInt<8>(Value));
- Data.push_back(Value);
- }
-
- /// Inserts a ULEB128 encoded value into the table.
- void insertULEB128(uint64_t Value) {
- // Encode and emit the value to filter against.
- uint8_t Buffer[16];
- unsigned Len = encodeULEB128(Value, Buffer);
- Data.insert(Data.end(), Buffer, Buffer + Len);
- }
-
- // Insert space for `NumToSkip` and return the position
- // in the table for patching.
- size_t insertNumToSkip() {
- size_t Size = Data.size();
- Data.insert(Data.end(), getNumToSkipInBytes(), 0);
- return Size;
- }
-
- void patchNumToSkip(size_t FixupIdx, uint32_t DestIdx) {
- // Calculate the distance from the byte following the fixup entry byte
- // to the destination. The Target is calculated from after the
- // `getNumToSkipInBytes()`-byte NumToSkip entry itself, so subtract
- // `getNumToSkipInBytes()` from the displacement here to account for that.
- assert(DestIdx >= FixupIdx + getNumToSkipInBytes() &&
- "Expecting a forward jump in the decoding table");
- uint32_t Delta = DestIdx - FixupIdx - getNumToSkipInBytes();
- if (!isUIntN(8 * getNumToSkipInBytes(), Delta))
- PrintFatalError(
- "disassembler decoding table too large, try --large-decoder-table");
-
- Data[FixupIdx] = static_cast<uint8_t>(Delta);
- Data[FixupIdx + 1] = static_cast<uint8_t>(Delta >> 8);
- if (getNumToSkipInBytes() == 3)
- Data[FixupIdx + 2] = static_cast<uint8_t>(Delta >> 16);
- }
-
-private:
- std::vector<uint8_t> Data;
-};
-
struct DecoderTableInfo {
- DecoderTable Table;
PredicateSet Predicates;
DecoderSet Decoders;
bool HasCheckPredicate;
@@ -253,6 +183,8 @@ struct DecoderTableInfo {
using NamespacesHwModesMap = std::map<StringRef, std::set<unsigned>>;
+class DecoderTreeNode;
+
class DecoderEmitter {
const RecordKeeper &RK;
CodeGenTarget Target;
@@ -272,7 +204,7 @@ class DecoderEmitter {
// Emit the decoder state machine table.
void emitTable(formatted_raw_ostream &OS, DecoderTableInfo &TableInfo,
StringRef Namespace, unsigned HwModeID, unsigned BitWidth,
- ArrayRef<unsigned> EncodingIDs) const;
+ const DecoderTreeNode *Tree) const;
void emitInstrLenTable(formatted_raw_ostream &OS,
ArrayRef<unsigned> InstrLen) const;
void emitPredicateFunction(formatted_raw_ostream &OS,
@@ -383,7 +315,7 @@ enum bitAttr_t {
class FilterChooser {
// TODO: Unfriend by providing the necessary accessors.
- friend class DecoderTableBuilder;
+ friend class DecoderTreeBuilder;
// Vector of encodings to choose our filter.
ArrayRef<InstructionEncoding> Encodings;
@@ -488,7 +420,8 @@ class FilterChooser {
// This returns a list of undecoded bits of an instructions, for example,
// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
// decoded bits in order to verify that the instruction matches the Opcode.
- std::vector<Island> getIslands(const KnownBits &EncodingBits) const;
+ static std::vector<Island> getIslands(const KnownBits &EncodingBits,
+ const KnownBits &FilterBits);
/// Scans the well-known encoding bits of the encodings and, builds up a list
/// of candidate filters, and then returns the best one, if any.
@@ -507,35 +440,6 @@ class FilterChooser {
void dump() const;
};
-class DecoderTableBuilder {
- const CodeGenTarget &Target;
- ArrayRef<InstructionEncoding> Encodings;
- DecoderTableInfo &TableInfo;
-
-public:
- DecoderTableBuilder(const CodeGenTarget &Target,
- ArrayRef<InstructionEncoding> Encodings,
- DecoderTableInfo &TableInfo)
- : Target(Target), Encodings(Encodings), TableInfo(TableInfo) {}
-
- void buildTable(const FilterChooser &FC, unsigned BitWidth) const {
- // When specializing decoders per bit width, each decoder table will begin
- // with the bitwidth for that table.
- if (SpecializeDecodersPerBitwidth)
- TableInfo.Table.insertULEB128(BitWidth);
- emitTableEntries(FC);
- }
-
-private:
- void emitPredicateTableEntry(unsigned EncodingID) const;
-
- void emitSoftFailTableEntry(unsigned EncodingID) const;
-
- void emitSingletonTableEntry(const FilterChooser &FC) const;
-
- void emitTableEntries(const FilterChooser &FC) const;
-};
-
} // end anonymous namespace
///////////////////////////
@@ -612,221 +516,6 @@ unsigned Filter::usefulness() const {
// //
//////////////////////////////////
-static StringRef getDecoderOpName(DecoderOps Op) {
-#define CASE(OP) \
- case OP: \
- return #OP
- switch (Op) {
- CASE(OPC_Scope);
- CASE(OPC_ExtractField);
- CASE(OPC_FilterValueOrSkip);
- CASE(OPC_FilterValue);
- CASE(OPC_CheckField);
- CASE(OPC_CheckPredicate);
- CASE(OPC_Decode);
- CASE(OPC_TryDecode);
- CASE(OPC_SoftFail);
- }
-#undef CASE
- llvm_unreachable("Unknown decoder op");
-}
-
-// Emit the decoder state machine table.
-void DecoderEmitter::emitTable(formatted_raw_ostream &OS,
- DecoderTableInfo &TableInfo, StringRef Namespace,
- unsigned HwModeID, unsigned BitWidth,
- ArrayRef<unsigned> EncodingIDs) const {
- // We'll need to be able to map from a decoded opcode into the corresponding
- // EncodingID for this specific combination of BitWidth and Namespace. This
- // is used below to index into Encodings.
- DenseMap<unsigned, unsigned> OpcodeToEncodingID;
- OpcodeToEncodingID.reserve(EncodingIDs.size());
- for (unsigned EncodingID : EncodingIDs) {
- const Record *InstDef = Encodings[EncodingID].getInstruction()->TheDef;
- OpcodeToEncodingID[Target.getInstrIntValue(InstDef)] = EncodingID;
- }
-
- OS << "static const uint8_t DecoderTable" << Namespace;
- if (HwModeID != DefaultMode)
- OS << '_' << Target.getHwModes().getModeName(HwModeID);
- OS << BitWidth << "[" << TableInfo.Table.size() << "] = {\n";
-
- // Emit ULEB128 encoded value to OS, returning the number of bytes emitted.
- auto EmitULEB128 = [](DecoderTable::const_iterator &I,
- formatted_raw_ostream &OS) {
- while (*I >= 128)
- OS << (unsigned)*I++ << ", ";
- OS << (unsigned)*I++ << ", ";
- };
-
- // Emit `getNumToSkipInBytes()`-byte numtoskip value to OS, returning the
- // NumToSkip value.
- auto EmitNumToSkip = [](DecoderTable::const_iterator &I,
- formatted_raw_ostream &OS) {
- uint8_t Byte = *I++;
- uint32_t NumToSkip = Byte;
- OS << (unsigned)Byte << ", ";
- Byte = *I++;
- OS << (unsigned)Byte << ", ";
- NumToSkip |= Byte << 8;
- if (getNumToSkipInBytes() == 3) {
- Byte = *I++;
- OS << (unsigned)(Byte) << ", ";
- NumToSkip |= Byte << 16;
- }
- return NumToSkip;
- };
-
- // FIXME: We may be able to use the NumToSkip values to recover
- // appropriate indentation levels.
- DecoderTable &Table = TableInfo.Table;
- DecoderTable::const_iterator I = Table.begin();
- DecoderTable::const_iterator E = Table.end();
- const uint8_t *const EndPtr = Table.data() + Table.size();
-
- auto EmitPos = [&OS](uint32_t Pos) {
- constexpr uint32_t StartColumn = 12;
- OS << "/* " << Pos << " */";
- OS.PadToColumn(StartColumn);
- };
-
- auto StartComment = [&OS]() {
- constexpr uint32_t CommentColumn = 52;
- OS.PadToColumn(CommentColumn);
- OS << "// ";
- };
-
- auto EmitNumToSkipComment = [&](uint32_t NumToSkip) {
- uint32_t Index = (I - Table.begin()) + NumToSkip;
- OS << "skip to " << Index;
- };
-
- // The first entry when specializing decoders per bitwidth is the bitwidth.
- // This will be used for additional checks in `decodeInstruction`.
- if (SpecializeDecodersPerBitwidth) {
- EmitPos(0);
- EmitULEB128(I, OS);
- StartComment();
- OS << "Bitwidth " << BitWidth << '\n';
- }
-
- auto DecodeAndEmitULEB128 = [EndPtr,
- &EmitULEB128](DecoderTable::const_iterator &I,
- formatted_raw_ostream &OS) {
- const char *ErrMsg = nullptr;
- uint64_t Value = decodeULEB128(&*I, nullptr, EndPtr, &ErrMsg);
- assert(ErrMsg == nullptr && "ULEB128 value too large!");
-
- EmitULEB128(I, OS);
- return Value;
- };
-
- while (I != E) {
- assert(I < E && "incomplete decode table entry!");
-
- uint32_t Pos = I - Table.begin();
- EmitPos(Pos);
- const uint8_t DecoderOp = *I++;
- OS << getDecoderOpName(static_cast<DecoderOps>(DecoderOp)) << ", ";
- switch (DecoderOp) {
- default:
- PrintFatalError("Invalid decode table opcode: " + Twine((int)DecoderOp) +
- " at index " + Twine(Pos));
- case OPC_Scope: {
- uint32_t NumToSkip = EmitNumToSkip(I, OS);
- StartComment();
- uint32_t Index = (I - Table.begin()) + NumToSkip;
- OS << "end scope at " << Index;
- break;
- }
- case OPC_ExtractField: {
- // ULEB128 encoded start value.
- unsigned Start = DecodeAndEmitULEB128(I, OS);
- unsigned Len = *I++;
- OS << Len << ',';
- StartComment();
- OS << "Field = Inst{";
- if (Len > 1)
- OS << (Start + Len - 1) << '-';
- OS << Start << '}';
- break;
- }
- case OPC_FilterValueOrSkip: {
- // The filter value is ULEB128 encoded.
- uint64_t FilterVal = DecodeAndEmitULEB128(I, OS);
- uint32_t NumToSkip = EmitNumToSkip(I, OS);
- StartComment();
- OS << "if Field != " << format_hex(FilterVal, 0) << ' ';
- EmitNumToSkipComment(NumToSkip);
- break;
- }
- case OPC_FilterValue: {
- // The filter value is ULEB128 encoded.
- uint64_t FilterVal = DecodeAndEmitULEB128(I, OS);
-
- StartComment();
- OS << "if Field != " << format_hex(FilterVal, 0) << " pop scope";
- break;
- }
- case OPC_CheckField: {
- // ULEB128 encoded start value.
- unsigned Start = DecodeAndEmitULEB128(I, OS);
-
- // 8-bit length.
- unsigned Len = *I++;
- OS << Len << ", ";
-
- // ULEB128 encoded field value.
- uint64_t FieldVal = DecodeAndEmitULEB128(I, OS);
-
- StartComment();
- OS << "if Inst{";
- if (Len > 1)
- OS << (Start + Len - 1) << '-';
- OS << Start << "} != " << format_hex(FieldVal, 0) << " pop scope";
- break;
- }
- case OPC_CheckPredicate: {
- unsigned PIdx = DecodeAndEmitULEB128(I, OS);
- StartComment();
- OS << "if !checkPredicate(" << PIdx << ") pop scope";
- break;
- }
- case OPC_Decode:
- case OPC_TryDecode: {
- // Decode the Opcode value.
- unsigned Opc = DecodeAndEmitULEB128(I, OS);
-
- // Decoder index.
- unsigned DecodeIdx = DecodeAndEmitULEB128(I, OS);
-
- auto EncI = OpcodeToEncodingID.find(Opc);
- assert(EncI != OpcodeToEncodingID.end() && "no encoding entry");
- auto EncodingID = EncI->second;
-
- StartComment();
- OS << "Opcode: " << Encodings[EncodingID].getName()
- << ", DecodeIdx: " << DecodeIdx;
- break;
- }
- case OPC_SoftFail: {
- // Decode the positive mask.
- uint64_t PositiveMask = DecodeAndEmitULEB128(I, OS);
-
- // Decode the negative mask.
- uint64_t NegativeMask = DecodeAndEmitULEB128(I, OS);
-
- StartComment();
- OS << "positive mask: " << format_hex(PositiveMask, 0)
- << "negative mask: " << format_hex(NegativeMask, 0);
- break;
- }
- }
- OS << '\n';
- }
- OS << "};\n\n";
-}
-
void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS,
ArrayRef<unsigned> InstrLen) const {
OS << "static const uint8_t InstrLenTable[] = {\n";
@@ -952,7 +641,8 @@ void FilterChooser::dumpStack(raw_ostream &OS, indent Indent,
// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
// decoded bits in order to verify that the instruction matches the Opcode.
std::vector<FilterChooser::Island>
-FilterChooser::getIslands(const KnownBits &EncodingBits) const {
+FilterChooser::getIslands(const KnownBits &EncodingBits,
+ const KnownBits &FilterBits) {
std::vector<Island> Islands;
uint64_t FieldVal;
unsigned StartBit;
@@ -965,7 +655,7 @@ FilterChooser::getIslands(const KnownBits &EncodingBits) const {
unsigned FilterWidth = FilterBits.getBitWidth();
for (unsigned i = 0; i != FilterWidth; ++i) {
bool IsKnown = EncodingBits.Zero[i] || EncodingBits.One[i];
- bool Filtered = isPositionFiltered(i);
+ bool Filtered = FilterBits.Zero[i] || FilterBits.One[i];
switch (State) {
default:
llvm_unreachable("Unreachable code!");
@@ -1095,93 +785,6 @@ static std::string getPredicateString(const InstructionEncoding &Encoding,
return Predicate;
}
-void DecoderTableBuilder::emitPredicateTableEntry(unsigned EncodingID) const {
- const InstructionEncoding &Encoding = Encodings[EncodingID];
- std::string Predicate = getPredicateString(Encoding, Target.getName());
- if (Predicate.empty())
- return;
-
- // Using the full predicate string as the key value here is a bit
- // heavyweight, but is effective. If the string comparisons become a
- // performance concern, we can implement a mangling of the predicate
- // data easily enough with a map back to the actual string. That's
- // overkill for now, though.
- TableInfo.insertPredicate(Predicate);
- unsigned PredicateIndex = TableInfo.getPredicateIndex(Predicate);
-
- TableInfo.Table.insertOpcode(OPC_CheckPredicate);
- TableInfo.Table.insertULEB128(PredicateIndex);
- TableInfo.HasCheckPredicate = true;
-}
-
-void DecoderTableBuilder::emitSoftFailTableEntry(unsigned EncodingID) const {
- const InstructionEncoding &Encoding = Encodings[EncodingID];
- const KnownBits &InstBits = Encoding.getInstBits();
- const APInt &SoftFailMask = Encoding.getSoftFailMask();
-
- if (SoftFailMask.isZero())
- return;
-
- APInt PositiveMask = InstBits.Zero & SoftFailMask;
- APInt NegativeMask = InstBits.One & SoftFailMask;
-
- TableInfo.Table.insertOpcode(OPC_SoftFail);
- TableInfo.Table.insertULEB128(PositiveMask.getZExtValue());
- TableInfo.Table.insertULEB128(NegativeMask.getZExtValue());
- TableInfo.HasSoftFail = true;
-}
-
-// Emits table entries to decode the singleton.
-void DecoderTableBuilder::emitSingletonTableEntry(
- const FilterChooser &FC) const {
- unsigned EncodingID = *FC.SingletonEncodingID;
- const InstructionEncoding &Encoding = Encodings[EncodingID];
- KnownBits EncodingBits = Encoding.getMandatoryBits();
-
- // Look for islands of undecoded bits of the singleton.
- std::vector<FilterChooser::Island> Islands = FC.getIslands(EncodingBits);
-
- // Emit the predicate table entry if one is needed.
- emitPredicateTableEntry(EncodingID);
-
- // Check any additional encoding fields needed.
- for (const FilterChooser::Island &Ilnd : reverse(Islands)) {
- TableInfo.Table.insertOpcode(OPC_CheckField);
- TableInfo.Table.insertULEB128(Ilnd.StartBit);
- TableInfo.Table.insertUInt8(Ilnd.NumBits);
- TableInfo.Table.insertULEB128(Ilnd.FieldVal);
- }
-
- // Check for soft failure of the match.
- emitSoftFailTableEntry(EncodingID);
-
- // Using the full decoder string as the key value here is a bit
- // heavyweight, but is effective. If the string comparisons become a
- // performance concern, we can implement a mangling of the predicate
- // data easily enough with a map back to the actual string. That's
- // overkill for now, though.
- std::string Decoder = getDecoderString(Encoding);
- TableInfo.insertDecoder(Decoder);
- unsigned DecoderIndex = TableInfo.getDecoderIndex(Decoder);
-
- // Produce OPC_Decode or OPC_TryDecode opcode based on the information
- // whether the instruction decoder is complete or not. If it is complete
- // then it handles all possible values of remaining variable/unfiltered bits
- // and for any value can determine if the bitpattern is a valid instruction
- // or not. This means OPC_Decode will be the final step in the decoding
- // process. If it is not complete, then the Fail return code from the
- // decoder method indicates that additional processing should be done to see
- // if there is any other instruction that also matches the bitpattern and
- // can decode it.
- const DecoderOps DecoderOp =
- Encoding.hasCompleteDecoder() ? OPC_Decode : OPC_TryDecode;
- TableInfo.Table.insertOpcode(DecoderOp);
- const Record *InstDef = Encodings[EncodingID].getInstruction()->TheDef;
- TableInfo.Table.insertULEB128(Target.getInstrIntValue(InstDef));
- TableInfo.Table.insertULEB128(DecoderIndex);
- TableInfo.HasTryDecode |= DecoderOp == OPC_TryDecode;
-}
-
std::unique_ptr<Filter>
FilterChooser::findBestFilter(ArrayRef<bitAttr_t> BitAttrs, bool AllowMixed,
bool Greedy) const {
@@ -1197,7 +800,7 @@ FilterChooser::findBestFilter(ArrayRef<bitAttr_t> BitAttrs, bool AllowMixed,
KnownBits EncodingBits = Encoding.getMandatoryBits();
// Look for islands of undecoded bits of any instruction.
- std::vector<Island> Islands = getIslands(EncodingBits);
+ std::vector<Island> Islands = getIslands(EncodingBits, FilterBits);
if (!Islands.empty()) {
// Found an instruction with island(s). Now just assign a filter.
return std::make_unique<Filter>(
@@ -1457,83 +1060,11 @@ void FilterChooser::dump() const {
}
}
-void DecoderTableBuilder::emitTableEntries(const FilterChooser &FC) const {
- DecoderTable &Table = TableInfo.Table;
-
- // If there are other encodings that could match if those with all bits
- // known don't, enter a scope so that they have a chance.
- size_t FixupLoc = 0;
- if (FC.VariableFC) {
- Table.insertOpcode(OPC_Scope);
- FixupLoc = Table.insertNumToSkip();
- }
-
- if (FC.SingletonEncodingID) {
- assert(FC.FilterChooserMap.empty());
- // There is only one encoding in which all bits in the filtered range are
- // fully defined, but we still need to check if the remaining (unfiltered)
- // bits are valid for this encoding. We also need to check predicates etc.
- emitSingletonTableEntry(FC);
- } else if (FC.FilterChooserMap.size() == 1) {
- // If there is only one possible field value, emit a combined OPC_CheckField
- // instead of OPC_ExtractField + OPC_FilterValue.
- const auto &[FilterVal, Delegate] = *FC.FilterChooserMap.begin();
- Table.insertOpcode(OPC_CheckField);
- Table.insertULEB128(FC.StartBit);
- Table.insertUInt8(FC.NumBits);
- Table.insertULEB128(FilterVal);
-
- // Emit table entries for the only case.
- emitTableEntries(*Delegate);
- } else {
- // The general case: emit a switch over the field value.
- Table.insertOpcode(OPC_ExtractField);
- Table.insertULEB128(FC.StartBit);
- Table.insertUInt8(FC.NumBits);
-
- // Emit switch cases for all but the last element.
- for (const auto &[FilterVal, Delegate] : drop_end(FC.FilterChooserMap)) {
- Table.insertOpcode(OPC_FilterValueOrSkip);
- Table.insertULEB128(FilterVal);
- size_t FixupPos = Table.insertNumToSkip();
-
- // Emit table entries for this case.
- emitTableEntries(*Delegate);
-
- // Patch the previous FilterValueOrSkip to fall through to the next case.
- Table.patchNumToSkip(FixupPos, Table.size());
- }
-
- // Emit a switch case for the last element. It never falls through;
- // if it doesn't match, we leave the current scope.
- const auto &[FilterVal, Delegate] = *FC.FilterChooserMap.rbegin();
- Table.insertOpcode(OPC_FilterValue);
- Table.insertULEB128(FilterVal);
-
- // Emit table entries for the last case.
- emitTableEntries(*Delegate);
- }
-
- if (FC.VariableFC) {
- Table.patchNumToSkip(FixupLoc, Table.size());
- emitTableEntries(*FC.VariableFC);
- }
-}
-
// emitDecodeInstruction - Emit the templated helper function
// decodeInstruction().
static void emitDecodeInstruction(formatted_raw_ostream &OS, bool IsVarLenInst,
const DecoderTableInfo &TableInfo) {
OS << R"(
-static unsigned decodeNumToSkip(const uint8_t *&Ptr) {
- unsigned NumToSkip = *Ptr++;
- NumToSkip |= (*Ptr++) << 8;
-)";
- if (getNumToSkipInBytes() == 3)
- OS << " NumToSkip |= (*Ptr++) << 16;\n";
- OS << R"( return NumToSkip;
-}
-
template <typename InsnType>
static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
InsnType insn, uint64_t Address,
@@ -1560,7 +1091,6 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
OS << R"(
SmallVector<const uint8_t *, 8> ScopeStack;
- uint64_t CurFieldValue = 0;
DecodeStatus S = MCDisassembler::Success;
while (true) {
ptrdiff_t Loc = Ptr - DecodeTable;
@@ -1571,51 +1101,34 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
<< (int)DecoderOp << '\n';
return MCDisassembler::Fail;
case OPC_Scope: {
- unsigned NumToSkip = decodeNumToSkip(Ptr);
+ unsigned NumToSkip = decodeULEB128AndIncUnsafe(Ptr);
const uint8_t *SkipTo = Ptr + NumToSkip;
ScopeStack.push_back(SkipTo);
LLVM_DEBUG(dbgs() << Loc << ": OPC_Scope(" << SkipTo - DecodeTable
<< ")\n");
break;
}
- case OPC_ExtractField: {
+ case OPC_SwitchField: {
// Decode the start value.
unsigned Start = decodeULEB128AndIncUnsafe(Ptr);
unsigned Len = *Ptr++;)";
if (IsVarLenInst)
OS << "\n makeUp(insn, Start + Len);";
OS << R"(
- CurFieldValue = fieldFromInstruction(insn, Start, Len);
- LLVM_DEBUG(dbgs() << Loc << ": OPC_ExtractField(" << Start << ", "
- << Len << "): " << CurFieldValue << "\n");
- break;
- }
- case OPC_FilterValueOrSkip: {
- // Decode the field value.
- uint64_t Val = decodeULEB128AndIncUnsafe(Ptr);
- bool Failed = Val != CurFieldValue;
- unsigned NumToSkip = decodeNumToSkip(Ptr);
- const uint8_t *SkipTo = Ptr + NumToSkip;
-
- LLVM_DEBUG(dbgs() << Loc << ": OPC_FilterValueOrSkip(" << Val << ", "
- << SkipTo - DecodeTable << ") "
- << (Failed ? "FAIL, " : "PASS\n"));
-
- if (Failed) {
- Ptr = SkipTo;
- LLVM_DEBUG(dbgs() << "continuing at " << Ptr - DecodeTable << '\n');
+ uint64_t FieldValue = fieldFromInstruction(insn, Start, Len);
+ uint64_t CaseValue;
+ unsigned CaseSize;
+ while (true) {
+ CaseValue = decodeULEB128AndIncUnsafe(Ptr);
+ CaseSize = decodeULEB128AndIncUnsafe(Ptr);
+ if (FieldValue == CaseValue || !CaseSize)
+ break;
+ Ptr += CaseSize;
}
- break;
- }
- case OPC_FilterValue: {
- // Decode the field value.
- uint64_t Val = decodeULEB128AndIncUnsafe(Ptr);
- bool Failed = Val != CurFieldValue;
-
- LLVM_DEBUG(dbgs() << Loc << ": OPC_FilterValue(" << Val << ") "
- << (Failed ? "FAIL, " : "PASS\n"));
-
- if (Failed) {
+ if (FieldValue == CaseValue) {
+ LLVM_DEBUG(dbgs() << Loc << ": OPC_SwitchField(" << Start << ", " << Len
+ << "): " << FieldValue << '\n');
+ } else {
if (ScopeStack.empty()) {
LLVM_DEBUG(dbgs() << "returning Fail\n");
return MCDisassembler::Fail;
@@ -1753,6 +1266,624 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
)";
}
+namespace {
+
+class DecoderTreeNode {
+public:
+ virtual ~DecoderTreeNode() = default;
+
+ enum KindTy {
+ CheckAny,
+ CheckAll,
+ CheckField,
+ SwitchField,
+ CheckPredicate,
+ SoftFail,
+ Decode,
+ };
+
+ KindTy getKind() const { return Kind; }
+
+protected:
+ explicit DecoderTreeNode(KindTy Kind) : Kind(Kind) {}
+
+private:
+ KindTy Kind;
+};
+
+class CheckAnyNode : public DecoderTreeNode {
+ SmallVector<std::unique_ptr<DecoderTreeNode>, 0> Children;
+
+ static const DecoderTreeNode *
+ mapElement(decltype(Children)::const_reference Element) {
+ return Element.get();
+ }
+
+public:
+ CheckAnyNode() : DecoderTreeNode(CheckAny) {}
+
+ void addChild(std::unique_ptr<DecoderTreeNode> N) {
+ Children.push_back(std::move(N));
+ }
+
+ using child_iterator = mapped_iterator<decltype(Children)::const_iterator,
+ decltype(&mapElement)>;
+
+ child_iterator child_begin() const {
+ return child_iterator(Children.begin(), mapElement);
+ }
+
+ child_iterator child_end() const {
+ return child_iterator(Children.end(), mapElement);
+ }
+
+ iterator_range<child_iterator> children() const {
+ return make_range(child_begin(), child_end());
+ }
+};
+
+class CheckAllNode : public DecoderTreeNode {
+ SmallVector<std::unique_ptr<DecoderTreeNode>, 0> Children;
+
+ static const DecoderTreeNode *
+ mapElement(decltype(Children)::const_reference Element) {
+ return Element.get();
+ }
+
+public:
+ CheckAllNode() : DecoderTreeNode(CheckAll) {}
+
+ void addChild(std::unique_ptr<DecoderTreeNode> Child) {
+ Children.push_back(std::move(Child));
+ }
+
+ using child_iterator = mapped_iterator<decltype(Children)::const_iterator,
+ decltype(&mapElement)>;
+
+ child_iterator child_begin() const {
+ return child_iterator(Children.begin(), mapElement);
+ }
+
+ child_iterator child_end() const {
+ return child_iterator(Children.end(), mapElement);
+ }
+
+ iterator_range<child_iterator> children() const {
+ return make_range(child_begin(), child_end());
+ }
+};
+
+class CheckFieldNode : public DecoderTreeNode {
+ unsigned StartBit;
+ unsigned NumBits;
+ uint64_t Value;
+
+public:
+ CheckFieldNode(unsigned StartBit, unsigned NumBits, uint64_t Value)
+ : DecoderTreeNode(CheckField), StartBit(StartBit), NumBits(NumBits),
+ Value(Value) {}
+
+ unsigned getStartBit() const { return StartBit; }
+
+ unsigned getNumBits() const { return NumBits; }
+
+ uint64_t getValue() const { return Value; }
+};
+
+class SwitchFieldNode : public DecoderTreeNode {
+ unsigned StartBit;
+ unsigned NumBits;
+ std::map<uint64_t, std::unique_ptr<DecoderTreeNode>> Cases;
+
+ static std::pair<uint64_t, const DecoderTreeNode *>
+ mapElement(decltype(Cases)::const_reference Element) {
+ return std::pair(Element.first, Element.second.get());
+ }
+
+public:
+ SwitchFieldNode(unsigned StartBit, unsigned NumBits)
+ : DecoderTreeNode(SwitchField), StartBit(StartBit), NumBits(NumBits) {}
+
+ void addCase(uint64_t Value, std::unique_ptr<DecoderTreeNode> N) {
+ Cases.try_emplace(Value, std::move(N));
+ }
+
+ unsigned getStartBit() const { return StartBit; }
+
+ unsigned getNumBits() const { return NumBits; }
+
+ using case_iterator =
+ mapped_iterator<decltype(Cases)::const_iterator, decltype(&mapElement)>;
+
+ case_iterator case_begin() const {
+ return case_iterator(Cases.begin(), mapElement);
+ }
+
+ case_iterator case_end() const {
+ return case_iterator(Cases.end(), mapElement);
+ }
+
+ iterator_range<case_iterator> cases() const {
+ return make_range(case_begin(), case_end());
+ }
+};
+
+class CheckPredicateNode : public DecoderTreeNode {
+ std::string PredicateString;
+
+public:
+ explicit CheckPredicateNode(std::string PredicateString)
+ : DecoderTreeNode(CheckPredicate),
+ PredicateString(std::move(PredicateString)) {}
+
+ StringRef getPredicateString() const { return PredicateString; }
+};
+
+class SoftFailNode : public DecoderTreeNode {
+ uint64_t PositiveMask, NegativeMask;
+
+public:
+ SoftFailNode(uint64_t PositiveMask, uint64_t NegativeMask)
+ : DecoderTreeNode(SoftFail), PositiveMask(PositiveMask),
+ NegativeMask(NegativeMask) {}
+
+ uint64_t getPositiveMask() const { return PositiveMask; }
+ uint64_t getNegativeMask() const { return NegativeMask; }
+};
+
+class DecodeNode : public DecoderTreeNode {
+ const InstructionEncoding &Encoding;
+ std::string DecoderString;
+
+public:
+ DecodeNode(const InstructionEncoding &Encoding, std::string DecoderString)
+ : DecoderTreeNode(Decode), Encoding(Encoding),
+ DecoderString(std::move(DecoderString)) {}
+
+ const InstructionEncoding &getEncoding() const { return Encoding; }
+
+ StringRef getDecoderString() const { return DecoderString; }
+};
+
+class DecoderTreeBuilder {
+ const CodeGenTarget &Target;
+ ArrayRef<InstructionEncoding> Encodings;
+
+public:
+ DecoderTreeBuilder(const CodeGenTarget &Target,
+ ArrayRef<InstructionEncoding> Encodings)
+ : Target(Target), Encodings(Encodings) {}
+
+ std::unique_ptr<DecoderTreeNode> buildTree(const FilterChooser &FC) {
+ return buildCheckAnyNode(FC);
+ }
+
+private:
+ std::unique_ptr<DecoderTreeNode>
+ buildTerminalNode(unsigned EncodingID, const KnownBits &FilterBits);
+
+ std::unique_ptr<DecoderTreeNode> buildCheckAllOrSwitchNode(
+ unsigned StartBit, unsigned NumBits,
+ const std::map<uint64_t, std::unique_ptr<const FilterChooser>> &FCMap);
+
+ std::unique_ptr<DecoderTreeNode> buildCheckAnyNode(const FilterChooser &FC);
+};
+
+class DecoderTableEmitter {
+ DecoderTableInfo &TableInfo;
+ formatted_raw_ostream OS;
+ unsigned IndexWidth;
+ unsigned CurrentIndex;
+ unsigned CommentIndex;
+
+public:
+ DecoderTableEmitter(DecoderTableInfo &TableInfo, raw_ostream &OS)
+ : TableInfo(TableInfo), OS(OS) {}
+
+ void emitTable(StringRef TableName, unsigned BitWidth,
+ const DecoderTreeNode *Root);
+
+private:
+ void analyzeNode(const DecoderTreeNode *Node) const;
+
+ unsigned computeNodeSize(const DecoderTreeNode *Node) const;
+ unsigned computeTableSize(const DecoderTreeNode *Root,
+ unsigned BitWidth) const;
+
+ void emitStartLine();
+ void emitOpcode(StringRef Name);
+ void emitByte(uint8_t Val);
+ void emitUInt8(unsigned Val);
+ void emitULEB128(uint64_t Val);
+ formatted_raw_ostream &emitComment(indent Indent);
+
+ void emitCheckAnyNode(const CheckAnyNode *N, indent Indent);
+ void emitCheckAllNode(const CheckAllNode *N, indent Indent);
+ void emitSwitchFieldNode(const SwitchFieldNode *N, indent Indent);
+ void emitCheckFieldNode(const CheckFieldNode *N, indent Indent);
+ void emitCheckPredicateNode(const CheckPredicateNode *N, indent Indent);
+ void emitSoftFailNode(const SoftFailNode *N, indent Indent);
+ void emitDecodeNode(const DecodeNode *N, indent Indent);
+ void emitNode(const DecoderTreeNode *N, indent Indent);
+};
+
+} // namespace
+
+std::unique_ptr<DecoderTreeNode>
+DecoderTreeBuilder::buildTerminalNode(unsigned EncodingID,
+ const KnownBits &FilterBits) {
+ const InstructionEncoding &Encoding = Encodings[EncodingID];
+ auto N = std::make_unique<CheckAllNode>();
+
+ std::string Predicate = getPredicateString(Encoding, Target.getName());
+ if (!Predicate.empty())
+ N->addChild(std::make_unique<CheckPredicateNode>(std::move(Predicate)));
+
+ std::vector<FilterChooser::Island> Islands =
+ FilterChooser::getIslands(Encoding.getMandatoryBits(), FilterBits);
+ for (const FilterChooser::Island &Ilnd : reverse(Islands)) {
+ N->addChild(std::make_unique<CheckFieldNode>(Ilnd.StartBit, Ilnd.NumBits,
+ Ilnd.FieldVal));
+ }
+
+ const KnownBits &InstBits = Encoding.getInstBits();
+ const APInt &SoftFailMask = Encoding.getSoftFailMask();
+ if (!SoftFailMask.isZero()) {
+ APInt PositiveMask = InstBits.Zero & SoftFailMask;
+ APInt NegativeMask = InstBits.One & SoftFailMask;
+ N->addChild(std::make_unique<SoftFailNode>(PositiveMask.getZExtValue(),
+ NegativeMask.getZExtValue()));
+ }
+
+ std::string DecoderIndex = getDecoderString(Encoding);
+ N->addChild(std::make_unique<DecodeNode>(Encoding, DecoderIndex));
+
+ return N;
+}
+
+std::unique_ptr<DecoderTreeNode> DecoderTreeBuilder::buildCheckAllOrSwitchNode(
+ unsigned StartBit, unsigned NumBits,
+ const std::map<uint64_t, std::unique_ptr<const FilterChooser>> &FCMap) {
+ if (FCMap.size() == 1) {
+ const auto &[FieldVal, ChildFC] = *FCMap.begin();
+ auto N = std::make_unique<CheckAllNode>();
+ N->addChild(std::make_unique<CheckFieldNode>(StartBit, NumBits, FieldVal));
+ N->addChild(buildCheckAnyNode(*ChildFC));
+ return N;
+ }
+ auto N = std::make_unique<SwitchFieldNode>(StartBit, NumBits);
+ for (const auto &[FieldVal, ChildFC] : FCMap)
+ N->addCase(FieldVal, buildCheckAnyNode(*ChildFC));
+ return N;
+}
+
+std::unique_ptr<DecoderTreeNode>
+DecoderTreeBuilder::buildCheckAnyNode(const FilterChooser &FC) {
+ auto N = std::make_unique<CheckAnyNode>();
+ if (FC.SingletonEncodingID) {
+ N->addChild(buildTerminalNode(*FC.SingletonEncodingID, FC.FilterBits));
+ } else {
+ N->addChild(buildCheckAllOrSwitchNode(FC.StartBit, FC.NumBits,
+ FC.FilterChooserMap));
+ }
+ if (FC.VariableFC) {
+ N->addChild(buildCheckAnyNode(*FC.VariableFC));
+ }
+
+ return N;
+}
+
+void DecoderTableEmitter::analyzeNode(const DecoderTreeNode *Node) const {
+ switch (Node->getKind()) {
+ case DecoderTreeNode::CheckAny: {
+ const auto *N = static_cast<const CheckAnyNode *>(Node);
+ for (const DecoderTreeNode *Child : N->children())
+ analyzeNode(Child);
+ break;
+ }
+ case DecoderTreeNode::CheckAll: {
+ const auto *N = static_cast<const CheckAllNode *>(Node);
+ for (const DecoderTreeNode *Child : N->children())
+ analyzeNode(Child);
+ break;
+ }
+ case DecoderTreeNode::CheckField:
+ break;
+ case DecoderTreeNode::SwitchField: {
+ const auto *N = static_cast<const SwitchFieldNode *>(Node);
+ for (const DecoderTreeNode *Child : make_second_range(N->cases()))
+ analyzeNode(Child);
+ break;
+ }
+ case DecoderTreeNode::CheckPredicate: {
+ const auto *N = static_cast<const CheckPredicateNode *>(Node);
+ TableInfo.insertPredicate(N->getPredicateString());
+ break;
+ }
+ case DecoderTreeNode::SoftFail:
+ break;
+ case DecoderTreeNode::Decode: {
+ const auto *N = static_cast<const DecodeNode *>(Node);
+ TableInfo.insertDecoder(N->getDecoderString());
+ break;
+ }
+ }
+}
+
+unsigned
+DecoderTableEmitter::computeNodeSize(const DecoderTreeNode *Node) const {
+ switch (Node->getKind()) {
+ case DecoderTreeNode::CheckAny: {
+ const auto *N = static_cast<const CheckAnyNode *>(Node);
+ unsigned Size = 0;
+ for (const DecoderTreeNode *Child : drop_end(N->children())) {
+ unsigned ChildSize = computeNodeSize(Child);
+ Size += 1 + getULEB128Size(ChildSize) + ChildSize;
+ }
+ return Size + computeNodeSize(*std::prev(N->child_end()));
+ }
+ case DecoderTreeNode::CheckAll: {
+ const auto *N = static_cast<const CheckAllNode *>(Node);
+ unsigned Size = 0;
+ for (const DecoderTreeNode *Child : N->children())
+ Size += computeNodeSize(Child);
+ return Size;
+ }
+ case DecoderTreeNode::CheckField: {
+ const auto *N = static_cast<const CheckFieldNode *>(Node);
+ return 1 + getULEB128Size(N->getStartBit()) + 1 +
+ getULEB128Size(N->getValue());
+ }
+ case DecoderTreeNode::SwitchField: {
+ const auto *N = static_cast<const SwitchFieldNode *>(Node);
+ unsigned Size = 1 + getULEB128Size(N->getStartBit()) + 1;
+
+ for (auto [Val, Child] : drop_end(N->cases())) {
+ unsigned ChildSize = computeNodeSize(Child);
+ Size += getULEB128Size(Val) + getULEB128Size(ChildSize) + ChildSize;
+ }
+
+ auto [Val, Child] = *std::prev(N->case_end());
+ unsigned ChildSize = computeNodeSize(Child);
+ Size += getULEB128Size(Val) + getULEB128Size(0) + ChildSize;
+ return Size;
+ }
+ case DecoderTreeNode::CheckPredicate: {
+ const auto *N = static_cast<const CheckPredicateNode *>(Node);
+ unsigned PredicateIndex =
+ TableInfo.getPredicateIndex(N->getPredicateString());
+ return 1 + getULEB128Size(PredicateIndex);
+ }
+ case DecoderTreeNode::SoftFail: {
+ const auto *N = static_cast<const SoftFailNode *>(Node);
+ return 1 + getULEB128Size(N->getPositiveMask()) +
+ getULEB128Size(N->getNegativeMask());
+ }
+ case DecoderTreeNode::Decode: {
+ const auto *N = static_cast<const DecodeNode *>(Node);
+ unsigned InstOpcode = N->getEncoding().getInstruction()->EnumVal;
+ unsigned DecoderIndex = TableInfo.getDecoderIndex(N->getDecoderString());
+ return 1 + getULEB128Size(InstOpcode) + getULEB128Size(DecoderIndex);
+ }
+ }
+ llvm_unreachable("Unknown node kind");
+}
+
+unsigned DecoderTableEmitter::computeTableSize(const DecoderTreeNode *Root,
+ unsigned BitWidth) const {
+ unsigned Size = 0;
+ if (SpecializeDecodersPerBitwidth)
+ Size += getULEB128Size(BitWidth);
+ Size += computeNodeSize(Root);
+ return Size;
+}
+
+void DecoderTableEmitter::emitStartLine() {
+ CommentIndex = CurrentIndex;
+ OS.indent(2);
+}
+
+void DecoderTableEmitter::emitOpcode(StringRef Name) {
+ emitStartLine();
+ OS << Name << ", ";
+ ++CurrentIndex;
+}
+
+void DecoderTableEmitter::emitByte(uint8_t Val) {
+ OS << static_cast<unsigned>(Val) << ", ";
+ ++CurrentIndex;
+}
+
+void DecoderTableEmitter::emitUInt8(unsigned Val) {
+ assert(isUInt<8>(Val));
+ emitByte(Val);
+}
+
+void DecoderTableEmitter::emitULEB128(uint64_t Val) {
+ while (Val >= 0x80) {
+ emitByte((Val & 0x7F) | 0x80);
+ Val >>= 7;
+ }
+ emitByte(Val);
+}
+
+formatted_raw_ostream &DecoderTableEmitter::emitComment(indent Indent) {
+ constexpr unsigned CommentColumn = 45;
+ if (OS.getColumn() > CommentColumn)
+ OS << '\n';
+ OS.PadToColumn(CommentColumn);
+ OS << "// " << format_decimal(CommentIndex, IndexWidth) << ": " << Indent;
+ return OS;
+}
+
+void DecoderTableEmitter::emitCheckAnyNode(const CheckAnyNode *N,
+ indent Indent) {
+ for (const DecoderTreeNode *Child : drop_end(N->children())) {
+ emitOpcode("OPC_Scope");
+ emitULEB128(computeNodeSize(Child));
+
+ emitComment(Indent) << "{\n";
+ emitNode(Child, Indent + 1);
+ emitComment(Indent) << "}\n";
+ }
+
+ const DecoderTreeNode *Child = *std::prev(N->child_end());
+ emitNode(Child, Indent);
+}
+
+void DecoderTableEmitter::emitCheckAllNode(const CheckAllNode *N,
+ indent Indent) {
+ for (const DecoderTreeNode *Child : N->children())
+ emitNode(Child, Indent);
+}
+
+void DecoderTableEmitter::emitSwitchFieldNode(const SwitchFieldNode *N,
+ indent Indent) {
+ unsigned LSB = N->getStartBit();
+ unsigned Width = N->getNumBits();
+ unsigned MSB = LSB + Width - 1;
+
+ emitOpcode("OPC_SwitchField");
+ emitULEB128(LSB);
+ emitUInt8(Width);
+
+ emitComment(Indent) << "switch Inst[" << MSB << ':' << LSB << "] {\n";
+
+ for (auto [Val, Child] : drop_end(N->cases())) {
+ emitStartLine();
+ emitULEB128(Val);
+ emitULEB128(computeNodeSize(Child));
+
+ emitComment(Indent) << "case " << format_hex(Val, 0) << ": {\n";
+ emitNode(Child, Indent + 1);
+ emitComment(Indent) << "}\n";
+ }
+
+ auto [Val, Child] = *std::prev(N->case_end());
+ emitStartLine();
+ emitULEB128(Val);
+ emitULEB128(0);
+
+ emitComment(Indent) << "case " << format_hex(Val, 0) << ": {\n";
+ emitNode(Child, Indent + 1);
+ emitComment(Indent) << "}\n";
+
+ emitComment(Indent) << "} // switch Inst[" << MSB << ':' << LSB << "]\n";
+}
+
+void DecoderTableEmitter::emitCheckFieldNode(const CheckFieldNode *N,
+ indent Indent) {
+ unsigned LSB = N->getStartBit();
+ unsigned Width = N->getNumBits();
+ unsigned MSB = LSB + Width - 1;
+ uint64_t Val = N->getValue();
+
+ emitOpcode("OPC_CheckField");
+ emitULEB128(LSB);
+ emitUInt8(Width);
+ emitULEB128(Val);
+
+ emitComment(Indent);
+ OS << "check Inst[" << MSB << ':' << LSB << "] == " << format_hex(Val, 0)
+ << '\n';
+}
+
+void DecoderTableEmitter::emitCheckPredicateNode(const CheckPredicateNode *N,
+ indent Indent) {
+ unsigned PredicateIndex =
+ TableInfo.getPredicateIndex(N->getPredicateString());
+
+ emitOpcode("OPC_CheckPredicate");
+ emitULEB128(PredicateIndex);
+ TableInfo.HasCheckPredicate = true;
+
+ emitComment(Indent) << "check predicate " << PredicateIndex << "\n";
+}
+
+void DecoderTableEmitter::emitSoftFailNode(const SoftFailNode *N,
+ indent Indent) {
+ uint64_t PositiveMask = N->getPositiveMask();
+ uint64_t NegativeMask = N->getNegativeMask();
+
+ emitOpcode("OPC_SoftFail");
+ emitULEB128(PositiveMask);
+ emitULEB128(NegativeMask);
+ TableInfo.HasSoftFail = true;
+
+ emitComment(Indent) << "check softfail";
+ OS << " pos=" << format_hex(PositiveMask, 10);
+ OS << " neg=" << format_hex(NegativeMask, 10) << '\n';
+}
+
+void DecoderTableEmitter::emitDecodeNode(const DecodeNode *N, indent Indent) {
+ const InstructionEncoding &Encoding = N->getEncoding();
+ unsigned InstOpcode = Encoding.getInstruction()->EnumVal;
+ unsigned DecoderIndex = TableInfo.getDecoderIndex(N->getDecoderString());
+
+ emitOpcode(Encoding.hasCompleteDecoder() ? "OPC_Decode" : "OPC_TryDecode");
+ emitULEB128(InstOpcode);
+ emitULEB128(DecoderIndex);
+
+ emitComment(Indent);
+ if (!Encoding.hasCompleteDecoder()) {
+ TableInfo.HasTryDecode = true;
+ OS << "try ";
+ }
+ OS << "decode to " << Encoding.getName() << " using decoder " << DecoderIndex
+ << '\n';
+}
+
+void DecoderTableEmitter::emitNode(const DecoderTreeNode *N, indent Indent) {
+ switch (N->getKind()) {
+ case DecoderTreeNode::CheckAny:
+ return emitCheckAnyNode(static_cast<const CheckAnyNode *>(N), Indent);
+ case DecoderTreeNode::CheckAll:
+ return emitCheckAllNode(static_cast<const CheckAllNode *>(N), Indent);
+ case DecoderTreeNode::SwitchField:
+ return emitSwitchFieldNode(static_cast<const SwitchFieldNode *>(N), Indent);
+ case DecoderTreeNode::CheckField:
+ return emitCheckFieldNode(static_cast<const CheckFieldNode *>(N), Indent);
+ case DecoderTreeNode::CheckPredicate:
+ return emitCheckPredicateNode(static_cast<const CheckPredicateNode *>(N),
+ Indent);
+ case DecoderTreeNode::SoftFail:
+ return emitSoftFailNode(static_cast<const SoftFailNode *>(N), Indent);
+ case DecoderTreeNode::Decode:
+ return emitDecodeNode(static_cast<const DecodeNode *>(N), Indent);
+ }
+ llvm_unreachable("Unknown node kind");
+}
+
+void DecoderTableEmitter::emitTable(StringRef TableName, unsigned BitWidth,
+ const DecoderTreeNode *Root) {
+ analyzeNode(Root);
+
+ unsigned TableSize = computeTableSize(Root, BitWidth);
+ OS << "static const uint8_t " << TableName << "[" << TableSize << "] = {\n";
+
+ // Calculate the number of decimal places for table indices.
+ // This is simply log10 of the table size.
+ IndexWidth = 1;
+ for (unsigned S = TableSize; S /= 10;)
+ ++IndexWidth;
+
+ CurrentIndex = 0;
+
+ // When specializing decoders per bit width, each decoder table will begin
+ // with the bitwidth for that table.
+ if (SpecializeDecodersPerBitwidth) {
+ emitStartLine();
+ emitULEB128(BitWidth);
+ emitComment(indent(0)) << "BitWidth " << BitWidth << '\n';
+ }
+
+ emitNode(Root, indent(0));
+ assert(CurrentIndex == TableSize &&
+ "The size of the emitted table differs from the calculated one");
+
+ OS << "};\n";
+}
+
/// Collects all HwModes referenced by the target for encoding purposes.
void DecoderEmitter::collectHwModesReferencedForEncodings(
std::vector<unsigned> &HwModeIDs,
@@ -1920,6 +2051,21 @@ DecoderEmitter::DecoderEmitter(const RecordKeeper &RK)
parseInstructionEncodings();
}
+// Emit the decoder state machine table.
+void DecoderEmitter::emitTable(formatted_raw_ostream &OS,
+ DecoderTableInfo &TableInfo, StringRef Namespace,
+ unsigned HwModeID, unsigned BitWidth,
+ const DecoderTreeNode *Tree) const {
+ SmallString<32> TableName("DecoderTable");
+ TableName.append(Namespace);
+ if (HwModeID != DefaultMode)
+ TableName.append({"_", Target.getHwModes().getModeName(HwModeID)});
+ TableName.append(utostr(BitWidth));
+
+ DecoderTableEmitter TableEmitter(TableInfo, OS);
+ TableEmitter.emitTable(TableName, BitWidth, Tree);
+}
+
// Emits disassembler code for instruction decoding.
void DecoderEmitter::run(raw_ostream &o) const {
formatted_raw_ostream OS(o);
@@ -1991,7 +2137,6 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
// Entries in `EncMap` are already sorted by bitwidth. So bucketing per
// bitwidth can be done on-the-fly as we iterate over the map.
DecoderTableInfo TableInfo{};
- DecoderTableBuilder TableBuilder(Target, Encodings, TableInfo);
bool HasConflict = false;
for (const auto &[BitWidth, BWMap] : EncMap) {
@@ -2005,6 +2150,9 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
if (HasConflict)
continue;
+ DecoderTreeBuilder TreeBuilder(Target, Encodings);
+ std::unique_ptr<DecoderTreeNode> Tree = TreeBuilder.buildTree(FC);
+
// The decode table is cleared for each top level decoder function. The
// predicates and decoders themselves, however, are shared across
// different decoders to give more opportunities for uniqueing.
@@ -2012,12 +2160,9 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
// across all decoder tables for a given bitwidth, else they are shared
// across all decoder tables.
// - predicates are shared across all decoder tables.
- TableInfo.Table.clear();
- TableBuilder.buildTable(FC, BitWidth);
-
// Print the table to the output stream.
emitTable(OS, TableInfo, DecoderNamespace, HwModeID, BitWidth,
- EncodingIDs);
+ Tree.get());
}
// Each BitWidth get's its own decoders and decoder function if
>From 71cbd51675277f6d4b9d41e977cb6e61e01b00ce Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 16 Sep 2025 20:53:31 +0300
Subject: [PATCH 2/3] update tests
---
.../DecoderEmitterBitwidthSpecialization.td | 44 ++++++------
.../TableGen/DecoderEmitter/VarLenDecoder.td | 28 ++++----
.../DecoderEmitter/additional-encoding.td | 54 +++++++++------
.../TableGen/DecoderEmitter/big-filter.td | 20 +++---
.../DecoderEmitter/trydecode-emission.td | 31 ++-------
.../DecoderEmitter/trydecode-emission2.td | 30 +++-----
.../DecoderEmitter/trydecode-emission3.td | 22 ++----
.../DecoderEmitter/trydecode-emission4.td | 23 ++-----
.../DecoderEmitter/var-len-conflict-1.td | 19 ++----
llvm/test/TableGen/HwModeEncodeDecode.td | 10 +--
llvm/test/TableGen/HwModeEncodeDecode2.td | 28 ++++----
llvm/test/TableGen/HwModeEncodeDecode3.td | 68 +++++++++----------
12 files changed, 168 insertions(+), 209 deletions(-)
diff --git a/llvm/test/TableGen/DecoderEmitter/DecoderEmitterBitwidthSpecialization.td b/llvm/test/TableGen/DecoderEmitter/DecoderEmitterBitwidthSpecialization.td
index 71b0c99675baa..5f3e2a8d2d7df 100644
--- a/llvm/test/TableGen/DecoderEmitter/DecoderEmitterBitwidthSpecialization.td
+++ b/llvm/test/TableGen/DecoderEmitter/DecoderEmitterBitwidthSpecialization.td
@@ -84,14 +84,14 @@ def Inst3 : Instruction16Bit<3> {
// In the default case, we emit a single decodeToMCinst function and DecodeIdx
// is shared across all bitwidths.
-// CHECK-DEFAULT-LABEL: DecoderTable8[25]
-// CHECK-DEFAULT: DecodeIdx: 0
-// CHECK-DEFAULT: DecodeIdx: 1
+// CHECK-DEFAULT-LABEL: DecoderTable8
+// CHECK-DEFAULT: using decoder 0
+// CHECK-DEFAULT: using decoder 1
// CHECK-DEFAULT: };
-// CHECK-DEFAULT-LABEL: DecoderTable16[25]
-// CHECK-DEFAULT: DecodeIdx: 2
-// CHECK-DEFAULT: DecodeIdx: 3
+// CHECK-DEFAULT-LABEL: DecoderTable16
+// CHECK-DEFAULT: using decoder 2
+// CHECK-DEFAULT: using decoder 3
// CHECK-DEFAULT: };
// CHECK-DEFAULT-LABEL: template <typename InsnType>
@@ -105,10 +105,10 @@ def Inst3 : Instruction16Bit<3> {
// When we specialize per bitwidth, we emit 2 decodeToMCInst functions and
// DecodeIdx is assigned per bit width.
-// CHECK-SPECIALIZE-NO-TABLE-LABEL: DecoderTable8[26]
-// CHECK-SPECIALIZE-NO-TABLE: /* 0 */ 8, // Bitwidth 8
-// CHECK-SPECIALIZE-NO-TABLE: DecodeIdx: 0
-// CHECK-SPECIALIZE-NO-TABLE: DecodeIdx: 1
+// CHECK-SPECIALIZE-NO-TABLE-LABEL: DecoderTable8
+// CHECK-SPECIALIZE-NO-TABLE: 8, // 0: BitWidth 8
+// CHECK-SPECIALIZE-NO-TABLE: using decoder 0
+// CHECK-SPECIALIZE-NO-TABLE: using decoder 1
// CHECK-SPECIALIZE-NO-TABLE: };
// CHECK-SPECIALIZE-NO-TABLE-LABEL: template <typename InsnType>
@@ -117,10 +117,10 @@ def Inst3 : Instruction16Bit<3> {
// CHECK-SPECIALIZE-NO-TABLE: case 0
// CHECK-SPECIALIZE-NO-TABLE: case 1
-// CHECK-SPECIALIZE-NO-TABLE-LABEL: DecoderTable16[26]
-// CHECK-SPECIALIZE-NO-TABLE: /* 0 */ 16, // Bitwidth 16
-// CHECK-SPECIALIZE-NO-TABLE: DecodeIdx: 0
-// CHECK-SPECIALIZE-NO-TABLE: DecodeIdx: 1
+// CHECK-SPECIALIZE-NO-TABLE-LABEL: DecoderTable16
+// CHECK-SPECIALIZE-NO-TABLE: 16, // 0: BitWidth 16
+// CHECK-SPECIALIZE-NO-TABLE: using decoder 0
+// CHECK-SPECIALIZE-NO-TABLE: using decoder 1
// CHECK-SPECIALIZE-NO-TABLE: };
// CHECK-SPECIALIZE-NO-TABLE-LABEL: template <typename InsnType>
@@ -138,10 +138,10 @@ def Inst3 : Instruction16Bit<3> {
// Per bitwidth specialization with function table.
// 8 bit deccoder table, functions, and function table.
-// CHECK-SPECIALIZE-TABLE-LABEL: DecoderTable8[26]
-// CHECK-SPECIALIZE-TABLE: /* 0 */ 8, // Bitwidth 8
-// CHECK-SPECIALIZE-TABLE: DecodeIdx: 0
-// CHECK-SPECIALIZE-TABLE: DecodeIdx: 1
+// CHECK-SPECIALIZE-TABLE-LABEL: DecoderTable8
+// CHECK-SPECIALIZE-TABLE: 8, // 0: BitWidth 8
+// CHECK-SPECIALIZE-TABLE: using decoder 0
+// CHECK-SPECIALIZE-TABLE: using decoder 1
// CHECK-SPECIALIZE-TABLE: };
// CHECK-SPECIALIZE-TABLE-LABEL: template <typename InsnType>
@@ -161,10 +161,10 @@ def Inst3 : Instruction16Bit<3> {
// CHECK-SPECIALIZE-TABLE-NEXT: };
// 16 bit deccoder table, functions, and function table.
-// CHECK-SPECIALIZE-TABLE-LABEL: DecoderTable16[26]
-// CHECK-SPECIALIZE-TABLE: /* 0 */ 16, // Bitwidth 16
-// CHECK-SPECIALIZE-TABLE: DecodeIdx: 0
-// CHECK-SPECIALIZE-TABLE: DecodeIdx: 1
+// CHECK-SPECIALIZE-TABLE-LABEL: DecoderTable16
+// CHECK-SPECIALIZE-TABLE: 16, // 0: BitWidth 16
+// CHECK-SPECIALIZE-TABLE: using decoder 0
+// CHECK-SPECIALIZE-TABLE: using decoder 1
// CHECK-SPECIALIZE-TABLE: };
// CHECK-SPECIALIZE-TABLE-LABEL: template <typename InsnType>
diff --git a/llvm/test/TableGen/DecoderEmitter/VarLenDecoder.td b/llvm/test/TableGen/DecoderEmitter/VarLenDecoder.td
index 0d913dc7587ed..0bead888d71d6 100644
--- a/llvm/test/TableGen/DecoderEmitter/VarLenDecoder.td
+++ b/llvm/test/TableGen/DecoderEmitter/VarLenDecoder.td
@@ -1,5 +1,4 @@
-// RUN: llvm-tblgen -gen-disassembler -I %p/../../../include %s | FileCheck %s --check-prefixes=CHECK,CHECK-SMALL
-// RUN: llvm-tblgen -gen-disassembler --large-decoder-table -I %p/../../../include %s | FileCheck %s --check-prefixes=CHECK,CHECK-LARGE
+// RUN: llvm-tblgen -gen-disassembler -I %p/../../../include %s | FileCheck %s --check-prefixes=CHECK
include "llvm/Target/Target.td"
@@ -53,19 +52,16 @@ def FOO32 : MyVarInst<MemOp32> {
// CHECK-NEXT: 43,
// CHECK-NEXT: };
-// CHECK-SMALL: /* 0 */ OPC_ExtractField, 3, 5, // Field = Inst{7-3}
-// CHECK-SMALL-NEXT: /* 3 */ OPC_FilterValueOrSkip, 8, 4, 0, // if Field != 0x8 skip to 11
-// CHECK-SMALL-NEXT: /* 7 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16
-// CHECK-SMALL-NEXT: /* 11 */ OPC_FilterValue, 9, // if Field != 0x9 pop scope
-// CHECK-SMALL-NEXT: /* 13 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
-// CHECK-SMALL-NEXT: };
-
-// CHECK-LARGE: /* 0 */ OPC_ExtractField, 3, 5, // Field = Inst{7-3}
-// CHECK-LARGE-NEXT: /* 3 */ OPC_FilterValueOrSkip, 8, 4, 0, 0, // if Field != 0x8 skip to 12
-// CHECK-LARGE-NEXT: /* 8 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16
-// CHECK-LARGE-NEXT: /* 12 */ OPC_FilterValue, 9, // if Field != 0x9 pop scope
-// CHECK-LARGE-NEXT: /* 14 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
-// CHECK-LARGE-NEXT: };
+// CHECK-LABEL: static const uint8_t DecoderTable43[15] = {
+// CHECK-NEXT: OPC_SwitchField, 3, 5, // 0: switch Inst[7:3] {
+// CHECK-NEXT: 8, 4, // 3: case 0x8: {
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 0, // 5: decode to FOO16 using decoder 0
+// CHECK-NEXT: // 5: }
+// CHECK-NEXT: 9, 0, // 9: case 0x9: {
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 1, // 11: decode to FOO32 using decoder 1
+// CHECK-NEXT: // 11: }
+// CHECK-NEXT: // 11: } // switch Inst[7:3]
+// CHECK-NEXT: };
// CHECK: case 0:
// CHECK-NEXT: tmp = fieldFromInstruction(insn, 8, 3);
@@ -86,7 +82,7 @@ def FOO32 : MyVarInst<MemOp32> {
// CHECK-NEXT: MI.addOperand(MCOperand::createImm(tmp));
// CHECK-NEXT: return S;
-// CHECK-LABEL: case OPC_ExtractField: {
+// CHECK-LABEL: case OPC_SwitchField: {
// CHECK: makeUp(insn, Start + Len);
// CHECK-LABEL: case OPC_CheckField: {
diff --git a/llvm/test/TableGen/DecoderEmitter/additional-encoding.td b/llvm/test/TableGen/DecoderEmitter/additional-encoding.td
index 0d4d3c096f83d..e60c9c35c8439 100644
--- a/llvm/test/TableGen/DecoderEmitter/additional-encoding.td
+++ b/llvm/test/TableGen/DecoderEmitter/additional-encoding.td
@@ -30,28 +30,38 @@ class I<dag out_ops, dag in_ops> : Instruction {
let OutOperandList = out_ops;
}
-// CHECK: /* 0 */ OPC_ExtractField, 12, 4, // Field = Inst{15-12}
-// CHECK-NEXT: /* 3 */ OPC_FilterValueOrSkip, 0, 15, 0, // if Field != 0x0 skip to 22
-// CHECK-NEXT: /* 7 */ OPC_Scope, 8, 0, // end scope at 18
-// CHECK-NEXT: /* 10 */ OPC_CheckField, 6, 6, 0, // if Inst{11-6} != 0x0
-// CHECK-NEXT: /* 14 */ OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
-// CHECK-NEXT: /* 18 */ OPC_TryDecode, {{[0-9]+}}, 2, 1, // Opcode: SHIFT0, DecodeIdx: 1
-// CHECK-NEXT: /* 22 */ OPC_FilterValueOrSkip, 1, 15, 0, // if Field != 0x1 skip to 41
-// CHECK-NEXT: /* 26 */ OPC_Scope, 8, 0, // end scope at 37
-// CHECK-NEXT: /* 29 */ OPC_CheckField, 6, 6, 0, // if Inst{11-6} != 0x0
-// CHECK-NEXT: /* 33 */ OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
-// CHECK-NEXT: /* 37 */ OPC_TryDecode, {{[0-9]+}}, 2, 1, // Opcode: SHIFT1, DecodeIdx: 1
-// CHECK-NEXT: /* 41 */ OPC_FilterValueOrSkip, 2, 15, 0, // if Field != 0x2 skip to 60
-// CHECK-NEXT: /* 45 */ OPC_Scope, 8, 0, // end scope at 56
-// CHECK-NEXT: /* 48 */ OPC_CheckField, 6, 6, 0, // if Inst{11-6} != 0x0
-// CHECK-NEXT: /* 52 */ OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
-// CHECK-NEXT: /* 56 */ OPC_TryDecode, {{[0-9]+}}, 2, 1, // Opcode: SHIFT2, DecodeIdx: 1
-// CHECK-NEXT: /* 60 */ OPC_FilterValue, 3, // if Field != 0x3
-// CHECK-NEXT: /* 62 */ OPC_Scope, 8, 0, // end scope at 73
-// CHECK-NEXT: /* 65 */ OPC_CheckField, 6, 6, 0, // if Inst{11-6} != 0x0
-// CHECK-NEXT: /* 69 */ OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
-// CHECK-NEXT: /* 73 */ OPC_TryDecode, {{[0-9]+}}, 2, 1, // Opcode: SHIFT3, DecodeIdx: 1
-
+// CHECK-LABEL: static const uint8_t DecoderTable16[67] = {
+// CHECK-NEXT: OPC_SwitchField, 12, 4, // 0: switch Inst[15:12] {
+// CHECK-NEXT: 0, 14, // 3: case 0x0: {
+// CHECK-NEXT: OPC_Scope, 8, // 5: {
+// CHECK-NEXT: OPC_CheckField, 6, 6, 0, // 7: check Inst[11:6] == 0x0
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 0, // 11: decode to NOP using decoder 0
+// CHECK-NEXT: // 11: }
+// CHECK-NEXT: OPC_TryDecode, {{[0-9, ]+}}, 1, // 15: try decode to SHIFT0 using decoder 1
+// CHECK-NEXT: // 15: }
+// CHECK-NEXT: 1, 14, // 19: case 0x1: {
+// CHECK-NEXT: OPC_Scope, 8, // 21: {
+// CHECK-NEXT: OPC_CheckField, 6, 6, 0, // 23: check Inst[11:6] == 0x0
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 0, // 27: decode to anonymous_10323:NOP using decoder 0
+// CHECK-NEXT: // 27: }
+// CHECK-NEXT: OPC_TryDecode, {{[0-9, ]+}}, 1, // 31: try decode to SHIFT1 using decoder 1
+// CHECK-NEXT: // 31: }
+// CHECK-NEXT: 2, 14, // 35: case 0x2: {
+// CHECK-NEXT: OPC_Scope, 8, // 37: {
+// CHECK-NEXT: OPC_CheckField, 6, 6, 0, // 39: check Inst[11:6] == 0x0
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 0, // 43: decode to anonymous_10324:NOP using decoder 0
+// CHECK-NEXT: // 43: }
+// CHECK-NEXT: OPC_TryDecode, {{[0-9, ]+}}, 1, // 47: try decode to SHIFT2 using decoder 1
+// CHECK-NEXT: // 47: }
+// CHECK-NEXT: 3, 0, // 51: case 0x3: {
+// CHECK-NEXT: OPC_Scope, 8, // 53: {
+// CHECK-NEXT: OPC_CheckField, 6, 6, 0, // 55: check Inst[11:6] == 0x0
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 0, // 59: decode to anonymous_10325:NOP using decoder 0
+// CHECK-NEXT: // 59: }
+// CHECK-NEXT: OPC_TryDecode, {{[0-9, ]+}}, 1, // 63: try decode to SHIFT3 using decoder 1
+// CHECK-NEXT: // 63: }
+// CHECK-NEXT: // 63: } // switch Inst[15:12]
+// CHECK-NEXT: };
class SHIFT<bits<2> opc> : I<(outs), (ins ShAmtOp:$shamt)>, EncSHIFT<opc>;
def SHIFT0 : SHIFT<0>;
diff --git a/llvm/test/TableGen/DecoderEmitter/big-filter.td b/llvm/test/TableGen/DecoderEmitter/big-filter.td
index 87aa7f814c3f3..fa516ad5665a5 100644
--- a/llvm/test/TableGen/DecoderEmitter/big-filter.td
+++ b/llvm/test/TableGen/DecoderEmitter/big-filter.td
@@ -11,14 +11,18 @@ class I : Instruction {
// Check that a 64-bit filter with all bits set does not confuse DecoderEmitter.
//
-// CHECK-LABEL: static const uint8_t DecoderTable128[34] = {
-// CHECK-NEXT: /* 0 */ OPC_ExtractField, 0, 64, // Field = Inst{63-0}
-// CHECK-NEXT: /* 3 */ OPC_FilterValueOrSkip, 1, 8, 0, // if Field != 0x1 skip to 15
-// CHECK-NEXT: /* 7 */ OPC_CheckField, 127, 1, 1, // if Inst{127} != 0x1
-// CHECK-NEXT: /* 11 */ OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: I2, DecodeIdx: 0
-// CHECK-NEXT: /* 15 */ OPC_FilterValue, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, // if Field != 0xffffffffffffffff
-// CHECK-NEXT: /* 26 */ OPC_CheckField, 127, 1, 0, // if Inst{127} != 0x0
-// CHECK-NEXT: /* 30 */ OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: I1, DecodeIdx: 0
+// CHECK-LABEL: static const uint8_t DecoderTable128[32] = {
+// CHECK-NEXT: OPC_SwitchField, 0, 64, // 0: switch Inst[63:0] {
+// CHECK-NEXT: 1, 8, // 3: case 0x1: {
+// CHECK-NEXT: OPC_CheckField, 127, 1, 1, // 5: check Inst[127:127] == 0x1
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 0, // 9: decode to I2 using decoder 0
+// CHECK-NEXT: // 9: }
+// CHECK-NEXT: 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0,
+// CHECK-NEXT: // 13: case 0xffffffffffffffff: {
+// CHECK-NEXT: OPC_CheckField, 127, 1, 0, // 24: check Inst[127:127] == 0x0
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 0, // 28: decode to I1 using decoder 0
+// CHECK-NEXT: // 28: }
+// CHECK-NEXT: // 28: } // switch Inst[63:0]
// CHECK-NEXT: };
def I1 : I {
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
index cdb1e327ad07d..8c0d715a87d27 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
@@ -1,5 +1,4 @@
// RUN: llvm-tblgen -gen-disassembler -I %p/../../../include %s | FileCheck %s
-// RUN: llvm-tblgen -gen-disassembler --large-decoder-table -I %p/../../../include %s | FileCheck %s --check-prefix=CHECK-LARGE
// Check that if decoding of an instruction fails and the instruction does not
// have a complete decoder method that can determine if the bitpattern is valid
@@ -34,29 +33,13 @@ def InstB : TestInstruction {
let hasCompleteDecoder = 0;
}
-// CHECK: /* 0 */ OPC_CheckField, 4, 4, 0, // if Inst{7-4} != 0x0
-// CHECK-NEXT: /* 4 */ OPC_Scope, 8, 0, // end scope at 15
-// CHECK-NEXT: /* 7 */ OPC_CheckField, 2, 2, 0, // if Inst{3-2} != 0x0
-// CHECK-NEXT: /* 11 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: InstB, DecodeIdx: 0
-// CHECK-NEXT: /* 15 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
+// CHECK-LABEL: static const uint8_t DecoderTable8[18] = {
+// CHECK-NEXT: OPC_CheckField, 4, 4, 0, // 0: check Inst[7:4] == 0x0
+// CHECK-NEXT: OPC_Scope, 8, // 4: {
+// CHECK-NEXT: OPC_CheckField, 2, 2, 0, // 6: check Inst[3:2] == 0x0
+// CHECK-NEXT: OPC_TryDecode, {{[0-9, ]+}}, 0, // 10: try decode to InstB using decoder 0
+// CHECK-NEXT: // 10: }
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 1, // 14: decode to InstA using decoder 1
// CHECK-NEXT: };
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-
-// CHECK: unsigned NumToSkip = *Ptr++;
-// CHECK-NEXT: NumToSkip |= (*Ptr++) << 8;
-// CHECK-NEXT: return NumToSkip;
-
-// CHECK-LARGE: /* 0 */ OPC_CheckField, 4, 4, 0, // if Inst{7-4} != 0x0
-// CHECK-LARGE-NEXT: /* 4 */ OPC_Scope, 8, 0, 0, // end scope at 16
-// CHECK-LARGE-NEXT: /* 8 */ OPC_CheckField, 2, 2, 0, // if Inst{3-2} != 0x0
-// CHECK-LARGE-NEXT: /* 12 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: InstB, DecodeIdx: 0
-// CHECK-LARGE-NEXT: /* 16 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
-// CHECK-LARGE-NEXT: };
-
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-
-// CHECK-LARGE: unsigned NumToSkip = *Ptr++;
-// CHECK-LARGE-NEXT: NumToSkip |= (*Ptr++) << 8;
-// CHECK-LARGE-NEXT: NumToSkip |= (*Ptr++) << 16;
-// CHECK-LARGE-NEXT: return NumToSkip;
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
index 35657ff35c86f..8614639cb24da 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
@@ -1,5 +1,4 @@
// RUN: llvm-tblgen -gen-disassembler -I %p/../../../include %s | FileCheck %s
-// RUN: llvm-tblgen -gen-disassembler --large-decoder-table -I %p/../../../include %s | FileCheck %s --check-prefix=CHECK-LARGE
include "llvm/Target/Target.td"
@@ -31,25 +30,16 @@ def InstB : TestInstruction {
let hasCompleteDecoder = 0;
}
-// CHECK: /* 0 */ OPC_CheckField, 2, 1, 0,
-// CHECK-NEXT: /* 4 */ OPC_CheckField, 5, 3, 0,
-// CHECK-NEXT: /* 8 */ OPC_Scope, 8, 0, // end scope at 19
-// CHECK-NEXT: /* 11 */ OPC_CheckField, 0, 2, 3,
-// CHECK-NEXT: /* 15 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
-// CHECK-NEXT: /* 19 */ OPC_CheckField, 3, 2, 0,
-// CHECK-NEXT: /* 23 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1,
+// CHECK-LABEL: static const uint8_t DecoderTable8[26] = {
+// CHECK-NEXT: OPC_CheckField, 2, 1, 0, // 0: check Inst[2:2] == 0x0
+// CHECK-NEXT: OPC_CheckField, 5, 3, 0, // 4: check Inst[7:5] == 0x0
+// CHECK-NEXT: OPC_Scope, 8, // 8: {
+// CHECK-NEXT: OPC_CheckField, 0, 2, 3, // 10: check Inst[1:0] == 0x3
+// CHECK-NEXT: OPC_TryDecode, {{[0-9, ]+}}, 0, // 14: try decode to InstB using decoder 0
+// CHECK-NEXT: // 14: }
+// CHECK-NEXT: OPC_CheckField, 3, 2, 0, // 18: check Inst[4:3] == 0x0
+// CHECK-NEXT: OPC_TryDecode, {{[0-9, ]+}}, 1, // 22: try decode to InstA using decoder 1
+// CHECK-NEXT: };
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
// CHECK: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-
-// CHECK-LARGE: /* 0 */ OPC_CheckField, 2, 1, 0,
-// CHECK-LARGE-NEXT: /* 4 */ OPC_CheckField, 5, 3, 0,
-// CHECK-LARGE-NEXT: /* 8 */ OPC_Scope, 8, 0, 0, // end scope at 20
-// CHECK-LARGE-NEXT: /* 12 */ OPC_CheckField, 0, 2, 3,
-// CHECK-LARGE-NEXT: /* 16 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
-// CHECK-LARGE-NEXT: /* 20 */ OPC_CheckField, 3, 2, 0,
-// CHECK-LARGE-NEXT: /* 24 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1,
-// CHECK-LARGE-NEXT: };
-
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-// CHECK-LARGE: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
index 4ac868dbb51aa..b602a8850ae87 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
@@ -1,5 +1,4 @@
// RUN: llvm-tblgen -gen-disassembler -I %p/../../../include %s | FileCheck %s
-// RUN: llvm-tblgen -gen-disassembler --large-decoder-table -I %p/../../../include %s | FileCheck %s --check-prefix=CHECK-LARGE
include "llvm/Target/Target.td"
@@ -35,20 +34,13 @@ def InstB : TestInstruction {
let AsmString = "InstB";
}
-// CHECK: /* 0 */ OPC_CheckField, 4, 4, 0,
-// CHECK-NEXT: /* 4 */ OPC_Scope, 8, 0, // end scope at 15
-// CHECK-NEXT: /* 7 */ OPC_CheckField, 2, 2, 0,
-// CHECK-NEXT: /* 11 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
-// CHECK-NEXT: /* 15 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
+// CHECK-LABEL: static const uint8_t DecoderTable8[18] = {
+// CHECK-NEXT: OPC_CheckField, 4, 4, 0, // 0: check Inst[7:4] == 0x0
+// CHECK-NEXT: OPC_Scope, 8, // 4: {
+// CHECK-NEXT: OPC_CheckField, 2, 2, 0, // 6: check Inst[3:2] == 0x0
+// CHECK-NEXT: OPC_TryDecode, {{[0-9, ]+}}, 0, // 10: try decode to InstB using decoder 0
+// CHECK-NEXT: // 10: }
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 1, // 14: decode to InstA using decoder 1
// CHECK-NEXT: };
// CHECK: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-
-// CHECK-LARGE: /* 0 */ OPC_CheckField, 4, 4, 0,
-// CHECK-LARGE-NEXT: /* 4 */ OPC_Scope, 8, 0, 0, // end scope at 16
-// CHECK-LARGE-NEXT: /* 8 */ OPC_CheckField, 2, 2, 0,
-// CHECK-LARGE-NEXT: /* 12 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
-// CHECK-LARGE-NEXT: /* 16 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
-// CHECK-LARGE-NEXT: };
-
-// CHECK-LARGE: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
index ff1a7e33747ba..b2f47f8610361 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
@@ -1,5 +1,4 @@
// RUN: llvm-tblgen -gen-disassembler -I %p/../../../include %s | FileCheck %s
-// RUN: llvm-tblgen -gen-disassembler --large-decoder-table -I %p/../../../include %s | FileCheck %s --check-prefix=CHECK-LARGE
// Test for OPC_ExtractField/OPC_CheckField with start bit > 255.
// These large start values may arise for architectures with long instruction
@@ -33,21 +32,13 @@ def InstB : TestInstruction {
let hasCompleteDecoder = 0;
}
-// CHECK: /* 0 */ OPC_CheckField, 250, 3, 4, 0,
-// CHECK-NEXT: /* 5 */ OPC_Scope, 9, 0, // end scope at 17
-// CHECK-NEXT: /* 8 */ OPC_CheckField, 248, 3, 2, 0,
-// CHECK-NEXT: /* 13 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
-// CHECK-NEXT: /* 17 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
+// CHECK-LABEL: static const uint8_t DecoderTable512[20] = {
+// CHECK-NEXT: OPC_CheckField, 250, 3, 4, 0, // 0: check Inst[509:506] == 0x0
+// CHECK-NEXT: OPC_Scope, 9, // 5: {
+// CHECK-NEXT: OPC_CheckField, 248, 3, 2, 0, // 7: check Inst[505:504] == 0x0
+// CHECK-NEXT: OPC_TryDecode, {{[0-9, ]+}}, 0, // 12: try decode to InstB using decoder 0
+// CHECK-NEXT: // 12: }
+// CHECK-NEXT: OPC_Decode, {{[0-9, ]+}}, 1, // 16: decode to InstA using decoder 1
// CHECK-NEXT: };
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-
-
-// CHECK-LARGE: /* 0 */ OPC_CheckField, 250, 3, 4, 0,
-// CHECK-LARGE-NEXT: /* 5 */ OPC_Scope, 9, 0, 0, // end scope at 18
-// CHECK-LARGE-NEXT: /* 9 */ OPC_CheckField, 248, 3, 2, 0,
-// CHECK-LARGE-NEXT: /* 14 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
-// CHECK-LARGE-NEXT: /* 18 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
-// CHECK-LARGE-NEXT: };
-
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/DecoderEmitter/var-len-conflict-1.td b/llvm/test/TableGen/DecoderEmitter/var-len-conflict-1.td
index b18d28a9f5136..50e2d6d97f721 100644
--- a/llvm/test/TableGen/DecoderEmitter/var-len-conflict-1.td
+++ b/llvm/test/TableGen/DecoderEmitter/var-len-conflict-1.td
@@ -18,19 +18,12 @@ class I : Instruction {
// 00000001 ________ I16_1
// 00000010 ________ I16_2
-// CHECK: /* 0 */ OPC_Scope, 17, 0, // end scope at 20
-// CHECK-NEXT: /* 3 */ OPC_ExtractField, 0, 1, // Field = Inst{0}
-// CHECK-NEXT: /* 6 */ OPC_FilterValueOrSkip, 0, 4, 0, // if Field != 0x0 skip to 14
-// CHECK-NEXT: /* 10 */ OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: I8_0, DecodeIdx: 0
-// CHECK-NEXT: /* 14 */ OPC_FilterValue, 1, // if Field != 0x1
-// CHECK-NEXT: /* 16 */ OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: I8_1, DecodeIdx: 0
-// CHECK-NEXT: /* 20 */ OPC_ExtractField, 8, 8, // Field = Inst{15-8}
-// CHECK-NEXT: /* 23 */ OPC_FilterValueOrSkip, 0, 4, 0, // if Field != 0x0 skip to 31
-// CHECK-NEXT: /* 27 */ OPC_Decode, {{[0-9]+}}, 2, 1, // Opcode: I16_0, DecodeIdx: 1
-// CHECK-NEXT: /* 31 */ OPC_FilterValueOrSkip, 1, 4, 0, // if Field != 0x1 skip to 39
-// CHECK-NEXT: /* 35 */ OPC_Decode, {{[0-9]+}}, 2, 1, // Opcode: I16_1, DecodeIdx: 1
-// CHECK-NEXT: /* 39 */ OPC_FilterValue, 2, // if Field != 0x2
-// CHECK-NEXT: /* 41 */ OPC_Decode, {{[0-9]+}}, 2, 1, // Opcode: I16_2, DecodeIdx: 1
+// CHECK: switch Inst[0:0]
+// CHECK: decode to I8_0
+// CHECK: decode to I8_1
+// CHECK: switch Inst[15:8]
+// CHECK: decode to I16_0
+// CHECK: decode to I16_1
def I8_0 : I { dag Inst = (descend (operand "$op", 7), 0b0); }
def I8_1 : I { dag Inst = (descend (operand "$op", 7), 0b1); }
diff --git a/llvm/test/TableGen/HwModeEncodeDecode.td b/llvm/test/TableGen/HwModeEncodeDecode.td
index 6df5fd46297bf..7badc895d5f50 100644
--- a/llvm/test/TableGen/HwModeEncodeDecode.td
+++ b/llvm/test/TableGen/HwModeEncodeDecode.td
@@ -71,12 +71,12 @@ def baz : Instruction {
}
// DECODER-LABEL: DecoderTable_ModeA32
-// DECODER-DAG: Opcode: fooTypeEncA:foo
-// DECODER-DAG: Opcode: bar
+// DECODER-DAG: decode to fooTypeEncA:foo
+// DECODER-DAG: decode to bar
// DECODER-LABEL: DecoderTable_ModeB32
-// DECODER-DAG: Opcode: fooTypeEncB:foo
-// DECODER-DAG: Opcode: fooTypeEncA:baz
-// DECODER-DAG: Opcode: bar
+// DECODER-DAG: decode to fooTypeEncA:baz
+// DECODER-DAG: decode to bar
+// DECODER-DAG: decode to fooTypeEncB:foo
// ENCODER-LABEL: static const uint64_t InstBits_ModeA[] = {
// ENCODER: UINT64_C(2), // bar
diff --git a/llvm/test/TableGen/HwModeEncodeDecode2.td b/llvm/test/TableGen/HwModeEncodeDecode2.td
index 6431a9bd69a55..e1a5ccffec722 100644
--- a/llvm/test/TableGen/HwModeEncodeDecode2.td
+++ b/llvm/test/TableGen/HwModeEncodeDecode2.td
@@ -94,25 +94,25 @@ let OutOperandList = (outs) in {
}
// DECODER-LABEL: DecoderTable_ModeA32
-// DECODER-DAG: Opcode: fooTypeEncA:foo
-// DECODER-DAG: Opcode: bar
+// DECODER-DAG: decode to fooTypeEncA:foo
+// DECODER-DAG: decode to bar
// DECODER-LABEL: DecoderTable_ModeB32
-// DECODER-DAG: Opcode: fooTypeEncB:foo
-// DECODER-DAG: Opcode: fooTypeEncA:baz
-// DECODER-DAG: Opcode: bar
+// DECODER-DAG: decode to fooTypeEncB:foo
+// DECODER-DAG: decode to fooTypeEncA:baz
+// DECODER-DAG: decode to bar
// DECODER-LABEL: DecoderTableAlt_ModeA32
-// DECODER-DAG: Opcode: unrelated
+// DECODER-DAG: decode to unrelated
// DECODER-LABEL: DecoderTableAlt_ModeB32
-// DECODER-DAG: Opcode: unrelated
+// DECODER-DAG: decode to unrelated
// DECODER-SUPPRESS-LABEL: DecoderTable32
-// DECODER-SUPPRESS-DAG: Opcode: bar
+// DECODER-SUPPRESS-DAG: decode to bar
// DECODER-SUPPRESS-LABEL: DecoderTable_ModeA32
-// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncA:foo
-// DECODER-SUPPRESS-NOT: Opcode: bar
+// DECODER-SUPPRESS-DAG: decode to fooTypeEncA:foo
+// DECODER-SUPPRESS-NOT: decode to bar
// DECODER-SUPPRESS-LABEL: DecoderTable_ModeB32
-// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncB:foo
-// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncA:baz
-// DECODER-SUPPRESS-NOT: Opcode: bar
+// DECODER-SUPPRESS-DAG: decode to fooTypeEncB:foo
+// DECODER-SUPPRESS-DAG: decode to fooTypeEncA:baz
+// DECODER-SUPPRESS-NOT: decode to bar
// DECODER-SUPPRESS-LABEL: DecoderTableAlt32
-// DECODER-SUPPRESS-DAG: Opcode: unrelated
+// DECODER-SUPPRESS-DAG: decode to unrelated
diff --git a/llvm/test/TableGen/HwModeEncodeDecode3.td b/llvm/test/TableGen/HwModeEncodeDecode3.td
index 3893216f70e01..36c65214d2719 100644
--- a/llvm/test/TableGen/HwModeEncodeDecode3.td
+++ b/llvm/test/TableGen/HwModeEncodeDecode3.td
@@ -117,46 +117,46 @@ def unrelated: Instruction {
// ‘DecoderTableAlt_ModeA32’, ‘DecoderTableAlt_ModeB32’ and 'DecoderTable_ModeC32' are
// exact duplicates and could effectively be merged into one.
// DECODER-LABEL: DecoderTable32
-// DECODER-DAG: Opcode: bar
+// DECODER-DAG: decode to bar
// DECODER-LABEL: DecoderTable_ModeA32
-// DECODER-DAG: Opcode: fooTypeEncA:foo
-// DECODER-DAG: Opcode: bar
+// DECODER-DAG: decode to fooTypeEncA:foo
+// DECODER-DAG: decode to bar
// DECODER-LABEL: DecoderTable_ModeB32
-// DECODER-DAG: Opcode: fooTypeEncB:foo
-// DECODER-DAG: Opcode: fooTypeEncA:baz
-// DECODER-DAG: Opcode: bar
+// DECODER-DAG: decode to fooTypeEncB:foo
+// DECODER-DAG: decode to fooTypeEncA:baz
+// DECODER-DAG: decode to bar
// DECODER-LABEL: DecoderTable_ModeC32
-// DECODER-DAG: Opcode: fooTypeEncC:foo
-// DECODER-DAG: Opcode: bar
+// DECODER-DAG: decode to fooTypeEncC:foo
+// DECODER-DAG: decode to bar
// DECODER-LABEL: DecoderTableAlt32
-// DECODER-DAG: Opcode: unrelated
+// DECODER-DAG: decode to unrelated
// DECODER-LABEL: DecoderTableAlt_ModeA32
-// DECODER-DAG: Opcode: unrelated
+// DECODER-DAG: decode to unrelated
// DECODER-LABEL: DecoderTableAlt_ModeB32
-// DECODER-DAG: Opcode: unrelated
+// DECODER-DAG: decode to unrelated
// DECODER-LABEL: DecoderTableAlt_ModeC32
-// DECODER-DAG: Opcode: unrelated
+// DECODER-DAG: decode to unrelated
// DECODER-LABEL: DecoderTable64
-// DECODER-DAG: Opcode: fooTypeEncDefault:foo
+// DECODER-DAG: decode to fooTypeEncDefault:foo
// Under the 'O1' optimization level, unnecessary duplicate tables will be eliminated,
// reducing the four ‘Alt’ tables down to just one.
// DECODER-SUPPRESS-O1-LABEL: DecoderTable32
-// DECODER-SUPPRESS-O1-DAG: Opcode: bar
+// DECODER-SUPPRESS-O1-DAG: decode to bar
// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeA32
-// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncA:foo
-// DECODER-SUPPRESS-O1-DAG: Opcode: bar
+// DECODER-SUPPRESS-O1-DAG: decode to fooTypeEncA:foo
+// DECODER-SUPPRESS-O1-DAG: decode to bar
// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeB32
-// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncB:foo
-// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncA:baz
-// DECODER-SUPPRESS-O1-DAG: Opcode: bar
+// DECODER-SUPPRESS-O1-DAG: decode to fooTypeEncB:foo
+// DECODER-SUPPRESS-O1-DAG: decode to fooTypeEncA:baz
+// DECODER-SUPPRESS-O1-DAG: decode to bar
// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeC32
-// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncC:foo
-// DECODER-SUPPRESS-O1-DAG: Opcode: bar
+// DECODER-SUPPRESS-O1-DAG: decode to fooTypeEncC:foo
+// DECODER-SUPPRESS-O1-DAG: decode to bar
// DECODER-SUPPRESS-O1-LABEL: DecoderTableAlt32
-// DECODER-SUPPRESS-O1-DAG: Opcode: unrelated
+// DECODER-SUPPRESS-O1-DAG: decode to unrelated
// DECODER-SUPPRESS-O1-LABEL: DecoderTable64
-// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncDefault:foo
+// DECODER-SUPPRESS-O1-DAG: decode to fooTypeEncDefault:foo
// Under the 'O2' optimization condition, instructions possessing the 'EncodingByHwMode'
// attribute will be extracted from their original DecoderNamespace and placed into their
@@ -165,22 +165,22 @@ def unrelated: Instruction {
// approach will significantly reduce instruction redundancy, but it necessitates users to thoroughly
// consider the interplay between HwMode and DecoderNamespace for their instructions.
// DECODER-SUPPRESS-O2-LABEL: DecoderTable32
-// DECODER-SUPPRESS-O2-DAG: Opcode: bar
+// DECODER-SUPPRESS-O2-DAG: decode to bar
// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeA32
-// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncA:foo
-// DECODER-SUPPRESS-O2-NOT: Opcode: bar
+// DECODER-SUPPRESS-O2-DAG: decode to fooTypeEncA:foo
+// DECODER-SUPPRESS-O2-NOT: decode to bar
// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeB32
-// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncB:foo
-// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncA:baz
-// DECODER-SUPPRESS-O2-NOT: Opcode: bar
+// DECODER-SUPPRESS-O2-DAG: decode to fooTypeEncB:foo
+// DECODER-SUPPRESS-O2-DAG: decode to fooTypeEncA:baz
+// DECODER-SUPPRESS-O2-NOT: decode to bar
// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeC32
-// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncC:foo
-// DECODER-SUPPRESS-O2-NOT: Opcode: bar
+// DECODER-SUPPRESS-O2-DAG: decode to fooTypeEncC:foo
+// DECODER-SUPPRESS-O2-NOT: decode to bar
// DECODER-SUPPRESS-O2-LABEL: DecoderTableAlt32
-// DECODER-SUPPRESS-O2-DAG: Opcode: unrelated
+// DECODER-SUPPRESS-O2-DAG: decode to unrelated
// DECODER-SUPPRESS-O2-LABEL: DecoderTable64
-// DECODER-SUPPRESS-O2-NOT: Opcode: bar
-// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncDefault:foo
+// DECODER-SUPPRESS-O2-NOT: decode to bar
+// DECODER-SUPPRESS-O2-DAG: decode to fooTypeEncDefault:foo
// For 'bar' and 'unrelated', we didn't assign any HwModes for them,
// they should keep the same in the following four tables.
>From eb59743e2b5f151573fcd6bef9ef88179dc1976e Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 16 Sep 2025 20:59:59 +0300
Subject: [PATCH 3/3] Remove MCDecoderOps.h
---
llvm/include/llvm/MC/MCDecoder.h | 12 ++++++++
llvm/include/llvm/MC/MCDecoderOps.h | 29 -------------------
.../Disassembler/AArch64Disassembler.cpp | 1 -
.../Disassembler/AMDGPUDisassembler.cpp | 1 -
.../ARC/Disassembler/ARCDisassembler.cpp | 1 -
.../ARM/Disassembler/ARMDisassembler.cpp | 1 -
.../AVR/Disassembler/AVRDisassembler.cpp | 1 -
.../BPF/Disassembler/BPFDisassembler.cpp | 1 -
.../CSKY/Disassembler/CSKYDisassembler.cpp | 1 -
.../Disassembler/HexagonDisassembler.cpp | 1 -
.../Lanai/Disassembler/LanaiDisassembler.cpp | 1 -
.../Disassembler/LoongArchDisassembler.cpp | 1 -
.../M68k/Disassembler/M68kDisassembler.cpp | 1 -
.../Disassembler/MSP430Disassembler.cpp | 1 -
.../Mips/Disassembler/MipsDisassembler.cpp | 1 -
.../PowerPC/Disassembler/PPCDisassembler.cpp | 1 -
.../RISCV/Disassembler/RISCVDisassembler.cpp | 1 -
.../Sparc/Disassembler/SparcDisassembler.cpp | 1 -
.../Disassembler/SystemZDisassembler.cpp | 1 -
.../Target/VE/Disassembler/VEDisassembler.cpp | 1 -
.../XCore/Disassembler/XCoreDisassembler.cpp | 1 -
.../Disassembler/XtensaDisassembler.cpp | 1 -
22 files changed, 12 insertions(+), 49 deletions(-)
delete mode 100644 llvm/include/llvm/MC/MCDecoderOps.h
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h
index 87df6c10d8bb2..dfa2ec33eefaf 100644
--- a/llvm/include/llvm/MC/MCDecoder.h
+++ b/llvm/include/llvm/MC/MCDecoder.h
@@ -17,6 +17,18 @@
namespace llvm::MCD {
+/// Disassembler state machine opcodes.
+enum DecoderOps {
+ OPC_Scope = 1, // OPC_Scope(uleb128 Size)
+ OPC_SwitchField, // OPC_SwitchField(uleb128 Start, uint8_t Len,
+ // [uleb128 Val, uleb128 Size]...)
+ OPC_CheckField, // OPC_CheckField(uleb128 Start, uint8_t Len, uleb128 Val)
+ OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx)
+ OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
+ OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx)
+ OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
+};
+
// 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
diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h
deleted file mode 100644
index 4e06deb0eacee..0000000000000
--- a/llvm/include/llvm/MC/MCDecoderOps.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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 ops.
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCDECODEROPS_H
-#define LLVM_MC_MCDECODEROPS_H
-
-namespace llvm::MCD {
-
-// Disassembler state machine opcodes.
-enum DecoderOps {
- OPC_Scope = 1, // OPC_Scope(uleb128 Size)
- OPC_SwitchField, // OPC_SwitchField(uleb128 Start, uint8_t Len,
- // [uleb128 Val, uleb128 Size]...)
- OPC_CheckField, // OPC_CheckField(uleb128 Start, uint8_t Len, uleb128 Val)
- OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx)
- OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
- OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx)
- OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
-};
-
-} // namespace llvm::MCD
-
-#endif
diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index aa1c1c882e225..c60c156345cb2 100644
--- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -16,7 +16,6 @@
#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"
#include "llvm/MC/MCInstrDesc.h"
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index d3db1b7394675..af5e8164c3798 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -28,7 +28,6 @@
#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"
#include "llvm/MC/MCRegisterInfo.h"
diff --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp
index f28c7d8fe92a5..6ccf6b09519ea 100644
--- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp
+++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp
@@ -17,7 +17,6 @@
#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"
#include "llvm/MC/MCInstrInfo.h"
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 1d19bc89ccf92..5c8581176cf95 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -14,7 +14,6 @@
#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"
#include "llvm/MC/MCInstrDesc.h"
diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
index 3a840a3714975..06b8ecfe64688 100644
--- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
+++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
@@ -19,7 +19,6 @@
#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"
#include "llvm/MC/TargetRegistry.h"
diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
index 813dddad7d75f..58da46fb63eeb 100644
--- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
+++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
@@ -16,7 +16,6 @@
#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"
#include "llvm/MC/TargetRegistry.h"
diff --git a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp
index 39e651d52e4d3..263847bc3c5f5 100644
--- a/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp
+++ b/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp
@@ -16,7 +16,6 @@
#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"
#include "llvm/MC/MCInstrInfo.h"
diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
index 974f6533411e0..a4859235fbd1e 100644
--- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
+++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
@@ -14,7 +14,6 @@
#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"
#include "llvm/MC/MCInst.h"
diff --git a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp
index 96feaf28d0a0f..99c979dd3bcbe 100644
--- a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp
+++ b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp
@@ -17,7 +17,6 @@
#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"
#include "llvm/MC/TargetRegistry.h"
diff --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp
index d4058fac4304a..e1ec5b30a4b4f 100644
--- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp
+++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp
@@ -14,7 +14,6 @@
#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"
#include "llvm/MC/MCInstrInfo.h"
diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp
index 4992f1abe5a00..2e2d21edd5cb5 100644
--- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp
+++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp
@@ -20,7 +20,6 @@
#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"
#include "llvm/MC/TargetRegistry.h"
diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
index e6666e8cafdf9..170f1d2112483 100644
--- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
+++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
@@ -15,7 +15,6 @@
#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"
#include "llvm/MC/MCSubtargetInfo.h"
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index c22b8f61b12dc..acffaa223007c 100644
--- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -15,7 +15,6 @@
#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"
#include "llvm/MC/MCRegisterInfo.h"
diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
index 47586c417cfe3..b3d84ff68bc8c 100644
--- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
+++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
@@ -9,7 +9,6 @@
#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"
#include "llvm/MC/MCSubtargetInfo.h"
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index ff07122b61378..9ef9c0bf285a9 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -15,7 +15,6 @@
#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"
#include "llvm/MC/MCInstrInfo.h"
diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
index c3d60f3689e1f..c4ba46c74a873 100644
--- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
@@ -15,7 +15,6 @@
#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"
#include "llvm/MC/TargetRegistry.h"
diff --git a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp
index a724c5a7f97c8..08dc6de7e300a 100644
--- a/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp
+++ b/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp
@@ -9,7 +9,6 @@
#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"
#include "llvm/MC/MCSubtargetInfo.h"
diff --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp
index aad826b5f285f..ae02be1c726b1 100644
--- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp
+++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp
@@ -16,7 +16,6 @@
#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"
#include "llvm/MC/TargetRegistry.h"
diff --git a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
index 096ad08d8a3c9..9ddac3eecf9f3 100644
--- a/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
+++ b/llvm/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
@@ -16,7 +16,6 @@
#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"
#include "llvm/MC/MCSubtargetInfo.h"
diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index 7d22a0489a951..31ca43cf41383 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -16,7 +16,6 @@
#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"
#include "llvm/MC/MCRegisterInfo.h"
More information about the llvm-commits
mailing list