diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 95146a1e6c313..9aa7d31c62693 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -226,6 +226,9 @@ struct DecoderTableInfo { DecoderTable Table; PredicateSet Predicates; DecoderSet Decoders; + bool HasCheckPredicate; + bool HasSoftFail; + bool HasTryDecode; void insertPredicate(StringRef Predicate) { Predicates.insert(CachedHashString(Predicate)); @@ -266,11 +269,10 @@ class DecoderEmitter { const CodeGenTarget &getTarget() const { return Target; } - // Emit the decoder state machine table. Returns a mask of MCD decoder ops - // that were emitted. - unsigned emitTable(formatted_raw_ostream &OS, DecoderTable &Table, - StringRef Namespace, unsigned HwModeID, unsigned BitWidth, - ArrayRef EncodingIDs) const; + // Emit the decoder state machine table. + void emitTable(formatted_raw_ostream &OS, DecoderTableInfo &TableInfo, + StringRef Namespace, unsigned HwModeID, unsigned BitWidth, + ArrayRef EncodingIDs) const; void emitInstrLenTable(formatted_raw_ostream &OS, ArrayRef InstrLen) const; void emitPredicateFunction(formatted_raw_ostream &OS, @@ -629,12 +631,11 @@ static StringRef getDecoderOpName(DecoderOps Op) { llvm_unreachable("Unknown decoder op"); } -// Emit the decoder state machine table. Returns a mask of MCD decoder ops -// that were emitted. -unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS, - DecoderTable &Table, StringRef Namespace, - unsigned HwModeID, unsigned BitWidth, - ArrayRef EncodingIDs) const { +// Emit the decoder state machine table. +void DecoderEmitter::emitTable(formatted_raw_ostream &OS, + DecoderTableInfo &TableInfo, StringRef Namespace, + unsigned HwModeID, unsigned BitWidth, + ArrayRef 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. @@ -648,7 +649,7 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS, OS << "static const uint8_t DecoderTable" << Namespace; if (HwModeID != DefaultMode) OS << '_' << Target.getHwModes().getModeName(HwModeID); - OS << BitWidth << "[" << Table.size() << "] = {\n"; + OS << BitWidth << "[" << TableInfo.Table.size() << "] = {\n"; // Emit ULEB128 encoded value to OS, returning the number of bytes emitted. auto EmitULEB128 = [](DecoderTable::const_iterator &I, @@ -678,6 +679,7 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS, // 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(); @@ -719,15 +721,12 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS, return Value; }; - unsigned OpcodeMask = 0; - while (I != E) { assert(I < E && "incomplete decode table entry!"); uint32_t Pos = I - Table.begin(); EmitPos(Pos); const uint8_t DecoderOp = *I++; - OpcodeMask |= (1 << DecoderOp); OS << getDecoderOpName(static_cast(DecoderOp)) << ", "; switch (DecoderOp) { default: @@ -826,8 +825,6 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS, OS << '\n'; } OS << "};\n\n"; - - return OpcodeMask; } void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS, @@ -1114,6 +1111,7 @@ void DecoderTableBuilder::emitPredicateTableEntry(unsigned EncodingID) const { TableInfo.Table.insertOpcode(OPC_CheckPredicate); TableInfo.Table.insertULEB128(PredicateIndex); + TableInfo.HasCheckPredicate = true; } void DecoderTableBuilder::emitSoftFailTableEntry(unsigned EncodingID) const { @@ -1130,6 +1128,7 @@ void DecoderTableBuilder::emitSoftFailTableEntry(unsigned EncodingID) const { 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. @@ -1180,6 +1179,7 @@ void DecoderTableBuilder::emitSingletonTableEntry( 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 @@ -1523,11 +1523,7 @@ void DecoderTableBuilder::emitTableEntries(const FilterChooser &FC) const { // emitDecodeInstruction - Emit the templated helper function // decodeInstruction(). static void emitDecodeInstruction(formatted_raw_ostream &OS, bool IsVarLenInst, - unsigned OpcodeMask) { - const bool HasTryDecode = OpcodeMask & (1 << OPC_TryDecode); - const bool HasCheckPredicate = OpcodeMask & (1 << OPC_CheckPredicate); - const bool HasSoftFail = OpcodeMask & (1 << OPC_SoftFail); - + const DecoderTableInfo &TableInfo) { OS << R"( static unsigned decodeNumToSkip(const uint8_t *&Ptr) { unsigned NumToSkip = *Ptr++; @@ -1548,7 +1544,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI, "llvm::function_ref makeUp"; } OS << ") {\n"; - if (HasCheckPredicate) + if (TableInfo.HasCheckPredicate) OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n"; OS << " const uint8_t *Ptr = DecodeTable;\n"; @@ -1657,7 +1653,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI, } break; })"; - if (HasCheckPredicate) { + if (TableInfo.HasCheckPredicate) { OS << R"( case OPC_CheckPredicate: { // Decode the Predicate Index value. @@ -1701,7 +1697,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI, << (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n")); return S; })"; - if (HasTryDecode) { + if (TableInfo.HasTryDecode) { OS << R"( case OPC_TryDecode: { // Decode the Opcode value. @@ -1735,7 +1731,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI, break; })"; } - if (HasSoftFail) { + if (TableInfo.HasSoftFail) { OS << R"( case OPC_SoftFail: { // Decode the mask values. @@ -1994,9 +1990,8 @@ template 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; + DecoderTableInfo TableInfo{}; DecoderTableBuilder TableBuilder(Target, Encodings, TableInfo); - unsigned OpcodeMask = 0; bool HasConflict = false; for (const auto &[BitWidth, BWMap] : EncMap) { @@ -2021,8 +2016,8 @@ template constexpr uint32_t InsnBitWidth = 0; TableBuilder.buildTable(FC, BitWidth); // Print the table to the output stream. - OpcodeMask |= emitTable(OS, TableInfo.Table, DecoderNamespace, HwModeID, - BitWidth, EncodingIDs); + emitTable(OS, TableInfo, DecoderNamespace, HwModeID, BitWidth, + EncodingIDs); } // Each BitWidth get's its own decoders and decoder function if @@ -2041,14 +2036,12 @@ template constexpr uint32_t InsnBitWidth = 0; if (!SpecializeDecodersPerBitwidth) emitDecoderFunction(OS, TableInfo.Decoders, 0); - const bool HasCheckPredicate = OpcodeMask & (1 << OPC_CheckPredicate); - // Emit the predicate function. - if (HasCheckPredicate) + if (TableInfo.HasCheckPredicate) emitPredicateFunction(OS, TableInfo.Predicates); // Emit the main entry point for the decoder, decodeInstruction(). - emitDecodeInstruction(OS, IsVarLenInst, OpcodeMask); + emitDecodeInstruction(OS, IsVarLenInst, TableInfo); OS << "\n} // namespace\n"; }