Skip to content

Conversation

@jurahul
Copy link
Contributor

@jurahul jurahul commented Jun 5, 2025

Print DecodeIdx associated with Decode MCD ops in the generated decoder tables. This can help in debugging decode failures by first mapping the Op -> DecodeIdx and then inspecting the code in decodeToMCInst associated with that DecodeIdx.

@jurahul jurahul force-pushed the print_decode_idx branch from 17e1470 to 33a90f7 Compare June 5, 2025 15:04
Print DecodeIdx associated with Decode MCD ops in the generated
decoder tables. This can help in debugging decode failures by
first mapping the Op -> DecodeIdx and then inspecting the code
in `decodeToMCInst` associated with that DecodeIdx.
@jurahul jurahul force-pushed the print_decode_idx branch from 33a90f7 to 343ee28 Compare June 5, 2025 21:24
@jurahul jurahul marked this pull request as ready for review June 6, 2025 00:54
@jurahul jurahul requested review from s-barannikov and topperc June 6, 2025 00:54
@llvmbot
Copy link
Member

llvmbot commented Jun 6, 2025

@llvm/pr-subscribers-tablegen

Author: Rahul Joshi (jurahul)

Changes

Print DecodeIdx associated with Decode MCD ops in the generated decoder tables. This can help in debugging decode failures by first mapping the Op -> DecodeIdx and then inspecting the code in decodeToMCInst associated with that DecodeIdx.


Full diff: https://github.com/llvm/llvm-project/pull/142963.diff

5 Files Affected:

  • (modified) llvm/test/TableGen/trydecode-emission.td (+4-4)
  • (modified) llvm/test/TableGen/trydecode-emission2.td (+2-2)
  • (modified) llvm/test/TableGen/trydecode-emission3.td (+3-3)
  • (modified) llvm/test/TableGen/trydecode-emission4.td (+4-4)
  • (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+8-6)
