Skip to content

Commit 23490c7

Browse files
committed
Reapply "Reapply "[LLVM][TableGen] Parameterize NumToSkip in DecoderEmitter" (llvm#136017)" (llvm#136068)
This reverts commit 6d8bf3c.
1 parent 6d8bf3c commit 23490c7

File tree

7 files changed

+83
-68
lines changed

7 files changed

+83
-68
lines changed

Diff for: llvm/lib/Target/AArch64/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tablegen(LLVM AArch64GenAsmWriter.inc -gen-asm-writer)
77
tablegen(LLVM AArch64GenAsmWriter1.inc -gen-asm-writer -asmwriternum=1)
88
tablegen(LLVM AArch64GenCallingConv.inc -gen-callingconv)
99
tablegen(LLVM AArch64GenDAGISel.inc -gen-dag-isel)
10-
tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
10+
tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler --num-to-skip-size=3)
1111
tablegen(LLVM AArch64GenFastISel.inc -gen-fast-isel)
1212
tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel)
1313
tablegen(LLVM AArch64GenO0PreLegalizeGICombiner.inc -gen-global-isel-combiner

Diff for: llvm/test/TableGen/VarLenDecoder.td

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ def FOO32 : MyVarInst<MemOp32> {
4747
}
4848

4949
// CHECK: MCD::OPC_ExtractField, 3, 5, // Inst{7-3} ...
50-
// CHECK-NEXT: MCD::OPC_FilterValue, 8, 4, 0, 0, // Skip to: 12
50+
// CHECK-NEXT: MCD::OPC_FilterValue, 8, 4, 0, // Skip to: 11
5151
// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16
52-
// CHECK-NEXT: MCD::OPC_FilterValue, 9, 4, 0, 0, // Skip to: 21
52+
// CHECK-NEXT: MCD::OPC_FilterValue, 9, 4, 0, // Skip to: 19
5353
// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
5454
// CHECK-NEXT: MCD::OPC_Fail,
5555

Diff for: llvm/test/TableGen/trydecode-emission.td

+5-5
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ def InstB : TestInstruction {
3434
}
3535

3636
// CHECK: /* 0 */ MCD::OPC_ExtractField, 4, 4, // Inst{7-4} ...
37-
// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 18, 0, 0, // Skip to: 26
38-
// CHECK-NEXT: /* 8 */ MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 22
39-
// CHECK-NEXT: /* 15 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, skip to: 22
40-
// CHECK-NEXT: /* 22 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
41-
// CHECK-NEXT: /* 26 */ MCD::OPC_Fail,
37+
// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 16, 0, // Skip to: 23
38+
// CHECK-NEXT: /* 7 */ MCD::OPC_CheckField, 2, 2, 0, 6, 0, // Skip to: 19
39+
// CHECK-NEXT: /* 13 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, skip to: 19
40+
// CHECK-NEXT: /* 19 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
41+
// CHECK-NEXT: /* 23 */ MCD::OPC_Fail,
4242

4343
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }

Diff for: llvm/test/TableGen/trydecode-emission2.td

+8-8
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ def InstB : TestInstruction {
3131
}
3232

3333
// CHECK: /* 0 */ MCD::OPC_ExtractField, 2, 1, // Inst{2} ...
34-
// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 36, 0, 0, // Skip to: 44
35-
// CHECK-NEXT: /* 8 */ MCD::OPC_ExtractField, 5, 3, // Inst{7-5} ...
36-
// CHECK-NEXT: /* 11 */ MCD::OPC_FilterValue, 0, 28, 0, 0, // Skip to: 44
37-
// CHECK-NEXT: /* 16 */ MCD::OPC_CheckField, 0, 2, 3, 7, 0, 0, // Skip to: 30
38-
// CHECK-NEXT: /* 23 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, skip to: 30
39-
// CHECK-NEXT: /* 30 */ MCD::OPC_CheckField, 3, 2, 0, 7, 0, 0, // Skip to: 44
40-
// CHECK-NEXT: /* 37 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1, 0, 0, 0, // Opcode: InstA, skip to: 44
41-
// CHECK-NEXT: /* 44 */ MCD::OPC_Fail,
34+
// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 31, 0, // Skip to: 38
35+
// CHECK-NEXT: /* 7 */ MCD::OPC_ExtractField, 5, 3, // Inst{7-5} ...
36+
// CHECK-NEXT: /* 10 */ MCD::OPC_FilterValue, 0, 24, 0, // Skip to: 38
37+
// CHECK-NEXT: /* 14 */ MCD::OPC_CheckField, 0, 2, 3, 6, 0, // Skip to: 26
38+
// CHECK-NEXT: /* 20 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, skip to: 26
39+
// CHECK-NEXT: /* 26 */ MCD::OPC_CheckField, 3, 2, 0, 6, 0, // Skip to: 38
40+
// CHECK-NEXT: /* 32 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1, 0, 0, // Opcode: InstA, skip to: 38
41+
// CHECK-NEXT: /* 38 */ MCD::OPC_Fail,
4242

