[llvm] [TableGen][DecoderEmitter] Add option to emit type-specialized code (PR #146593)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 17 04:41:40 PDT 2025
================
@@ -2630,57 +2789,121 @@ namespace {
}
}
+ bool GenerateTemplated =
+ Target.getInstructionSet()->getValueAsBit("GenerateTemplatedDecoder");
+
+ // For variable instruction, we emit a instruction length table to let the
+ // decoder know how long the instructions are. You can see example usage in
+ // M68k's disassembler.
+ if (IsVarLenInst) {
+ if (GenerateTemplated)
+ PrintFatalError(
+ "Templated decoder not needed for variable length instruction");
+ emitInstrLenTable(OS, InstrLen);
+ }
+
DecoderTableInfo TableInfo;
- unsigned OpcodeMask = 0;
- for (const auto &[NSAndByteSize, EncodingIDs] : OpcMap) {
- const std::string &DecoderNamespace = NSAndByteSize.first;
- const unsigned BitWidth = 8 * NSAndByteSize.second;
- // Emit the decoder for this namespace+width combination.
- FilterChooser FC(NumberedEncodings, EncodingIDs, Operands,
- IsVarLenInst ? MaxInstLen : BitWidth, this);
-
- // The decode table is cleared for each top level decoder function. The
- // predicates and decoders themselves, however, are shared across all
- // decoders to give more opportunities for uniqueing.
- TableInfo.Table.clear();
- TableInfo.FixupStack.clear();
- TableInfo.FixupStack.emplace_back();
- FC.emitTableEntries(TableInfo);
- // Any NumToSkip fixups in the top level scope can resolve to the
- // OPC_Fail at the end of the table.
- assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!");
- // Resolve any NumToSkip fixups in the current scope.
- resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
- TableInfo.Table.size());
- TableInfo.FixupStack.clear();
+ bool HasCheckPredicate = false;
+
+ // Helper lambda to emit the decoder code for a given instruction Bitwidth
+ // and associated C++ type. If `Bitwidth` is 0 (and CPPType is empty) it will
+ // generate templated decoder code.
+ auto emitDecoder = [&](const CPPType &Type, StringRef Suffix) {
+ // Reset the Decoders for each non-templated type.
+ TableInfo.Decoders.clear();
+ unsigned OpcodeMask = 0;
+
+ const bool IsTemplate = Type.Kind == CPPType::TemplateTy;
+ if (!IsTemplate) {
+ OS << "// ------------------------------------------------------------\n";
+ OS << "// Decoder tables for " << Type.Bitwidth << "-bit instructions.\n";
+ OS << "// Using C++ type `" << Type.getName() << "` for payload.\n\n";
+ }
- TableInfo.Table.push_back(MCD::OPC_Fail);
+ for (const auto &[NSAndByteSize, EncodingIDs] : OpcMap) {
+ const std::string &DecoderNamespace = NSAndByteSize.first;
+ const unsigned InstrBitwidth =
+ IsVarLenInst ? MaxInstLen : 8 * NSAndByteSize.second;
- // Print the table to the output stream.
- OpcodeMask |= emitTable(OS, TableInfo.Table, FC.getBitWidth(),
- DecoderNamespace, EncodingIDs);
- }
+ if (!IsTemplate && InstrBitwidth != Type.Bitwidth)
+ continue;
- // For variable instruction, we emit a instruction length table
- // to let the decoder know how long the instructions are.
- // You can see example usage in M68k's disassembler.
- if (IsVarLenInst)
- emitInstrLenTable(OS, InstrLen);
+ // Emit the decoder table for this namespace+ bitwidth combination.
+ FilterChooser FC(NumberedEncodings, EncodingIDs, Operands,
+ IsVarLenInst ? MaxInstLen : InstrBitwidth, this);
+
+ // FIXME: Update this comment.
----------------
s-barannikov wrote:
Can it be updated now?
https://github.com/llvm/llvm-project/pull/146593
More information about the llvm-commits
mailing list