[llvm] [LLVM][MC][DecoderEmitter] Encode BitWidth at the start of the table (PR #156734)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 3 11:57:58 PDT 2025
https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/156734
Testing if the llvm_unreachable ever fires.
>From 759c69f5bcabf1e48ec6a7c093d45acfee90daf4 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Wed, 3 Sep 2025 11:56:11 -0700
Subject: [PATCH] [LLVM][MC][DecoderEmitter] Encode BitWidth at the start of
the table
---
llvm/utils/TableGen/DecoderEmitter.cpp | 33 +++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index fcaf433918092..a364df96be2c6 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -611,7 +611,12 @@ class DecoderTableBuilder {
DecoderTableInfo &TableInfo)
: Target(Target), Encodings(Encodings), TableInfo(TableInfo) {}
- void buildTable(const FilterChooser &FC) const {
+ void buildTable(const FilterChooser &FC, unsigned BitWidth) const {
+ // When specializing decoders per bit width, each decoder table will begin
+ // with a the bitwidth for that table. This will be used to early out from
+ // the generated `decodeInstruction`.
+ if (SpecializeDecodersPerBitwidth)
+ TableInfo.Table.insertULEB128(BitWidth);
emitTableEntries(FC);
assert(TableInfo.FixupStack.empty() && "Fixup stack phasing error!");
}
@@ -774,6 +779,15 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
OS << "Skip to: " << Index;
};
+ // The first entry when specializing decoders per bitwidth will be the
+ // bitwidth. This will be used for early return in `decodeInstruction`.
+ if (SpecializeDecodersPerBitwidth) {
+ OS << "/* 0 */";
+ OS.PadToColumn(14);
+ emitULEB128(I, OS);
+ OS << " // Bitwidth " << BitWidth << '\n';
+ }
+
unsigned OpcodeMask = 0;
while (I != E) {
@@ -2108,9 +2122,22 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
if (HasCheckPredicate)
OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n";
OS << " using namespace llvm::MCD;\n";
+ OS << " const uint8_t *Ptr = DecodeTable;\n";
+
+ if (SpecializeDecodersPerBitwidth) {
+ // Insert early out checks if the decoder table's bitwidth does not match
+ // `InsnType`'s bitwidth.
+ // Decode the ULEB128 bitwidth stored at the start of the decoder table.
+ OS << " uint32_t BitWidth = decodeULEB128AndIncUnsafe(Ptr);\n";
+ OS << " if (InsnBitWidth<InsnType> != BitWidth) {\n";
+ OS << " dbgs() << \"Mismatch size: Table bitwidth = \" << BitWidth << "
+ "\", InsnBitWidth = \" << InsnBitWidth<InsnType> << \"\\n\";\n";
+ OS << " llvm_unreachable(\"Bitwidth mismatch\");\n";
+ OS << " return MCDisassembler::Fail;\n";
+ OS << " }\n";
+ }
OS << R"(
- const uint8_t *Ptr = DecodeTable;
uint64_t CurFieldValue = 0;
DecodeStatus S = MCDisassembler::Success;
while (true) {
@@ -2554,7 +2581,7 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
// across all decoder tables.
// - predicates are shared across all decoder tables.
TableInfo.Table.clear();
- TableBuilder.buildTable(FC);
+ TableBuilder.buildTable(FC, BitWidth);
// Print the table to the output stream.
OpcodeMask |= emitTable(OS, TableInfo.Table, DecoderNamespace, HwModeID,
More information about the llvm-commits
mailing list