32
32
#include " llvm/Support/CommandLine.h"
33
33
#include " llvm/Support/Debug.h"
34
34
#include " llvm/Support/ErrorHandling.h"
35
+ #include " llvm/Support/FormatVariadic.h"
35
36
#include " llvm/Support/FormattedStream.h"
36
37
#include " llvm/Support/LEB128.h"
38
+ #include " llvm/Support/MathExtras.h"
37
39
#include " llvm/Support/raw_ostream.h"
38
40
#include " llvm/TableGen/Error.h"
39
41
#include " llvm/TableGen/Record.h"
@@ -76,6 +78,12 @@ static cl::opt<SuppressLevel> DecoderEmitterSuppressDuplicates(
76
78
" significantly reducing Table Duplications" )),
77
79
cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat));
78
80
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
+
79
87
STATISTIC (NumEncodings, " Number of encodings considered" );
80
88
STATISTIC (NumEncodingsLackingDisasm,
81
89
" Number of encodings without disassembler info" );
@@ -130,9 +138,20 @@ struct DecoderTable : public std::vector<uint8_t> {
130
138
// in the table for patching.
131
139
size_t insertNumToSkip () {
132
140
size_t Size = size ();
133
- insert (end (), 3 , 0 );
141
+ insert (end (), NumToSkipSizeInBytes , 0 );
134
142
return Size;
135
143
}
144
+
145
+ void patchNumToSkip (size_t FixupIdx, uint32_t Value) {
146
+ if (!isUIntN (8 * NumToSkipSizeInBytes, Value))
147
+ PrintFatalError (
148
+ " disassembler decoding table too large, try --num-to-skip-size=3" );
149
+
150
+ (*this )[FixupIdx] = static_cast <uint8_t >(Value);
151
+ (*this )[FixupIdx + 1 ] = static_cast <uint8_t >(Value >> 8 );
152
+ if (NumToSkipSizeInBytes == 3 )
153
+ (*this )[FixupIdx + 2 ] = static_cast <uint8_t >(Value >> 16 );
154
+ }
136
155
};
137
156
struct DecoderTableInfo {
138
157
DecoderTable Table;
@@ -692,16 +711,11 @@ static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups,
692
711
// current location.
693
712
for (uint32_t FixupIdx : reverse (Fixups)) {
694
713
// 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 );
714
+ // to the destination. The Target is calculated from after the
715
+ // `NumToSkipSizeInBytes`-byte NumToSkip entry itself, so subtract
716
+ // `NumToSkipSizeInBytes` from the displacement here to account for that.
717
+ uint32_t Delta = DestIdx - FixupIdx - NumToSkipSizeInBytes;
718
+ Table.patchNumToSkip (FixupIdx, Delta);
705
719
}
706
720
}
707
721
@@ -760,13 +774,11 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
760
774
761
775
// Now that we've emitted the body of the handler, update the NumToSkip
762
776
// 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.
777
+ // `NumToSkipSizeInBytes` as to account for the width of the NumToSkip
778
+ // field itself.
764
779
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 );
780
+ uint32_t NumToSkip = Table.size () - PrevFilter - NumToSkipSizeInBytes;
781
+ Table.patchNumToSkip (PrevFilter, NumToSkip);
770
782
}
771
783
}
772
784
@@ -814,7 +826,8 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
814
826
OS << (unsigned )*I++ << " , " ;
815
827
};
816
828
817
- // Emit 24-bit numtoskip value to OS, returning the NumToSkip value.
829
+ // Emit `NumToSkipSizeInBytes`-byte numtoskip value to OS, returning the
830
+ // NumToSkip value.
818
831
auto emitNumToSkip = [](DecoderTable::const_iterator &I,
819
832
formatted_raw_ostream &OS) {
820
833
uint8_t Byte = *I++;
@@ -823,9 +836,11 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
823
836
Byte = *I++;
824
837
OS << (unsigned )Byte << " , " ;
825
838
NumToSkip |= Byte << 8 ;
826
- Byte = *I++;
827
- OS << (unsigned )(Byte) << " , " ;
828
- NumToSkip |= Byte << 16 ;
839
+ if (NumToSkipSizeInBytes == 3 ) {
840
+ Byte = *I++;
841
+ OS << (unsigned )(Byte) << " , " ;
842
+ NumToSkip |= Byte << 16 ;
843
+ }
829
844
return NumToSkip;
830
845
};
831
846
@@ -867,7 +882,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
867
882
// The filter value is ULEB128 encoded.
868
883
emitULEB128 (I, OS);
869
884
870
- // 24-bit numtoskip value.
885
+ // numtoskip value.
871
886
uint32_t NumToSkip = emitNumToSkip (I, OS);
872
887
OS << " // Skip to: " << ((I - Table.begin ()) + NumToSkip) << " \n " ;
873
888
break ;
@@ -883,7 +898,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
883
898
// ULEB128 encoded field value.
884
899
emitULEB128 (I, OS);
885
900
886
- // 24-bit numtoskip value.
901
+ // numtoskip value.
887
902
uint32_t NumToSkip = emitNumToSkip (I, OS);
888
903
OS << " // Skip to: " << ((I - Table.begin ()) + NumToSkip) << " \n " ;
889
904
break ;
@@ -893,7 +908,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
893
908
OS << Indent << " MCD::OPC_CheckPredicate, " ;
894
909
emitULEB128 (I, OS);
895
910
896
- // 24-bit numtoskip value.
911
+ // numtoskip value.
897
912
uint32_t NumToSkip = emitNumToSkip (I, OS);
898
913
OS << " // Skip to: " << ((I - Table.begin ()) + NumToSkip) << " \n " ;
899
914
break ;
@@ -925,7 +940,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
925
940
926
941
// Fallthrough for OPC_TryDecode.
927
942
928
- // 24-bit numtoskip value.
943
+ // numtoskip value.
929
944
uint32_t NumToSkip = emitNumToSkip (I, OS);
930
945
931
946
OS << " // Opcode: " << NumberedEncodings[EncodingID]
@@ -1411,9 +1426,9 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1411
1426
TableInfo.Table .push_back (NumBits);
1412
1427
TableInfo.Table .insertULEB128 (Ilnd.FieldVal );
1413
1428
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.
1429
+ // Allocate space in the table for fixup (NumToSkipSizeInBytes) so all
1430
+ // our relative position calculations work OK even before we fully
1431
+ // resolve the real value here.
1417
1432
1418
1433
// Push location for NumToSkip backpatching.
1419
1434
TableInfo.FixupStack .back ().push_back (TableInfo.Table .insertNumToSkip ());
@@ -2157,7 +2172,18 @@ insertBits(InsnType &field, uint64_t bits, unsigned startBit, unsigned numBits)
2157
2172
// decodeInstruction().
2158
2173
static void emitDecodeInstruction (formatted_raw_ostream &OS,
2159
2174
bool IsVarLenInst) {
2175
+ OS << formatv (" \n constexpr unsigned NumToSkipSizeInBytes = {};\n " ,
2176
+ NumToSkipSizeInBytes);
2177
+
2160
2178
OS << R"(
2179
+ inline unsigned decodeNumToSkip(const uint8_t *&Ptr) {
2180
+ unsigned NumToSkip = *Ptr++;
2181
+ NumToSkip |= (*Ptr++) << 8;
2182
+ if constexpr (NumToSkipSizeInBytes == 3)
2183
+ NumToSkip |= (*Ptr++) << 16;
2184
+ return NumToSkip;
2185
+ }
2186
+
2161
2187
template <typename InsnType>
2162
2188
static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2163
2189
InsnType insn, uint64_t Address,
@@ -2195,10 +2221,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2195
2221
// Decode the field value.
2196
2222
uint64_t Val = decodeULEB128AndIncUnsafe(++Ptr);
2197
2223
bool Failed = Val != CurFieldValue;
2198
- // NumToSkip is a plain 24-bit integer.
2199
- unsigned NumToSkip = *Ptr++;
2200
- NumToSkip |= (*Ptr++) << 8;
2201
- NumToSkip |= (*Ptr++) << 16;
2224
+ unsigned NumToSkip = decodeNumToSkip(Ptr);
2202
2225
2203
2226
// Perform the filter operation.
2204
2227
if (Failed)
@@ -2222,10 +2245,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2222
2245
uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen);
2223
2246
Ptr += PtrLen;
2224
2247
bool Failed = ExpectedValue != FieldValue;
2225
- // NumToSkip is a plain 24-bit integer.
2226
- unsigned NumToSkip = *Ptr++;
2227
- NumToSkip |= (*Ptr++) << 8;
2228
- NumToSkip |= (*Ptr++) << 16;
2248
+ unsigned NumToSkip = decodeNumToSkip(Ptr);
2229
2249
2230
2250
// If the actual and expected values don't match, skip.
2231
2251
if (Failed)
@@ -2240,10 +2260,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2240
2260
case MCD::OPC_CheckPredicate: {
2241
2261
// Decode the Predicate Index value.
2242
2262
unsigned PIdx = decodeULEB128AndIncUnsafe(++Ptr);
2243
- // NumToSkip is a plain 24-bit integer.
2244
- unsigned NumToSkip = *Ptr++;
2245
- NumToSkip |= (*Ptr++) << 8;
2246
- NumToSkip |= (*Ptr++) << 16;
2263
+ unsigned NumToSkip = decodeNumToSkip(Ptr);
2247
2264
// Check the predicate.
2248
2265
bool Failed = !checkDecoderPredicate(PIdx, Bits);
2249
2266
if (Failed)
@@ -2278,10 +2295,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2278
2295
// Decode the Opcode value.
2279
2296
unsigned Opc = decodeULEB128AndIncUnsafe(++Ptr);
2280
2297
unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
2281
- // NumToSkip is a plain 24-bit integer.
2282
- unsigned NumToSkip = *Ptr++;
2283
- NumToSkip |= (*Ptr++) << 8;
2284
- NumToSkip |= (*Ptr++) << 16;
2298
+ unsigned NumToSkip = decodeNumToSkip(Ptr);
2285
2299
2286
2300
// Perform the decode operation.
2287
2301
MCInst TmpMI;
@@ -2406,6 +2420,9 @@ handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
2406
2420
2407
2421
// Emits disassembler code for instruction decoding.
2408
2422
void DecoderEmitter::run (raw_ostream &o) {
2423
+ if (NumToSkipSizeInBytes != 2 && NumToSkipSizeInBytes != 3 )
2424
+ PrintFatalError (" Invalid value for num-to-skip-size, must be 2 or 3" );
2425
+
2409
2426
formatted_raw_ostream OS (o);
2410
2427
OS << R"(
2411
2428
#include "llvm/MC/MCInst.h"
0 commit comments