4343
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
4444
// CHECK: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }

Diff for: llvm/test/TableGen/trydecode-emission3.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | FileCheck %s
1+
// RUN: llvm-tblgen -gen-disassembler --num-to-skip-size=3 -I %p/../../include %s | FileCheck %s
22

33
include "llvm/Target/Target.td"
44

Diff for: llvm/test/TableGen/trydecode-emission4.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | FileCheck %s
1+
// RUN: llvm-tblgen -gen-disassembler --num-to-skip-size=3 -I %p/../../include %s | FileCheck %s
22

33
// Test for OPC_ExtractField/OPC_CheckField with start bit > 255.
44
// These large start values may arise for architectures with long instruction

Diff for: llvm/utils/TableGen/DecoderEmitter.cpp

+65-50
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@
3232
#include "llvm/Support/CommandLine.h"
3333
#include "llvm/Support/Debug.h"
3434
#include "llvm/Support/ErrorHandling.h"
35+
#include "llvm/Support/FormatVariadic.h"
3536
#include "llvm/Support/FormattedStream.h"
3637
#include "llvm/Support/LEB128.h"
38+
#include "llvm/Support/MathExtras.h"
3739
#include "llvm/Support/raw_ostream.h"
3840
#include "llvm/TableGen/Error.h"
3941
#include "llvm/TableGen/Record.h"
@@ -76,6 +78,12 @@ static cl::opt<SuppressLevel> DecoderEmitterSuppressDuplicates(
7678
"significantly reducing Table Duplications")),
7779
cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat));
7880

81+
static cl::opt<uint32_t>
82+
NumToSkipSizeInBytes("num-to-skip-size",
83+
cl::desc("number of bytes to use for num-to-skip "
84+
"entries in the decoder table (2 or 3)"),
85+
cl::init(2), cl::cat(DisassemblerEmitterCat));
86+
7987
STATISTIC(NumEncodings, "Number of encodings considered");
8088
STATISTIC(NumEncodingsLackingDisasm,
8189
"Number of encodings without disassembler info");
@@ -130,10 +138,29 @@ struct DecoderTable : public std::vector<uint8_t> {
130138
// in the table for patching.
131139
size_t insertNumToSkip() {
132140
size_t Size = size();
133-
insert(end(), 3, 0);
141+
insert(end(), NumToSkipSizeInBytes, 0);
134142
return Size;
135143
}
144+
145+
void patchNumToSkip(size_t FixupIdx, uint32_t DestIdx) {
146+
// Calculate the distance from the byte following the fixup entry byte
147+
// to the destination. The Target is calculated from after the
148+
// `NumToSkipSizeInBytes`-byte NumToSkip entry itself, so subtract
149+
// `NumToSkipSizeInBytes` from the displacement here to account for that.
150+
assert(DestIdx >= FixupIdx + NumToSkipSizeInBytes &&
151+
"Expecting a forward jump in the decoding table");
152+
uint32_t Delta = DestIdx - FixupIdx - NumToSkipSizeInBytes;
153+
if (!isUIntN(8 * NumToSkipSizeInBytes, Delta))
154+
PrintFatalError(
155+
"disassembler decoding table too large, try --num-to-skip-size=3");
156+
157+
(*this)[FixupIdx] = static_cast<uint8_t>(Delta);
158+
(*this)[FixupIdx + 1] = static_cast<uint8_t>(Delta >> 8);
159+
if (NumToSkipSizeInBytes == 3)
160+
(*this)[FixupIdx + 2] = static_cast<uint8_t>(Delta >> 16);
161+
}
136162
};
163+
137164
struct DecoderTableInfo {
138165
DecoderTable Table;
139166
FixupScopeList FixupStack;
@@ -690,19 +717,8 @@ static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups,
690717
uint32_t DestIdx) {
691718
// Any NumToSkip fixups in the current scope can resolve to the
692719
// current location.
693-
for (uint32_t FixupIdx : reverse(Fixups)) {
694-
// Calculate the distance from the byte following the fixup entry byte
695-
// to the destination. The Target is calculated from after the 24-bit
696-
// NumToSkip entry itself, so subtract three from the displacement here
697-
// to account for that.
698-
uint32_t Delta = DestIdx - FixupIdx - 3;
699-
// Our NumToSkip entries are 24-bits. Make sure our table isn't too
700-
// big.
701-
assert(isUInt<24>(Delta));
702-
Table[FixupIdx] = (uint8_t)Delta;
703-
Table[FixupIdx + 1] = (uint8_t)(Delta >> 8);
704-
Table[FixupIdx + 2] = (uint8_t)(Delta >> 16);
705-
}
720+
for (uint32_t FixupIdx : Fixups)
721+
Table.patchNumToSkip(FixupIdx, DestIdx);
706722
}
707723

708724
// Emit table entries to decode instructions given a segment or segments
@@ -759,15 +775,9 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
759775
Delegate->emitTableEntries(TableInfo);
760776

761777
// Now that we've emitted the body of the handler, update the NumToSkip
762-
// of the filter itself to be able to skip forward when false. Subtract
763-
// three as to account for the width of the NumToSkip field itself.
764-
if (PrevFilter) {
765-
uint32_t NumToSkip = Table.size() - PrevFilter - 3;
766-
assert(isUInt<24>(NumToSkip) && "disassembler decoding table too large!");
767-
Table[PrevFilter] = (uint8_t)NumToSkip;
768-
Table[PrevFilter + 1] = (uint8_t)(NumToSkip >> 8);
769-
Table[PrevFilter + 2] = (uint8_t)(NumToSkip >> 16);
770-
}
778+
// of the filter itself to be able to skip forward when false.
779+
if (PrevFilter)
780+
Table.patchNumToSkip(PrevFilter, Table.size());
771781
}
772782

773783
// If there is no fallthrough, then the final filter should get fixed
@@ -814,7 +824,8 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
814824
OS << (unsigned)*I++ << ", ";
815825
};
816826

817-
// Emit 24-bit numtoskip value to OS, returning the NumToSkip value.
827+
// Emit `NumToSkipSizeInBytes`-byte numtoskip value to OS, returning the
828+
// NumToSkip value.
818829
auto emitNumToSkip = [](DecoderTable::const_iterator &I,
819830
formatted_raw_ostream &OS) {
820831
uint8_t Byte = *I++;
@@ -823,9 +834,11 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
823834
Byte = *I++;
824835
OS << (unsigned)Byte << ", ";
825836
NumToSkip |= Byte << 8;
826-
Byte = *I++;
827-
OS << (unsigned)(Byte) << ", ";
828-
NumToSkip |= Byte << 16;
837+
if (NumToSkipSizeInBytes == 3) {
838+
Byte = *I++;
839+
OS << (unsigned)(Byte) << ", ";
840+
NumToSkip |= Byte << 16;
841+
}
829842
return NumToSkip;
830843
};
831844

@@ -867,7 +880,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
867880
// The filter value is ULEB128 encoded.
868881
emitULEB128(I, OS);
869882

870-
// 24-bit numtoskip value.
883+
// numtoskip value.
871884
uint32_t NumToSkip = emitNumToSkip(I, OS);
872885
OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
873886
break;
@@ -883,7 +896,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
883896
// ULEB128 encoded field value.
884897
emitULEB128(I, OS);
885898

886-
// 24-bit numtoskip value.
899+
// numtoskip value.
887900
uint32_t NumToSkip = emitNumToSkip(I, OS);
888901
OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
889902
break;
@@ -893,7 +906,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
893906
OS << Indent << "MCD::OPC_CheckPredicate, ";
894907
emitULEB128(I, OS);
895908

896-
// 24-bit numtoskip value.
909+
// numtoskip value.
897910
uint32_t NumToSkip = emitNumToSkip(I, OS);
898911
OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
899912
break;
@@ -925,7 +938,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
925938

926939
// Fallthrough for OPC_TryDecode.
927940

928-
// 24-bit numtoskip value.
941+
// numtoskip value.
929942
uint32_t NumToSkip = emitNumToSkip(I, OS);
930943

931944
OS << "// Opcode: " << NumberedEncodings[EncodingID]
@@ -1411,9 +1424,9 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
14111424
TableInfo.Table.push_back(NumBits);
14121425
TableInfo.Table.insertULEB128(Ilnd.FieldVal);
14131426

1414-
// The fixup is always 24-bits, so go ahead and allocate the space
1415-
// in the table so all our relative position calculations work OK even
1416-
// before we fully resolve the real value here.
1427+
// Allocate space in the table for fixup (NumToSkipSizeInBytes) so all
1428+
// our relative position calculations work OK even before we fully
1429+
// resolve the real value here.
14171430

14181431
// Push location for NumToSkip backpatching.
14191432
TableInfo.FixupStack.back().push_back(TableInfo.Table.insertNumToSkip());
@@ -2157,7 +2170,18 @@ insertBits(InsnType &field, uint64_t bits, unsigned startBit, unsigned numBits)
21572170
// decodeInstruction().
21582171
static void emitDecodeInstruction(formatted_raw_ostream &OS,
21592172
bool IsVarLenInst) {
2173+
OS << formatv("\nconstexpr unsigned NumToSkipSizeInBytes = {};\n",
2174+
NumToSkipSizeInBytes);
2175+
21602176
OS << R"(
2177+
inline unsigned decodeNumToSkip(const uint8_t *&Ptr) {
2178+
unsigned NumToSkip = *Ptr++;
2179+
NumToSkip |= (*Ptr++) << 8;
2180+
if constexpr (NumToSkipSizeInBytes == 3)
2181+
NumToSkip |= (*Ptr++) << 16;
2182+
return NumToSkip;
2183+
}
2184+
21612185
template <typename InsnType>
21622186
static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
21632187
InsnType insn, uint64_t Address,
@@ -2195,10 +2219,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
21952219
// Decode the field value.
21962220
uint64_t Val = decodeULEB128AndIncUnsafe(++Ptr);
21972221
bool Failed = Val != CurFieldValue;
2198-
// NumToSkip is a plain 24-bit integer.
2199-
unsigned NumToSkip = *Ptr++;
2200-
NumToSkip |= (*Ptr++) << 8;
2201-
NumToSkip |= (*Ptr++) << 16;
2222+
unsigned NumToSkip = decodeNumToSkip(Ptr);
22022223
22032224
// Perform the filter operation.
22042225
if (Failed)
@@ -2222,10 +2243,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
22222243
uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen);
22232244
Ptr += PtrLen;
22242245
bool Failed = ExpectedValue != FieldValue;
2225-
// NumToSkip is a plain 24-bit integer.
2226-
unsigned NumToSkip = *Ptr++;
2227-
NumToSkip |= (*Ptr++) << 8;
2228-
NumToSkip |= (*Ptr++) << 16;
2246+
unsigned NumToSkip = decodeNumToSkip(Ptr);
22292247
22302248
// If the actual and expected values don't match, skip.
22312249
if (Failed)
@@ -2240,10 +2258,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
22402258
case MCD::OPC_CheckPredicate: {
22412259
// Decode the Predicate Index value.
22422260
unsigned PIdx = decodeULEB128AndIncUnsafe(++Ptr);
2243-
// NumToSkip is a plain 24-bit integer.
2244-
unsigned NumToSkip = *Ptr++;
2245-
NumToSkip |= (*Ptr++) << 8;
2246-
NumToSkip |= (*Ptr++) << 16;
2261+
unsigned NumToSkip = decodeNumToSkip(Ptr);
22472262
// Check the predicate.
22482263
bool Failed = !checkDecoderPredicate(PIdx, Bits);
22492264
if (Failed)
@@ -2278,10 +2293,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
22782293
// Decode the Opcode value.
22792294
unsigned Opc = decodeULEB128AndIncUnsafe(++Ptr);
22802295
unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
2281-
// NumToSkip is a plain 24-bit integer.
2282-
unsigned NumToSkip = *Ptr++;
2283-
NumToSkip |= (*Ptr++) << 8;
2284-
NumToSkip |= (*Ptr++) << 16;
2296+
unsigned NumToSkip = decodeNumToSkip(Ptr);
22852297
22862298
// Perform the decode operation.
22872299
MCInst TmpMI;
@@ -2406,6 +2418,9 @@ handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
24062418

24072419
// Emits disassembler code for instruction decoding.
24082420
void DecoderEmitter::run(raw_ostream &o) {
2421+
if (NumToSkipSizeInBytes != 2 && NumToSkipSizeInBytes != 3)
2422+
PrintFatalError("Invalid value for num-to-skip-size, must be 2 or 3");
2423+
24092424
formatted_raw_ostream OS(o);
24102425
OS << R"(
24112426
#include "llvm/MC/MCInst.h"

0 commit comments

Comments
 (0)