diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 109b955db6d79..0634fac72bd18 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -219,11 +219,12 @@ using NamespacesHwModesMap = std::map>; class DecoderEmitter { const RecordKeeper &RK; + CodeGenTarget Target; + const CodeGenHwModes &CGH; std::vector Encodings; public: - DecoderEmitter(const RecordKeeper &R, StringRef PredicateNamespace) - : RK(R), Target(R), PredicateNamespace(PredicateNamespace) {} + DecoderEmitter(const RecordKeeper &RK, StringRef PredicateNamespace); const CodeGenTarget &getTarget() const { return Target; } @@ -240,10 +241,19 @@ class DecoderEmitter { DecoderSet &Decoders) const; // run - Output the code emitter - void run(raw_ostream &o); + void run(raw_ostream &o) const; private: - CodeGenTarget Target; + void collectHwModesReferencedForEncodings( + std::vector &HwModeIDs, + NamespacesHwModesMap &NamespacesWithHwModes) const; + + void + handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr, + ArrayRef HwModeIDs, + NamespacesHwModesMap &NamespacesWithHwModes); + + void parseInstructionEncodings(); public: StringRef PredicateNamespace; @@ -2393,12 +2403,12 @@ static bool Check(DecodeStatus &Out, DecodeStatus In) { )"; } -// Collect all HwModes referenced by the target for encoding purposes. -static void collectHwModesReferencedForEncodings( - const CodeGenHwModes &HWM, std::vector &HwModeIDs, - NamespacesHwModesMap &NamespacesWithHwModes) { - SmallBitVector BV(HWM.getNumModeIds()); - for (const auto &MS : HWM.getHwModeSelects()) { +/// Collects all HwModes referenced by the target for encoding purposes. +void DecoderEmitter::collectHwModesReferencedForEncodings( + std::vector &HwModeIDs, + NamespacesHwModesMap &NamespacesWithHwModes) const { + SmallBitVector BV(CGH.getNumModeIds()); + for (const auto &MS : CGH.getHwModeSelects()) { for (auto [HwModeID, EncodingDef] : MS.second.Items) { if (EncodingDef->isSubClassOf("InstructionEncoding")) { std::string DecoderNamespace = @@ -2414,17 +2424,15 @@ static void collectHwModesReferencedForEncodings( llvm::copy(BV.set_bits(), std::back_inserter(HwModeIDs)); } -static void -handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr, - ArrayRef HwModeIDs, - NamespacesHwModesMap &NamespacesWithHwModes, - std::vector &GlobalEncodings) { +void DecoderEmitter::handleHwModesUnrelatedEncodings( + const CodeGenInstruction *Instr, ArrayRef HwModeIDs, + NamespacesHwModesMap &NamespacesWithHwModes) { const Record *InstDef = Instr->TheDef; switch (DecoderEmitterSuppressDuplicates) { case SUPPRESSION_DISABLE: { for (unsigned HwModeID : HwModeIDs) - GlobalEncodings.emplace_back(InstDef, Instr, HwModeID); + Encodings.emplace_back(InstDef, Instr, HwModeID); break; } case SUPPRESSION_LEVEL1: { @@ -2433,51 +2441,28 @@ handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr, auto It = NamespacesWithHwModes.find(DecoderNamespace); if (It != NamespacesWithHwModes.end()) { for (unsigned HwModeID : It->second) - GlobalEncodings.emplace_back(InstDef, Instr, HwModeID); + Encodings.emplace_back(InstDef, Instr, HwModeID); } else { // Only emit the encoding once, as it's DecoderNamespace doesn't // contain any HwModes. - GlobalEncodings.emplace_back(InstDef, Instr, DefaultMode); + Encodings.emplace_back(InstDef, Instr, DefaultMode); } break; } case SUPPRESSION_LEVEL2: - GlobalEncodings.emplace_back(InstDef, Instr, DefaultMode); + Encodings.emplace_back(InstDef, Instr, DefaultMode); break; } } -// Emits disassembler code for instruction decoding. -void DecoderEmitter::run(raw_ostream &o) { - formatted_raw_ostream OS(o); - OS << R"( -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Support/DataTypes.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/LEB128.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/TargetParser/SubtargetFeature.h" -#include - -namespace { -)"; - - emitFieldFromInstruction(OS); - emitInsertBits(OS); - emitCheck(OS); - - Target.reverseBitsForLittleEndianEncoding(); - - // Parameterize the decoders based on namespace and instruction width. - +/// Parses all InstructionEncoding instances and fills internal data structures. +void DecoderEmitter::parseInstructionEncodings() { // First, collect all encoding-related HwModes referenced by the target. // And establish a mapping table between DecoderNamespace and HwMode. // If HwModeNames is empty, add the default mode so we always have one HwMode. - const CodeGenHwModes &HWM = Target.getHwModes(); std::vector HwModeIDs; NamespacesHwModesMap NamespacesWithHwModes; - collectHwModesReferencedForEncodings(HWM, HwModeIDs, NamespacesWithHwModes); + collectHwModesReferencedForEncodings(HwModeIDs, NamespacesWithHwModes); if (HwModeIDs.empty()) HwModeIDs.push_back(DefaultMode); @@ -2488,15 +2473,14 @@ namespace { for (const CodeGenInstruction *Inst : Instructions) { const Record *InstDef = Inst->TheDef; if (const Record *RV = InstDef->getValueAsOptionalDef("EncodingInfos")) { - EncodingInfoByHwMode EBM(RV, HWM); + EncodingInfoByHwMode EBM(RV, CGH); for (auto [HwModeID, EncodingDef] : EBM) Encodings.emplace_back(EncodingDef, Inst, HwModeID); continue; } // This instruction is encoded the same on all HwModes. // According to user needs, provide varying degrees of suppression. - handleHwModesUnrelatedEncodings(Inst, HwModeIDs, NamespacesWithHwModes, - Encodings); + handleHwModesUnrelatedEncodings(Inst, HwModeIDs, NamespacesWithHwModes); } for (const Record *EncodingDef : @@ -2504,6 +2488,35 @@ namespace { const Record *InstDef = EncodingDef->getValueAsDef("AliasOf"); Encodings.emplace_back(EncodingDef, &Target.getInstruction(InstDef)); } +} + +DecoderEmitter::DecoderEmitter(const RecordKeeper &RK, + StringRef PredicateNamespace) + : RK(RK), Target(RK), CGH(Target.getHwModes()), + PredicateNamespace(PredicateNamespace) { + Target.reverseBitsForLittleEndianEncoding(); + parseInstructionEncodings(); +} + +// Emits disassembler code for instruction decoding. +void DecoderEmitter::run(raw_ostream &o) const { + formatted_raw_ostream OS(o); + OS << R"( +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/LEB128.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/SubtargetFeature.h" +#include + +namespace { +)"; + + emitFieldFromInstruction(OS); + emitInsertBits(OS); + emitCheck(OS); // Map of (namespace, hwmode, size) tuple to encoding IDs. std::map, std::vector> @@ -2512,7 +2525,7 @@ namespace { std::vector InstrLen; bool IsVarLenInst = Target.hasVariableLengthEncodings(); if (IsVarLenInst) - InstrLen.resize(Instructions.size(), 0); + InstrLen.resize(Target.getInstructions().size(), 0); unsigned MaxInstLen = 0; for (const auto &[EncodingID, Encoding] : enumerate(Encodings)) {