[llvm] [TableGen][DecoderEmitter] Add OPC_Scope opcode (PR #155580)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 5 11:17:48 PDT 2025
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/155580
>From 3c6c59ad383c7572dc146a0a4ae321d21a40f450 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sun, 24 Aug 2025 11:57:23 +0300
Subject: [PATCH 1/2] [TableGen][DecoderEmitter] Add OPC_Scope opcode
---
llvm/include/llvm/MC/MCDecoderOps.h | 24 +-
.../additional-encoding.td | 39 +--
.../FixedLenDecoderEmitter/big-filter.td | 14 +-
.../var-len-conflict-1.td | 25 +-
llvm/test/TableGen/VarLenDecoder.td | 11 +-
llvm/test/TableGen/trydecode-emission.td | 18 +-
llvm/test/TableGen/trydecode-emission2.td | 27 +-
llvm/test/TableGen/trydecode-emission3.td | 18 +-
llvm/test/TableGen/trydecode-emission4.td | 18 +-
llvm/utils/TableGen/DecoderEmitter.cpp | 255 +++++++-----------
10 files changed, 201 insertions(+), 248 deletions(-)
diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h
index d2e7cbf27b04b..790ff3eb4f333 100644
--- a/llvm/include/llvm/MC/MCDecoderOps.h
+++ b/llvm/include/llvm/MC/MCDecoderOps.h
@@ -16,20 +16,16 @@ namespace llvm::MCD {
// nts_t is either uint16_t or uint24_t based on whether large decoder table is
// enabled.
enum DecoderOps {
- OPC_ExtractField = 1, // OPC_ExtractField(uleb128 Start, uint8_t Len)
- OPC_FilterValue, // OPC_FilterValue(uleb128 Val, nts_t NumToSkip)
- OPC_FilterValueOrFail, // OPC_FilterValueOrFail(uleb128 Val)
- OPC_CheckField, // OPC_CheckField(uleb128 Start, uint8_t Len,
- // uleb128 Val, nts_t NumToSkip)
- OPC_CheckFieldOrFail, // OPC_CheckFieldOrFail(uleb128 Start, uint8_t Len,
- // uleb128 Val)
- OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx, nts_t NumToSkip)
- OPC_CheckPredicateOrFail, // OPC_CheckPredicateOrFail(uleb128 PIdx)
- OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
- OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx,
- // nts_t NumToSkip)
- OPC_TryDecodeOrFail, // OPC_TryDecodeOrFail(uleb128 Opcode, uleb128 DIdx)
- OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
+ OPC_Scope = 1, // OPC_Scope(nts_t NumToSkip)
+ OPC_ExtractField, // OPC_ExtractField(uleb128 Start, uint8_t Len)
+ OPC_FilterValueOrSkip, // OPC_FilterValueOrSkip(uleb128 Val, nts_t NumToSkip)
+ OPC_FilterValue, // OPC_FilterValue(uleb128 Val)
+ OPC_CheckField, // OPC_CheckField(uleb128 Start, uint8_t Len,
+ // uleb128 Val)
+ OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx)
+ OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
+ OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx)
+ OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
};
} // namespace llvm::MCD
diff --git a/llvm/test/TableGen/FixedLenDecoderEmitter/additional-encoding.td b/llvm/test/TableGen/FixedLenDecoderEmitter/additional-encoding.td
index 503822c37371e..ec7e35e1ecac7 100644
--- a/llvm/test/TableGen/FixedLenDecoderEmitter/additional-encoding.td
+++ b/llvm/test/TableGen/FixedLenDecoderEmitter/additional-encoding.td
@@ -30,23 +30,28 @@ class I<dag out_ops, dag in_ops> : Instruction {
let OutOperandList = out_ops;
}
-// CHECK: /* 0 */ MCD::OPC_ExtractField, 12, 4, // Inst{15-12} ...
-// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 14, 0, // Skip to: 21
-// CHECK-NEXT: /* 7 */ MCD::OPC_CheckField, 6, 6, 0, 4, 0, // Skip to: 17
-// CHECK-NEXT: /* 13 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP
-// CHECK-NEXT: /* 17 */ MCD::OPC_TryDecodeOrFail, {{[0-9]+}}, 2, 1,
-// CHECK-NEXT: /* 21 */ MCD::OPC_FilterValue, 1, 14, 0, // Skip to: 39
-// CHECK-NEXT: /* 25 */ MCD::OPC_CheckField, 6, 6, 0, 4, 0, // Skip to: 35
-// CHECK-NEXT: /* 31 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP
-// CHECK-NEXT: /* 35 */ MCD::OPC_TryDecodeOrFail, {{[0-9]+}}, 2, 1,
-// CHECK-NEXT: /* 39 */ MCD::OPC_FilterValue, 2, 14, 0, // Skip to: 57
-// CHECK-NEXT: /* 43 */ MCD::OPC_CheckField, 6, 6, 0, 4, 0, // Skip to: 53
-// CHECK-NEXT: /* 49 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP
-// CHECK-NEXT: /* 53 */ MCD::OPC_TryDecodeOrFail, {{[0-9]+}}, 2, 1,
-// CHECK-NEXT: /* 57 */ MCD::OPC_FilterValueOrFail, 3,
-// CHECK-NEXT: /* 59 */ MCD::OPC_CheckField, 6, 6, 0, 4, 0, // Skip to: 69
-// CHECK-NEXT: /* 65 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP
-// CHECK-NEXT: /* 69 */ MCD::OPC_TryDecodeOrFail, {{[0-9]+}}, 2, 1,
+// CHECK: /* 0 */ MCD::OPC_ExtractField, 12, 4, // Inst{15-12} ...
+// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValueOrSkip, 0, 15, 0, // Skip to: 22
+// CHECK-NEXT: /* 7 */ MCD::OPC_Scope, 8, 0, // Skip to: 18
+// CHECK-NEXT: /* 10 */ MCD::OPC_CheckField, 6, 6, 0,
+// CHECK-NEXT: /* 14 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
+// CHECK-NEXT: /* 18 */ MCD::OPC_TryDecode, 187, 2, 1,
+// CHECK-NEXT: /* 22 */ MCD::OPC_FilterValueOrSkip, 1, 15, 0, // Skip to: 41
+// CHECK-NEXT: /* 26 */ MCD::OPC_Scope, 8, 0, // Skip to: 37
+// CHECK-NEXT: /* 29 */ MCD::OPC_CheckField, 6, 6, 0,
+// CHECK-NEXT: /* 33 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
+// CHECK-NEXT: /* 37 */ MCD::OPC_TryDecode, 188, 2, 1,
+// CHECK-NEXT: /* 41 */ MCD::OPC_FilterValueOrSkip, 2, 15, 0, // Skip to: 60
+// CHECK-NEXT: /* 45 */ MCD::OPC_Scope, 8, 0, // Skip to: 56
+// CHECK-NEXT: /* 48 */ MCD::OPC_CheckField, 6, 6, 0,
+// CHECK-NEXT: /* 52 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
+// CHECK-NEXT: /* 56 */ MCD::OPC_TryDecode, 189, 2, 1,
+// CHECK-NEXT: /* 60 */ MCD::OPC_FilterValue, 3,
+// CHECK-NEXT: /* 62 */ MCD::OPC_Scope, 8, 0, // Skip to: 73
+// CHECK-NEXT: /* 65 */ MCD::OPC_CheckField, 6, 6, 0,
+// CHECK-NEXT: /* 69 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
+// CHECK-NEXT: /* 73 */ MCD::OPC_TryDecode, 190, 2, 1,
+
class SHIFT<bits<2> opc> : I<(outs), (ins ShAmtOp:$shamt)>, EncSHIFT<opc>;
def SHIFT0 : SHIFT<0>;
diff --git a/llvm/test/TableGen/FixedLenDecoderEmitter/big-filter.td b/llvm/test/TableGen/FixedLenDecoderEmitter/big-filter.td
index 7e2cda1bae9ed..28762bfa1ec24 100644
--- a/llvm/test/TableGen/FixedLenDecoderEmitter/big-filter.td
+++ b/llvm/test/TableGen/FixedLenDecoderEmitter/big-filter.td
@@ -12,13 +12,13 @@ class I : Instruction {
// Check that a 64-bit filter with all bits set does not confuse DecoderEmitter.
//
// CHECK-LABEL: static const uint8_t DecoderTable128[34] = {
-// CHECK-NEXT: MCD::OPC_ExtractField, 0, 64,
-// CHECK-NEXT: MCD::OPC_FilterValue, 1, 8, 0,
-// CHECK-NEXT: MCD::OPC_CheckFieldOrFail, 127, 1, 1,
-// CHECK-NEXT: MCD::OPC_Decode, 187, 2, 0,
-// CHECK-NEXT: MCD::OPC_FilterValueOrFail, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1,
-// CHECK-NEXT: MCD::OPC_CheckFieldOrFail, 127, 1, 0,
-// CHECK-NEXT: MCD::OPC_Decode, 186, 2, 0,
+// CHECK-NEXT: /* 0 */ MCD::OPC_ExtractField, 0, 64, // Inst{63-0} ...
+// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValueOrSkip, 1, 8, 0, // Skip to: 15
+// CHECK-NEXT: /* 7 */ MCD::OPC_CheckField, 127, 1, 1,
+// CHECK-NEXT: /* 11 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: I2, DecodeIdx: 0
+// CHECK-NEXT: /* 15 */ MCD::OPC_FilterValue, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1,
+// CHECK-NEXT: /* 26 */ MCD::OPC_CheckField, 127, 1, 0,
+// CHECK-NEXT: /* 30 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: I1, DecodeIdx: 0
// CHECK-NEXT: };
def I1 : I {
diff --git a/llvm/test/TableGen/FixedLenDecoderEmitter/var-len-conflict-1.td b/llvm/test/TableGen/FixedLenDecoderEmitter/var-len-conflict-1.td
index eda714eef1048..8afcf786f9c73 100644
--- a/llvm/test/TableGen/FixedLenDecoderEmitter/var-len-conflict-1.td
+++ b/llvm/test/TableGen/FixedLenDecoderEmitter/var-len-conflict-1.td
@@ -18,18 +18,19 @@ class I : Instruction {
// 00000001 ________ I16_1
// 00000010 ________ I16_2
-// CHECK: MCD::OPC_ExtractField, 0, 1, // Inst{0} ...
-// CHECK-NEXT: MCD::OPC_FilterValue, 0, 4, 0, // Skip to: 11
-// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: I8_0, DecodeIdx: 0
-// CHECK-NEXT: MCD::OPC_FilterValue, 1, 4, 0, // Skip to: 19
-// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: I8_1, DecodeIdx: 0
-// CHECK-NEXT: MCD::OPC_ExtractField, 8, 8, // Inst{15-8} ...
-// CHECK-NEXT: MCD::OPC_FilterValue, 0, 4, 0, // Skip to: 30
-// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, 2, 1, // Opcode: I16_0, DecodeIdx: 1
-// CHECK-NEXT: MCD::OPC_FilterValue, 1, 4, 0, // Skip to: 38
-// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, 2, 1, // Opcode: I16_1, DecodeIdx: 1
-// CHECK-NEXT: MCD::OPC_FilterValueOrFail, 2,
-// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, 2, 1, // Opcode: I16_2, DecodeIdx: 1
+// CHECK: /* 0 */ MCD::OPC_Scope, 17, 0, // Skip to: 20
+// CHECK-NEXT: /* 3 */ MCD::OPC_ExtractField, 0, 1, // Inst{0} ...
+// CHECK-NEXT: /* 6 */ MCD::OPC_FilterValueOrSkip, 0, 4, 0, // Skip to: 14
+// CHECK-NEXT: /* 10 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: I8_0, DecodeIdx: 0
+// CHECK-NEXT: /* 14 */ MCD::OPC_FilterValue, 1,
+// CHECK-NEXT: /* 16 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: I8_1, DecodeIdx: 0
+// CHECK-NEXT: /* 20 */ MCD::OPC_ExtractField, 8, 8, // Inst{15-8} ...
+// CHECK-NEXT: /* 23 */ MCD::OPC_FilterValueOrSkip, 0, 4, 0, // Skip to: 31
+// CHECK-NEXT: /* 27 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 1, // Opcode: I16_0, DecodeIdx: 1
+// CHECK-NEXT: /* 31 */ MCD::OPC_FilterValueOrSkip, 1, 4, 0, // Skip to: 39
+// CHECK-NEXT: /* 35 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 1, // Opcode: I16_1, DecodeIdx: 1
+// CHECK-NEXT: /* 39 */ MCD::OPC_FilterValue, 2,
+// CHECK-NEXT: /* 41 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 1, // Opcode: I16_2, DecodeIdx: 1
def I8_0 : I { dag Inst = (descend (operand "$op", 7), 0b0); }
def I8_1 : I { dag Inst = (descend (operand "$op", 7), 0b1); }
diff --git a/llvm/test/TableGen/VarLenDecoder.td b/llvm/test/TableGen/VarLenDecoder.td
index 10e254f7673e6..7eda1e6e47431 100644
--- a/llvm/test/TableGen/VarLenDecoder.td
+++ b/llvm/test/TableGen/VarLenDecoder.td
@@ -54,16 +54,16 @@ def FOO32 : MyVarInst<MemOp32> {
// CHECK-NEXT: };
// CHECK-SMALL: /* 0 */ MCD::OPC_ExtractField, 3, 5, // Inst{7-3} ...
-// CHECK-SMALL-NEXT: /* 3 */ MCD::OPC_FilterValue, 8, 4, 0, // Skip to: 11
+// CHECK-SMALL-NEXT: /* 3 */ MCD::OPC_FilterValueOrSkip, 8, 4, 0, // Skip to: 11
// CHECK-SMALL-NEXT: /* 7 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16
-// CHECK-SMALL-NEXT: /* 11 */ MCD::OPC_FilterValueOrFail, 9,
+// CHECK-SMALL-NEXT: /* 11 */ MCD::OPC_FilterValue, 9,
// CHECK-SMALL-NEXT: /* 13 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
// CHECK-SMALL-NEXT: };
// CHECK-LARGE: /* 0 */ MCD::OPC_ExtractField, 3, 5, // Inst{7-3} ...
-// CHECK-LARGE-NEXT: /* 3 */ MCD::OPC_FilterValue, 8, 4, 0, 0, // Skip to: 12
+// CHECK-LARGE-NEXT: /* 3 */ MCD::OPC_FilterValueOrSkip, 8, 4, 0, 0, // Skip to: 12
// CHECK-LARGE-NEXT: /* 8 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16
-// CHECK-LARGE-NEXT: /* 12 */ MCD::OPC_FilterValueOrFail, 9,
+// CHECK-LARGE-NEXT: /* 12 */ MCD::OPC_FilterValue, 9,
// CHECK-LARGE-NEXT: /* 14 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
// CHECK-LARGE-NEXT: };
@@ -89,8 +89,7 @@ def FOO32 : MyVarInst<MemOp32> {
// CHECK-LABEL: case MCD::OPC_ExtractField: {
// CHECK: makeUp(insn, Start + Len);
-// CHECK-LABEL: case MCD::OPC_CheckField:
-// CHECK-NEXT: case MCD::OPC_CheckFieldOrFail: {
+// CHECK-LABEL: case MCD::OPC_CheckField: {
// CHECK: makeUp(insn, Start + Len);
// CHECK-LABEL: case MCD::OPC_Decode: {
diff --git a/llvm/test/TableGen/trydecode-emission.td b/llvm/test/TableGen/trydecode-emission.td
index 5d1c18fe65d0e..d1cf4bf541835 100644
--- a/llvm/test/TableGen/trydecode-emission.td
+++ b/llvm/test/TableGen/trydecode-emission.td
@@ -34,10 +34,11 @@ def InstB : TestInstruction {
let hasCompleteDecoder = 0;
}
-// CHECK: /* 0 */ MCD::OPC_CheckFieldOrFail, 4, 4, 0,
-// CHECK-NEXT: /* 4 */ MCD::OPC_CheckField, 2, 2, 0, 6, 0, // Skip to: 16
-// CHECK-NEXT: /* 10 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 16
-// CHECK-NEXT: /* 16 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: {{[0-9]+}}
+// CHECK: /* 0 */ MCD::OPC_CheckField, 4, 4, 0,
+// CHECK-NEXT: /* 4 */ MCD::OPC_Scope, 8, 0, // Skip to: 15
+// CHECK-NEXT: /* 7 */ MCD::OPC_CheckField, 2, 2, 0,
+// CHECK-NEXT: /* 11 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
+// CHECK-NEXT: /* 15 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
@@ -46,10 +47,11 @@ def InstB : TestInstruction {
// CHECK-NEXT: NumToSkip |= (*Ptr++) << 8;
// CHECK-NEXT: return NumToSkip;
-// CHECK-LARGE: /* 0 */ MCD::OPC_CheckFieldOrFail, 4, 4, 0,
-// CHECK-LARGE-NEXT: /* 4 */ MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 18
-// CHECK-LARGE-NEXT: /* 11 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 18
-// CHECK-LARGE-NEXT: /* 18 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: {{[0-9]+}}
+// CHECK-LARGE: /* 0 */ MCD::OPC_CheckField, 4, 4, 0,
+// CHECK-LARGE-NEXT: /* 4 */ MCD::OPC_Scope, 8, 0, 0, // Skip to: 16
+// CHECK-LARGE-NEXT: /* 8 */ MCD::OPC_CheckField, 2, 2, 0,
+// CHECK-LARGE-NEXT: /* 12 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
+// CHECK-LARGE-NEXT: /* 16 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
// 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 375be9ad13d19..d7a87eb4b8691 100644
--- a/llvm/test/TableGen/trydecode-emission2.td
+++ b/llvm/test/TableGen/trydecode-emission2.td
@@ -31,23 +31,24 @@ def InstB : TestInstruction {
let hasCompleteDecoder = 0;
}
-// CHECK: /* 0 */ MCD::OPC_CheckFieldOrFail, 2, 1, 0,
-// CHECK-NEXT: /* 4 */ MCD::OPC_CheckFieldOrFail, 5, 3, 0,
-// CHECK-NEXT: /* 8 */ MCD::OPC_CheckField, 0, 2, 3, 6, 0, // Skip to: 20
-// CHECK-NEXT: /* 14 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 20
-// CHECK-NEXT: /* 20 */ MCD::OPC_CheckFieldOrFail, 3, 2, 0,
-// CHECK-NEXT: /* 24 */ MCD::OPC_TryDecodeOrFail, {{[0-9]+}}, {{[0-9]+}}, 1,
-// CHECK-NEXT: };
+// CHECK: /* 0 */ MCD::OPC_CheckField, 2, 1, 0,
+// CHECK-NEXT: /* 4 */ MCD::OPC_CheckField, 5, 3, 0,
+// CHECK-NEXT: /* 8 */ MCD::OPC_Scope, 8, 0, // Skip to: 19
+// CHECK-NEXT: /* 11 */ MCD::OPC_CheckField, 0, 2, 3,
+// CHECK-NEXT: /* 15 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
+// CHECK-NEXT: /* 19 */ MCD::OPC_CheckField, 3, 2, 0,
+// CHECK-NEXT: /* 23 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1,
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
// CHECK: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-// CHECK-LARGE: /* 0 */ MCD::OPC_CheckFieldOrFail, 2, 1, 0,
-// CHECK-LARGE-NEXT: /* 4 */ MCD::OPC_CheckFieldOrFail, 5, 3, 0,
-// CHECK-LARGE-NEXT: /* 8 */ MCD::OPC_CheckField, 0, 2, 3, 7, 0, 0, // Skip to: 22
-// CHECK-LARGE-NEXT: /* 15 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 22
-// CHECK-LARGE-NEXT: /* 22 */ MCD::OPC_CheckFieldOrFail, 3, 2, 0,
-// CHECK-LARGE-NEXT: /* 26 */ MCD::OPC_TryDecodeOrFail, {{[0-9]+}}, {{[0-9]+}}, 1,
+// CHECK-LARGE: /* 0 */ MCD::OPC_CheckField, 2, 1, 0,
+// CHECK-LARGE-NEXT: /* 4 */ MCD::OPC_CheckField, 5, 3, 0,
+// CHECK-LARGE-NEXT: /* 8 */ MCD::OPC_Scope, 8, 0, 0, // Skip to: 20
+// CHECK-LARGE-NEXT: /* 12 */ MCD::OPC_CheckField, 0, 2, 3,
+// CHECK-LARGE-NEXT: /* 16 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
+// CHECK-LARGE-NEXT: /* 20 */ MCD::OPC_CheckField, 3, 2, 0,
+// CHECK-LARGE-NEXT: /* 24 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1,
// CHECK-LARGE-NEXT: };
// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/trydecode-emission3.td b/llvm/test/TableGen/trydecode-emission3.td
index 9696724ce2836..b7d1b8ddc1b6c 100644
--- a/llvm/test/TableGen/trydecode-emission3.td
+++ b/llvm/test/TableGen/trydecode-emission3.td
@@ -35,18 +35,20 @@ def InstB : TestInstruction {
let AsmString = "InstB";
}
-// CHECK: /* 0 */ MCD::OPC_CheckFieldOrFail, 4, 4, 0,
-// CHECK-NEXT: /* 4 */ MCD::OPC_CheckField, 2, 2, 0, 6, 0, // Skip to: 16
-// CHECK-NEXT: /* 10 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 16
-// CHECK-NEXT: /* 16 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK: /* 0 */ MCD::OPC_CheckField, 4, 4, 0,
+// CHECK-NEXT: /* 4 */ MCD::OPC_Scope, 8, 0, // Skip to: 15
+// CHECK-NEXT: /* 7 */ MCD::OPC_CheckField, 2, 2, 0,
+// CHECK-NEXT: /* 11 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
+// CHECK-NEXT: /* 15 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
// CHECK: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-// CHECK-LARGE: /* 0 */ MCD::OPC_CheckFieldOrFail, 4, 4, 0,
-// CHECK-LARGE-NEXT: /* 4 */ MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 18
-// CHECK-LARGE-NEXT: /* 11 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 18
-// CHECK-LARGE-NEXT: /* 18 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: {{[0-9]+}}
+// CHECK-LARGE: /* 0 */ MCD::OPC_CheckField, 4, 4, 0,
+// CHECK-LARGE-NEXT: /* 4 */ MCD::OPC_Scope, 8, 0, 0, // Skip to: 16
+// CHECK-LARGE-NEXT: /* 8 */ MCD::OPC_CheckField, 2, 2, 0,
+// CHECK-LARGE-NEXT: /* 12 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
+// CHECK-LARGE-NEXT: /* 16 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
// 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 03cb635dbcaad..439bd9d4ff369 100644
--- a/llvm/test/TableGen/trydecode-emission4.td
+++ b/llvm/test/TableGen/trydecode-emission4.td
@@ -33,19 +33,21 @@ def InstB : TestInstruction {
let hasCompleteDecoder = 0;
}
-// CHECK: /* 0 */ MCD::OPC_CheckFieldOrFail, 250, 3, 4, 0,
-// CHECK-NEXT: /* 5 */ MCD::OPC_CheckField, 248, 3, 2, 0, 6, 0, // Skip to: 18
-// CHECK-NEXT: /* 12 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 18
-// CHECK-NEXT: /* 18 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: {{[0-9]+}}
+// CHECK: /* 0 */ MCD::OPC_CheckField, 250, 3, 4, 0,
+// CHECK-NEXT: /* 5 */ MCD::OPC_Scope, 9, 0, // Skip to: 17
+// CHECK-NEXT: /* 8 */ MCD::OPC_CheckField, 248, 3, 2, 0,
+// CHECK-NEXT: /* 13 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
+// CHECK-NEXT: /* 17 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-// CHECK-LARGE: /* 0 */ MCD::OPC_CheckFieldOrFail, 250, 3, 4, 0,
-// CHECK-LARGE-NEXT: /* 5 */ MCD::OPC_CheckField, 248, 3, 2, 0, 7, 0, 0, // Skip to: 20
-// CHECK-LARGE-NEXT: /* 13 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, DecodeIdx: {{[0-9]+}}, Skip to: 20
-// CHECK-LARGE-NEXT: /* 20 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: {{[0-9]+}}
+// CHECK-LARGE: /* 0 */ MCD::OPC_CheckField, 250, 3, 4, 0,
+// CHECK-LARGE-NEXT: /* 5 */ MCD::OPC_Scope, 9, 0, 0, // Skip to: 18
+// CHECK-LARGE-NEXT: /* 9 */ MCD::OPC_CheckField, 248, 3, 2, 0,
+// CHECK-LARGE-NEXT: /* 14 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0,
+// CHECK-LARGE-NEXT: /* 18 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
// 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 ebb7deb757c44..918426f012bae 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -276,8 +276,6 @@ class LessEncodingIDByWidth {
}
};
-typedef std::vector<uint32_t> FixupList;
-typedef std::vector<FixupList> FixupScopeList;
typedef SmallSetVector<CachedHashString, 16> PredicateSet;
typedef SmallSetVector<CachedHashString, 16> DecoderSet;
@@ -342,21 +340,17 @@ class DecoderTable {
struct DecoderTableInfo {
DecoderTable Table;
- FixupScopeList FixupStack;
+ SmallVector<unsigned, 8> FixupStack;
PredicateSet Predicates;
DecoderSet Decoders;
- bool isOutermostScope() const { return FixupStack.empty(); }
-
- void pushScope() { FixupStack.emplace_back(); }
+ void pushScope() {
+ Table.insertOpcode(MCD::OPC_Scope);
+ FixupStack.push_back(Table.insertNumToSkip());
+ }
void popScope() {
- // Resolve any remaining fixups in the current scope before popping it.
- // All fixups resolve to the current location.
- uint32_t DestIdx = Table.size();
- for (uint32_t FixupIdx : FixupStack.back())
- Table.patchNumToSkip(FixupIdx, DestIdx);
- FixupStack.pop_back();
+ Table.patchNumToSkip(FixupStack.pop_back_val(), Table.size());
}
};
@@ -819,6 +813,13 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
default:
PrintFatalError("Invalid decode table opcode: " + Twine((int)DecoderOp) +
" at index " + Twine(Pos));
+ case MCD::OPC_Scope: {
+ OS << " MCD::OPC_Scope, ";
+ uint32_t NumToSkip = emitNumToSkip(I, OS);
+ emitNumToSkipComment(NumToSkip);
+ OS << '\n';
+ break;
+ }
case MCD::OPC_ExtractField: {
OS << " MCD::OPC_ExtractField, ";
@@ -835,24 +836,24 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
OS << Start << "} ...\n";
break;
}
- case MCD::OPC_FilterValue:
- case MCD::OPC_FilterValueOrFail: {
- bool IsFail = DecoderOp == MCD::OPC_FilterValueOrFail;
- OS << " MCD::OPC_FilterValue" << (IsFail ? "OrFail, " : ", ");
+ case MCD::OPC_FilterValueOrSkip: {
+ OS << " MCD::OPC_FilterValueOrSkip, ";
+ // The filter value is ULEB128 encoded.
+ emitULEB128(I, OS);
+ uint32_t NumToSkip = emitNumToSkip(I, OS);
+ emitNumToSkipComment(NumToSkip);
+ OS << '\n';
+ break;
+ }
+ case MCD::OPC_FilterValue: {
+ OS << " MCD::OPC_FilterValue, ";
// The filter value is ULEB128 encoded.
emitULEB128(I, OS);
-
- if (!IsFail) {
- uint32_t NumToSkip = emitNumToSkip(I, OS);
- emitNumToSkipComment(NumToSkip);
- }
OS << '\n';
break;
}
- case MCD::OPC_CheckField:
- case MCD::OPC_CheckFieldOrFail: {
- bool IsFail = DecoderOp == MCD::OPC_CheckFieldOrFail;
- OS << " MCD::OPC_CheckField" << (IsFail ? "OrFail, " : ", ");
+ case MCD::OPC_CheckField: {
+ OS << " MCD::OPC_CheckField, ";
// ULEB128 encoded start value.
emitULEB128(I, OS);
// 8-bit length.
@@ -860,40 +861,24 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
OS << Len << ", ";
// ULEB128 encoded field value.
emitULEB128(I, OS);
-
- if (!IsFail) {
- uint32_t NumToSkip = emitNumToSkip(I, OS);
- emitNumToSkipComment(NumToSkip);
- }
OS << '\n';
break;
}
- case MCD::OPC_CheckPredicate:
- case MCD::OPC_CheckPredicateOrFail: {
- bool IsFail = DecoderOp == MCD::OPC_CheckPredicateOrFail;
-
- OS << " MCD::OPC_CheckPredicate" << (IsFail ? "OrFail, " : ", ");
+ case MCD::OPC_CheckPredicate: {
+ OS << " MCD::OPC_CheckPredicate, ";
emitULEB128(I, OS);
-
- if (!IsFail) {
- uint32_t NumToSkip = emitNumToSkip(I, OS);
- emitNumToSkipComment(NumToSkip);
- }
OS << '\n';
break;
}
case MCD::OPC_Decode:
- case MCD::OPC_TryDecode:
- case MCD::OPC_TryDecodeOrFail: {
- bool IsFail = DecoderOp == MCD::OPC_TryDecodeOrFail;
- bool IsTry = DecoderOp == MCD::OPC_TryDecode || IsFail;
+ case MCD::OPC_TryDecode: {
+ bool IsTry = DecoderOp == MCD::OPC_TryDecode;
// Decode the Opcode value.
const char *ErrMsg = nullptr;
unsigned Opc = decodeULEB128(&*I, nullptr, EndPtr, &ErrMsg);
assert(ErrMsg == nullptr && "ULEB128 value too large!");
- OS << " MCD::OPC_" << (IsTry ? "Try" : "") << "Decode"
- << (IsFail ? "OrFail, " : ", ");
+ OS << " MCD::OPC_" << (IsTry ? "Try" : "") << "Decode, ";
emitULEB128(I, OS);
// Decoder index.
@@ -910,14 +895,6 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
<< ", DecodeIdx: " << DecodeIdx << '\n';
break;
}
-
- // Fallthrough for OPC_TryDecode.
- if (!IsFail) {
- uint32_t NumToSkip = emitNumToSkip(I, OS);
- OS << "// Opcode: " << Encodings[EncodingID].getName()
- << ", DecodeIdx: " << DecodeIdx;
- emitNumToSkipComment(NumToSkip, /*InComment=*/true);
- }
OS << '\n';
break;
}
@@ -1314,16 +1291,8 @@ void DecoderTableBuilder::emitPredicateTableEntry(unsigned EncodingID) const {
// computed.
unsigned PIdx = getPredicateIndex(PS.str());
- const MCD::DecoderOps DecoderOp = TableInfo.isOutermostScope()
- ? MCD::OPC_CheckPredicateOrFail
- : MCD::OPC_CheckPredicate;
- TableInfo.Table.insertOpcode(DecoderOp);
+ TableInfo.Table.insertOpcode(MCD::OPC_CheckPredicate);
TableInfo.Table.insertULEB128(PIdx);
-
- if (DecoderOp == MCD::OPC_CheckPredicate) {
- // Push location for NumToSkip backpatching.
- TableInfo.FixupStack.back().push_back(TableInfo.Table.insertNumToSkip());
- }
}
void DecoderTableBuilder::emitSoftFailTableEntry(unsigned EncodingID) const {
@@ -1357,21 +1326,10 @@ void DecoderTableBuilder::emitSingletonTableEntry(
// Check any additional encoding fields needed.
for (const FilterChooser::Island &Ilnd : reverse(Islands)) {
- const MCD::DecoderOps DecoderOp = TableInfo.isOutermostScope()
- ? MCD::OPC_CheckFieldOrFail
- : MCD::OPC_CheckField;
- TableInfo.Table.insertOpcode(DecoderOp);
+ TableInfo.Table.insertOpcode(MCD::OPC_CheckField);
TableInfo.Table.insertULEB128(Ilnd.StartBit);
TableInfo.Table.insertUInt8(Ilnd.NumBits);
TableInfo.Table.insertULEB128(Ilnd.FieldVal);
-
- if (DecoderOp == MCD::OPC_CheckField) {
- // Allocate space in the table for fixup so all our relative position
- // calculations work OK even before we fully resolve the real value here.
-
- // Push location for NumToSkip backpatching.
- TableInfo.FixupStack.back().push_back(TableInfo.Table.insertNumToSkip());
- }
}
// Check for soft failure of the match.
@@ -1389,18 +1347,11 @@ void DecoderTableBuilder::emitSingletonTableEntry(
// if there is any other instruction that also matches the bitpattern and
// can decode it.
const MCD::DecoderOps DecoderOp =
- Encoding.hasCompleteDecoder() ? MCD::OPC_Decode
- : TableInfo.isOutermostScope() ? MCD::OPC_TryDecodeOrFail
- : MCD::OPC_TryDecode;
+ Encoding.hasCompleteDecoder() ? MCD::OPC_Decode : MCD::OPC_TryDecode;
TableInfo.Table.insertOpcode(DecoderOp);
const Record *InstDef = Encodings[EncodingID].getInstruction()->TheDef;
TableInfo.Table.insertULEB128(Target.getInstrIntValue(InstDef));
TableInfo.Table.insertULEB128(DIdx);
-
- if (DecoderOp == MCD::OPC_TryDecode) {
- // Push location for NumToSkip backpatching.
- TableInfo.FixupStack.back().push_back(TableInfo.Table.insertNumToSkip());
- }
}
// reportRegion is a helper function for filterProcessor to mark a region as
@@ -1700,14 +1651,10 @@ void DecoderTableBuilder::emitTableEntries(const FilterChooser &FC) const {
// If there is only one possible field value, emit a combined OPC_CheckField
// instead of OPC_ExtractField + OPC_FilterValue.
const auto &[FilterVal, Delegate] = *FC.FilterChooserMap.begin();
- Table.insertOpcode(!TableInfo.isOutermostScope()
- ? MCD::OPC_CheckField
- : MCD::OPC_CheckFieldOrFail);
+ Table.insertOpcode(MCD::OPC_CheckField);
Table.insertULEB128(FC.StartBit);
Table.insertUInt8(FC.NumBits);
Table.insertULEB128(FilterVal);
- if (!TableInfo.isOutermostScope())
- TableInfo.FixupStack.back().push_back(TableInfo.Table.insertNumToSkip());
// Emit table entries for the only case.
emitTableEntries(*Delegate);
@@ -1719,26 +1666,22 @@ void DecoderTableBuilder::emitTableEntries(const FilterChooser &FC) const {
// Emit switch cases for all but the last element.
for (const auto &[FilterVal, Delegate] : drop_end(FC.FilterChooserMap)) {
- Table.insertOpcode(MCD::OPC_FilterValue);
+ Table.insertOpcode(MCD::OPC_FilterValueOrSkip);
Table.insertULEB128(FilterVal);
size_t FixupPos = Table.insertNumToSkip();
// Emit table entries for this case.
emitTableEntries(*Delegate);
- // Patch the previous OPC_FilterValue to fall through to the next case.
+ // Patch the previous FilterValueOrSkip to fall through to the next case.
Table.patchNumToSkip(FixupPos, Table.size());
}
// Emit a switch case for the last element. It never falls through;
// if it doesn't match, we leave the current scope.
const auto &[FilterVal, Delegate] = *FC.FilterChooserMap.rbegin();
- Table.insertOpcode(!TableInfo.isOutermostScope()
- ? MCD::OPC_FilterValue
- : MCD::OPC_FilterValueOrFail);
+ Table.insertOpcode(MCD::OPC_FilterValue);
Table.insertULEB128(FilterVal);
- if (!TableInfo.isOutermostScope())
- TableInfo.FixupStack.back().push_back(Table.insertNumToSkip());
// Emit table entries for the last case.
emitTableEntries(*Delegate);
@@ -2170,11 +2113,8 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef,
// decodeInstruction().
static void emitDecodeInstruction(formatted_raw_ostream &OS, bool IsVarLenInst,
unsigned OpcodeMask) {
- const bool HasTryDecode = OpcodeMask & ((1 << MCD::OPC_TryDecode) |
- (1 << MCD::OPC_TryDecodeOrFail));
- const bool HasCheckPredicate =
- OpcodeMask &
- ((1 << MCD::OPC_CheckPredicate) | (1 << MCD::OPC_CheckPredicateOrFail));
+ const bool HasTryDecode = OpcodeMask & (1 << MCD::OPC_TryDecode);
+ const bool HasCheckPredicate = OpcodeMask & (1 << MCD::OPC_CheckPredicate);
const bool HasSoftFail = OpcodeMask & (1 << MCD::OPC_SoftFail);
OS << R"(
@@ -2213,6 +2153,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
}
OS << R"(
+ SmallVector<const uint8_t *, 8> ScopeStack;
uint64_t CurFieldValue = 0;
DecodeStatus S = MCDisassembler::Success;
while (true) {
@@ -2223,6 +2164,14 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
errs() << Loc << ": Unexpected decode table opcode: "
<< (int)DecoderOp << '\n';
return MCDisassembler::Fail;
+ case MCD::OPC_Scope: {
+ unsigned NumToSkip = decodeNumToSkip(Ptr);
+ const uint8_t *SkipTo = Ptr + NumToSkip;
+ ScopeStack.push_back(SkipTo);
+ LLVM_DEBUG(dbgs() << Loc << ": OPC_Scope(" << SkipTo - DecodeTable
+ << ")\n");
+ break;
+ }
case MCD::OPC_ExtractField: {
// Decode the start value.
unsigned Start = decodeULEB128AndIncUnsafe(Ptr);
@@ -2235,34 +2184,42 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
<< Len << "): " << CurFieldValue << "\n");
break;
}
- case MCD::OPC_FilterValue:
- case MCD::OPC_FilterValueOrFail: {
- bool IsFail = DecoderOp == MCD::OPC_FilterValueOrFail;
+ case MCD::OPC_FilterValueOrSkip: {
+ // Decode the field value.
+ uint64_t Val = decodeULEB128AndIncUnsafe(Ptr);
+ bool Failed = Val != CurFieldValue;
+ unsigned NumToSkip = decodeNumToSkip(Ptr);
+ const uint8_t *SkipTo = Ptr + NumToSkip;
+
+ LLVM_DEBUG(dbgs() << Loc << ": OPC_FilterValueOrSkip(" << Val << ", "
+ << SkipTo - DecodeTable << ") "
+ << (Failed ? "FAIL, " : "PASS\n"));
+
+ if (Failed) {
+ Ptr = SkipTo;
+ LLVM_DEBUG(dbgs() << "continuing at " << Ptr - DecodeTable << '\n');
+ }
+ break;
+ }
+ case MCD::OPC_FilterValue: {
// Decode the field value.
uint64_t Val = decodeULEB128AndIncUnsafe(Ptr);
bool Failed = Val != CurFieldValue;
- unsigned NumToSkip = IsFail ? 0 : decodeNumToSkip(Ptr);
-
- // Note: Print NumToSkip even for OPC_FilterValueOrFail to simplify debug
- // prints.
- LLVM_DEBUG({
- StringRef OpName = IsFail ? "OPC_FilterValueOrFail" : "OPC_FilterValue";
- dbgs() << Loc << ": " << OpName << '(' << Val << ", " << NumToSkip
- << ") " << (Failed ? "FAIL:" : "PASS:")
- << " continuing at " << (Ptr - DecodeTable) << '\n';
- });
-
- // Perform the filter operation.
+
+ LLVM_DEBUG(dbgs() << Loc << ": OPC_FilterValue(" << Val << ") "
+ << (Failed ? "FAIL, " : "PASS\n"));
+
if (Failed) {
- if (IsFail)
+ if (ScopeStack.empty()) {
+ LLVM_DEBUG(dbgs() << "returning Fail\n");
return MCDisassembler::Fail;
- Ptr += NumToSkip;
+ }
+ Ptr = ScopeStack.pop_back_val();
+ LLVM_DEBUG(dbgs() << "continuing at " << Ptr - DecodeTable << '\n');
}
break;
}
- case MCD::OPC_CheckField:
- case MCD::OPC_CheckFieldOrFail: {
- bool IsFail = DecoderOp == MCD::OPC_CheckFieldOrFail;
+ case MCD::OPC_CheckField: {
// Decode the start value.
unsigned Start = decodeULEB128AndIncUnsafe(Ptr);
unsigned Len = *Ptr;)";
@@ -2275,45 +2232,39 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen);
Ptr += PtrLen;
bool Failed = ExpectedValue != FieldValue;
- unsigned NumToSkip = IsFail ? 0 : decodeNumToSkip(Ptr);
-
- LLVM_DEBUG({
- StringRef OpName = IsFail ? "OPC_CheckFieldOrFail" : "OPC_CheckField";
- dbgs() << Loc << ": " << OpName << '(' << Start << ", " << Len << ", "
- << ExpectedValue << ", " << NumToSkip << "): FieldValue = "
- << FieldValue << ", ExpectedValue = " << ExpectedValue << ": "
- << (Failed ? "FAIL\n" : "PASS\n");
- });
- // If the actual and expected values don't match, skip or fail.
+ LLVM_DEBUG(dbgs() << Loc << ": OPC_CheckField(" << Start << ", " << Len
+ << ", " << ExpectedValue << "): FieldValue = "
+ << FieldValue << ", ExpectedValue = " << ExpectedValue
+ << ": " << (Failed ? "FAIL, " : "PASS\n"););
if (Failed) {
- if (IsFail)
+ if (ScopeStack.empty()) {
+ LLVM_DEBUG(dbgs() << "returning Fail\n");
return MCDisassembler::Fail;
- Ptr += NumToSkip;
+ }
+ Ptr = ScopeStack.pop_back_val();
+ LLVM_DEBUG(dbgs() << "continuing at " << Ptr - DecodeTable << '\n');
}
break;
})";
if (HasCheckPredicate) {
OS << R"(
- case MCD::OPC_CheckPredicate:
- case MCD::OPC_CheckPredicateOrFail: {
- bool IsFail = DecoderOp == MCD::OPC_CheckPredicateOrFail;
+ case MCD::OPC_CheckPredicate: {
// Decode the Predicate Index value.
unsigned PIdx = decodeULEB128AndIncUnsafe(Ptr);
- unsigned NumToSkip = IsFail ? 0 : decodeNumToSkip(Ptr);
// Check the predicate.
bool Failed = !checkDecoderPredicate(PIdx, Bits);
- LLVM_DEBUG({
- StringRef OpName = IsFail ? "OPC_CheckPredicateOrFail" : "OPC_CheckPredicate";
- dbgs() << Loc << ": " << OpName << '(' << PIdx << ", " << NumToSkip
- << "): " << (Failed ? "FAIL\n" : "PASS\n");
- });
+ LLVM_DEBUG(dbgs() << Loc << ": OPC_CheckPredicate(" << PIdx << "): "
+ << (Failed ? "FAIL, " : "PASS\n"););
if (Failed) {
- if (IsFail)
+ if (ScopeStack.empty()) {
+ LLVM_DEBUG(dbgs() << "returning Fail\n");
return MCDisassembler::Fail;
- Ptr += NumToSkip;
+ }
+ Ptr = ScopeStack.pop_back_val();
+ LLVM_DEBUG(dbgs() << "continuing at " << Ptr - DecodeTable << '\n');
}
break;
})";
@@ -2342,13 +2293,10 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
})";
if (HasTryDecode) {
OS << R"(
- case MCD::OPC_TryDecode:
- case MCD::OPC_TryDecodeOrFail: {
- bool IsFail = DecoderOp == MCD::OPC_TryDecodeOrFail;
+ case MCD::OPC_TryDecode: {
// Decode the Opcode value.
unsigned Opc = decodeULEB128AndIncUnsafe(Ptr);
unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
- unsigned NumToSkip = IsFail ? 0 : decodeNumToSkip(Ptr);
// Perform the decode operation.
MCInst TmpMI;
@@ -2365,13 +2313,12 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
return S;
}
assert(S == MCDisassembler::Fail);
- if (IsFail) {
- LLVM_DEBUG(dbgs() << "FAIL: returning FAIL\n");
+ if (ScopeStack.empty()) {
+ LLVM_DEBUG(dbgs() << "FAIL, returning FAIL\n");
return MCDisassembler::Fail;
}
- // If the decoding was incomplete, skip.
- Ptr += NumToSkip;
- LLVM_DEBUG(dbgs() << "FAIL: continuing at " << (Ptr - DecodeTable) << "\n");
+ Ptr = ScopeStack.pop_back_val();
+ LLVM_DEBUG(dbgs() << "FAIL, continuing at " << Ptr - DecodeTable << '\n');
// Reset decode status. This also drops a SoftFail status that could be
// set before the decode attempt.
S = MCDisassembler::Success;
@@ -2676,9 +2623,7 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
if (!SpecializeDecodersPerBitwidth)
emitDecoderFunction(OS, TableInfo.Decoders, 0);
- const bool HasCheckPredicate =
- OpcodeMask &
- ((1 << MCD::OPC_CheckPredicate) | (1 << MCD::OPC_CheckPredicateOrFail));
+ const bool HasCheckPredicate = OpcodeMask & (1 << MCD::OPC_CheckPredicate);
// Emit the predicate function.
if (HasCheckPredicate)
>From 5e938ccf494c04b3a1b948773377e14667a0d0e8 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Wed, 27 Aug 2025 12:42:31 +0300
Subject: [PATCH 2/2] Remove FixupStack entirely
---
llvm/utils/TableGen/DecoderEmitter.cpp | 20 ++++++--------------
1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 918426f012bae..24b0291215cdc 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -340,18 +340,8 @@ class DecoderTable {
struct DecoderTableInfo {
DecoderTable Table;
- SmallVector<unsigned, 8> FixupStack;
PredicateSet Predicates;
DecoderSet Decoders;
-
- void pushScope() {
- Table.insertOpcode(MCD::OPC_Scope);
- FixupStack.push_back(Table.insertNumToSkip());
- }
-
- void popScope() {
- Table.patchNumToSkip(FixupStack.pop_back_val(), Table.size());
- }
};
using NamespacesHwModesMap = std::map<StringRef, std::set<unsigned>>;
@@ -628,7 +618,6 @@ class DecoderTableBuilder {
if (SpecializeDecodersPerBitwidth)
TableInfo.Table.insertULEB128(BitWidth);
emitTableEntries(FC);
- assert(TableInfo.FixupStack.empty() && "Fixup stack phasing error!");
}
private:
@@ -1638,8 +1627,11 @@ void DecoderTableBuilder::emitTableEntries(const FilterChooser &FC) const {
// If there are other encodings that could match if those with all bits
// known don't, enter a scope so that they have a chance.
- if (FC.VariableFC)
- TableInfo.pushScope();
+ size_t FixupLoc = 0;
+ if (FC.VariableFC) {
+ Table.insertOpcode(MCD::OPC_Scope);
+ FixupLoc = Table.insertNumToSkip();
+ }
if (FC.SingletonEncodingID) {
assert(FC.FilterChooserMap.empty());
@@ -1688,7 +1680,7 @@ void DecoderTableBuilder::emitTableEntries(const FilterChooser &FC) const {
}
if (FC.VariableFC) {
- TableInfo.popScope();
+ Table.patchNumToSkip(FixupLoc, Table.size());
emitTableEntries(*FC.VariableFC);
}
}
More information about the llvm-commits
mailing list