diff --git a/llvm/test/TableGen/trydecode-emission.td b/llvm/test/TableGen/trydecode-emission.td
index 47d47c9c96183..c3178dd71cf4b 100644
--- a/llvm/test/TableGen/trydecode-emission.td
+++ b/llvm/test/TableGen/trydecode-emission.td
@@ -37,8 +37,8 @@ def InstB : TestInstruction {
 // CHECK:      /* 0 */       MCD::OPC_ExtractField, 4, 4,  // Inst{7-4} ...
 // CHECK-NEXT: /* 3 */       MCD::OPC_FilterValueOrFail, 0,
 // CHECK-NEXT: /* 5 */       MCD::OPC_CheckField, 2, 2, 0, 6, 0, // Skip to: 17
-// CHECK-NEXT: /* 11 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, Skip to: 17
-// CHECK-NEXT: /* 17 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-NEXT: /* 11 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 17
+// CHECK-NEXT: /* 17 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: {{[0-9]+}}
 // CHECK-NEXT: /* 21 */      MCD::OPC_Fail,
 
 // CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
@@ -50,8 +50,8 @@ def InstB : TestInstruction {
 // CHECK-LARGE:      /* 0 */       MCD::OPC_ExtractField, 4, 4,  // Inst{7-4} ...
 // CHECK-LARGE-NEXT: /* 3 */       MCD::OPC_FilterValueOrFail, 0,
 // CHECK-LARGE-NEXT: /* 5 */       MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 19
-// CHECK-LARGE-NEXT: /* 12 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, Skip to: 19
-// CHECK-LARGE-NEXT: /* 19 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-LARGE-NEXT: /* 12 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 19
+// CHECK-LARGE-NEXT: /* 19 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: {{[0-9]+}}
 // CHECK-LARGE-NEXT: /* 23 */      MCD::OPC_Fail,
 
 // CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/trydecode-emission2.td b/llvm/test/TableGen/trydecode-emission2.td
index 593da63cd7616..4c8a95eff5dd1 100644
--- a/llvm/test/TableGen/trydecode-emission2.td
+++ b/llvm/test/TableGen/trydecode-emission2.td
@@ -36,7 +36,7 @@ def InstB : TestInstruction {
 // CHECK-NEXT: /* 5 */       MCD::OPC_ExtractField, 5, 3,  // Inst{7-5} ...
 // CHECK-NEXT: /* 8 */       MCD::OPC_FilterValueOrFail, 0
 // CHECK-NEXT: /* 10 */      MCD::OPC_CheckField, 0, 2, 3, 6, 0, // Skip to: 22
-// CHECK-NEXT: /* 16 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, Skip to: 22
+// CHECK-NEXT: /* 16 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 22
 // CHECK-NEXT: /* 22 */      MCD::OPC_CheckFieldOrFail, 3, 2, 0,
 // CHECK-NEXT: /* 26 */      MCD::OPC_TryDecodeOrFail, {{[0-9]+}}, {{[0-9]+}}, 1,
 // CHECK-NEXT: /* 30 */      MCD::OPC_Fail,
@@ -49,7 +49,7 @@ def InstB : TestInstruction {
 // CHECK-LARGE-NEXT: /* 5 */       MCD::OPC_ExtractField, 5, 3,  // Inst{7-5} ...
 // CHECK-LARGE-NEXT: /* 8 */       MCD::OPC_FilterValueOrFail, 0,
 // CHECK-LARGE-NEXT: /* 10 */      MCD::OPC_CheckField, 0, 2, 3, 7, 0, 0, // Skip to: 24
-// CHECK-LARGE-NEXT: /* 17 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, Skip to: 24
+// CHECK-LARGE-NEXT: /* 17 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 24
 // CHECK-LARGE-NEXT: /* 24 */      MCD::OPC_CheckFieldOrFail, 3, 2, 0,
 // CHECK-LARGE-NEXT: /* 28 */      MCD::OPC_TryDecodeOrFail, {{[0-9]+}}, {{[0-9]+}}, 1,
 // CHECK-LARGE-NEXT: /* 32 */      MCD::OPC_Fail,
diff --git a/llvm/test/TableGen/trydecode-emission3.td b/llvm/test/TableGen/trydecode-emission3.td
index e2b739d8338de..f262bfab77c3b 100644
--- a/llvm/test/TableGen/trydecode-emission3.td
+++ b/llvm/test/TableGen/trydecode-emission3.td
@@ -38,7 +38,7 @@ def InstB : TestInstruction {
 // CHECK:      /* 0 */       MCD::OPC_ExtractField, 4, 4,  // Inst{7-4} ...
 // CHECK-NEXT: /* 3 */       MCD::OPC_FilterValueOrFail, 0,
 // CHECK-NEXT: /* 5 */       MCD::OPC_CheckField, 2, 2, 0, 6, 0, // Skip to: 17
-// CHECK-NEXT: /* 11 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, Skip to: 17
+// CHECK-NEXT: /* 11 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 17
 // CHECK-NEXT: /* 17 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
 // CHECK-NEXT: /* 21 */      MCD::OPC_Fail,
 
@@ -47,8 +47,8 @@ def InstB : TestInstruction {
 // CHECK-LARGE:      /* 0 */       MCD::OPC_ExtractField, 4, 4,  // Inst{7-4} ...
 // CHECK-LARGE-NEXT: /* 3 */       MCD::OPC_FilterValueOrFail, 0,
 // CHECK-LARGE-NEXT: /* 5 */       MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 19
-// CHECK-LARGE-NEXT: /* 12 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, Skip to: 19
-// CHECK-LARGE-NEXT: /* 19 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-LARGE-NEXT: /* 12 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 19
+// CHECK-LARGE-NEXT: /* 19 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: {{[0-9]+}}
 // CHECK-LARGE-NEXT: /* 23 */      MCD::OPC_Fail,
 
 // CHECK-LARGE: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/trydecode-emission4.td b/llvm/test/TableGen/trydecode-emission4.td
index 39a3187c38bda..2c63229c053a5 100644
--- a/llvm/test/TableGen/trydecode-emission4.td
+++ b/llvm/test/TableGen/trydecode-emission4.td
@@ -36,8 +36,8 @@ def InstB : TestInstruction {
 // CHECK:      /* 0 */       MCD::OPC_ExtractField, 250, 3, 4,  // Inst{509-506} ...
 // CHECK-NEXT: /* 4 */       MCD::OPC_FilterValueOrFail, 0,
 // CHECK-NEXT: /* 6 */       MCD::OPC_CheckField, 248, 3, 2, 0, 6, 0, // Skip to: 19
-// CHECK-NEXT: /* 13 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, Skip to: 19
-// CHECK-NEXT: /* 19 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-NEXT: /* 13 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 19
+// CHECK-NEXT: /* 19 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: {{[0-9]+}}
 // CHECK-NEXT: /* 23 */      MCD::OPC_Fail,
 
 // CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
@@ -46,8 +46,8 @@ def InstB : TestInstruction {
 // CHECK-LARGE:      /* 0 */       MCD::OPC_ExtractField, 250, 3, 4,  // Inst{509-506} ...
 // CHECK-LARGE-NEXT: /* 4 */       MCD::OPC_FilterValueOrFail, 0,
 // CHECK-LARGE-NEXT: /* 6 */       MCD::OPC_CheckField, 248, 3, 2, 0, 7, 0, 0, // Skip to: 21
-// CHECK-LARGE-NEXT: /* 14 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, Skip to: 21
-// CHECK-LARGE-NEXT: /* 21 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-LARGE-NEXT: /* 14 */      MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 21
+// CHECK-LARGE-NEXT: /* 21 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: {{[0-9]+}}
 // CHECK-LARGE-NEXT: /* 25 */      MCD::OPC_Fail,
 
 // CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 3990836e9077f..56c3644c134f1 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -975,6 +975,8 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
       emitULEB128(I, OS);
 
       // Decoder index.
+      unsigned DecodeIdx = decodeULEB128(&*I, nullptr, EndPtr, &ErrMsg);
+      assert(ErrMsg == nullptr && "ULEB128 value too large!");
       emitULEB128(I, OS);
 
       auto EncI = OpcodeToEncodingID.find(Opc);
@@ -982,18 +984,17 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
       auto EncodingID = EncI->second;
 
       if (!IsTry) {
-        OS << "// Opcode: " << NumberedEncodings[EncodingID] << "\n";
+        OS << "// Opcode: " << NumberedEncodings[EncodingID]
+           << ", DecodeIdx: " << DecodeIdx << '\n';
         break;
       }
 
       // Fallthrough for OPC_TryDecode.
-
       if (!IsFail) {
         uint32_t NumToSkip = emitNumToSkip(I, OS);
-        OS << "// Opcode: " << NumberedEncodings[EncodingID];
+        OS << "// Opcode: " << NumberedEncodings[EncodingID]
+           << ", DecodeIdx: " << DecodeIdx;
         emitNumToSkipComment(NumToSkip, /*InComment=*/true);
-      } else {
-        OS << "// Opcode: " << NumberedEncodings[EncodingID];
       }
       OS << '\n';
       break;
@@ -2249,7 +2250,8 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
     const uint8_t DecoderOp = *Ptr++;
     switch (DecoderOp) {
     default:
-      errs() << Loc << ": Unexpected decode table opcode!\n";
+      errs() << Loc << ": Unexpected decode table opcode: "
+             << (int)DecoderOp << '\n';
       return MCDisassembler::Fail;
     case MCD::OPC_ExtractField: {
       // Decode the start value.

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jurahul jurahul merged commit 7005a76 into llvm:main Jun 6, 2025
10 checks passed
@jurahul jurahul deleted the print_decode_idx branch June 6, 2025 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants