Skip to content

Commit dda3726

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

File tree

7 files changed

+83
-68
lines changed

7 files changed

+83
-68
lines changed

llvm/lib/Target/AArch64/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
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

llvm/test/TableGen/VarLenDecoder.td

Lines changed: 2 additions & 2 deletions
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

llvm/test/TableGen/trydecode-emission.td

Lines changed: 5 additions & 5 deletions
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; }

llvm/test/TableGen/trydecode-emission2.td

Lines changed: 8 additions & 8 deletions
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; }

llvm/test/TableGen/trydecode-emission3.td

Lines changed: 1 addition & 1 deletion
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

llvm/test/TableGen/trydecode-emission4.td

Lines changed: 1 addition & 1 deletion
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

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 65 additions & 50 deletions
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

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

869-
// 24-bit numtoskip value.
882+
// numtoskip value.
870883
uint32_t NumToSkip = emitNumToSkip(I, OS);
871884
OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
872885
break;
@@ -881,7 +894,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
881894
// ULEB128 encoded field value.
882895
emitULEB128(I, OS);
883896

884-
// 24-bit numtoskip value.
897+
// numtoskip value.
885898
uint32_t NumToSkip = emitNumToSkip(I, OS);
886899
OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
887900
break;
@@ -890,7 +903,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
890903
OS << Indent << "MCD::OPC_CheckPredicate, ";
891904
emitULEB128(I, OS);
892905

893-
// 24-bit numtoskip value.
906+
// numtoskip value.
894907
uint32_t NumToSkip = emitNumToSkip(I, OS);
895908
OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
896909
break;
@@ -920,7 +933,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
920933

921934
// Fallthrough for OPC_TryDecode.
922935

923-
// 24-bit numtoskip value.
936+
// numtoskip value.
924937
uint32_t NumToSkip = emitNumToSkip(I, OS);
925938

926939
OS << "// Opcode: " << NumberedEncodings[EncodingID]
@@ -1392,9 +1405,9 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
13921405
TableInfo.Table.push_back(NumBits);
13931406
TableInfo.Table.insertULEB128(Ilnd.FieldVal);
13941407

1395-
// The fixup is always 24-bits, so go ahead and allocate the space
1396-
// in the table so all our relative position calculations work OK even
1397-
// before we fully resolve the real value here.
1408+
// Allocate space in the table for fixup (NumToSkipSizeInBytes) so all
1409+
// our relative position calculations work OK even before we fully
1410+
// resolve the real value here.
13981411

13991412
// Push location for NumToSkip backpatching.
14001413
TableInfo.FixupStack.back().push_back(TableInfo.Table.insertNumToSkip());
@@ -2138,7 +2151,18 @@ insertBits(InsnType &field, uint64_t bits, unsigned startBit, unsigned numBits)
21382151
// decodeInstruction().
21392152
static void emitDecodeInstruction(formatted_raw_ostream &OS,
21402153
bool IsVarLenInst) {
2154+
OS << formatv("\nconstexpr unsigned NumToSkipSizeInBytes = {};\n",
2155+
NumToSkipSizeInBytes);
2156+
21412157
OS << R"(
2158+
inline unsigned decodeNumToSkip(const uint8_t *&Ptr) {
2159+
unsigned NumToSkip = *Ptr++;
2160+
NumToSkip |= (*Ptr++) << 8;
2161+
if constexpr (NumToSkipSizeInBytes == 3)
2162+
NumToSkip |= (*Ptr++) << 16;
2163+
return NumToSkip;
2164+
}
2165+
21422166
template <typename InsnType>
21432167
static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
21442168
InsnType insn, uint64_t Address,
@@ -2176,10 +2200,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
21762200
// Decode the field value.
21772201
uint64_t Val = decodeULEB128AndIncUnsafe(Ptr);
21782202
bool Failed = Val != CurFieldValue;
2179-
// NumToSkip is a plain 24-bit integer.
2180-
unsigned NumToSkip = *Ptr++;
2181-
NumToSkip |= (*Ptr++) << 8;
2182-
NumToSkip |= (*Ptr++) << 16;
2203+
unsigned NumToSkip = decodeNumToSkip(Ptr);
21832204
21842205
// Perform the filter operation.
21852206
if (Failed)
@@ -2203,10 +2224,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
22032224
uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen);
22042225
Ptr += PtrLen;
22052226
bool Failed = ExpectedValue != FieldValue;
2206-
// NumToSkip is a plain 24-bit integer.
2207-
unsigned NumToSkip = *Ptr++;
2208-
NumToSkip |= (*Ptr++) << 8;
2209-
NumToSkip |= (*Ptr++) << 16;
2227+
unsigned NumToSkip = decodeNumToSkip(Ptr);
22102228
22112229
// If the actual and expected values don't match, skip.
22122230
if (Failed)
@@ -2221,10 +2239,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
22212239
case MCD::OPC_CheckPredicate: {
22222240
// Decode the Predicate Index value.
22232241
unsigned PIdx = decodeULEB128AndIncUnsafe(Ptr);
2224-
// NumToSkip is a plain 24-bit integer.
2225-
unsigned NumToSkip = *Ptr++;
2226-
NumToSkip |= (*Ptr++) << 8;
2227-
NumToSkip |= (*Ptr++) << 16;
2242+
unsigned NumToSkip = decodeNumToSkip(Ptr);
22282243
// Check the predicate.
22292244
bool Failed = !checkDecoderPredicate(PIdx, Bits);
22302245
if (Failed)
@@ -2259,10 +2274,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
22592274
// Decode the Opcode value.
22602275
unsigned Opc = decodeULEB128AndIncUnsafe(Ptr);
22612276
unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
2262-
// NumToSkip is a plain 24-bit integer.
2263-
unsigned NumToSkip = *Ptr++;
2264-
NumToSkip |= (*Ptr++) << 8;
2265-
NumToSkip |= (*Ptr++) << 16;
2277+
unsigned NumToSkip = decodeNumToSkip(Ptr);
22662278
22672279
// Perform the decode operation.
22682280
MCInst TmpMI;
@@ -2387,6 +2399,9 @@ handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
23872399

23882400
// Emits disassembler code for instruction decoding.
23892401
void DecoderEmitter::run(raw_ostream &o) {
2402+
if (NumToSkipSizeInBytes != 2 && NumToSkipSizeInBytes != 3)
2403+
PrintFatalError("Invalid value for num-to-skip-size, must be 2 or 3");
2404+
23902405
formatted_raw_ostream OS(o);
23912406
OS << R"(
23922407
#include "llvm/MC/MCInst.h"

0 commit comments

Comments
 (0)