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,10 +138,29 @@ 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 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
+ }
136
162
};
163
+
137
164
struct DecoderTableInfo {
138
165
DecoderTable Table;
139
166
FixupScopeList FixupStack;
@@ -690,19 +717,8 @@ static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups,
690
717
uint32_t DestIdx) {
691
718
// Any NumToSkip fixups in the current scope can resolve to the
692
719
// 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);
706
722
}
707
723
708
724
// Emit table entries to decode instructions given a segment or segments
@@ -759,15 +775,9 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
759
775
Delegate->emitTableEntries (TableInfo);
760
776
761
777
// 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 ());
771
781
}
772
782
773
783
// 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,
814
824
OS << (unsigned )*I++ << " , " ;
815
825
};
816
826
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.
818
829
auto emitNumToSkip = [](DecoderTable::const_iterator &I,
819
830
formatted_raw_ostream &OS) {
820
831
uint8_t Byte = *I++;
@@ -823,9 +834,11 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
823
834
Byte = *I++;
824
835
OS << (unsigned )Byte << " , " ;
825
836
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
+ }
829
842
return NumToSkip;
830
843
};
831
844
@@ -866,7 +879,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
866
879
// The filter value is ULEB128 encoded.
867
880
emitULEB128 (I, OS);
868
881
869
- // 24-bit numtoskip value.
882
+ // numtoskip value.
870
883
uint32_t NumToSkip = emitNumToSkip (I, OS);
871
884
OS << " // Skip to: " << ((I - Table.begin ()) + NumToSkip) << " \n " ;
872
885
break ;
@@ -881,7 +894,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
881
894
// ULEB128 encoded field value.
882
895
emitULEB128 (I, OS);
883
896
884
- // 24-bit numtoskip value.
897
+ // numtoskip value.
885
898
uint32_t NumToSkip = emitNumToSkip (I, OS);
886
899
OS << " // Skip to: " << ((I - Table.begin ()) + NumToSkip) << " \n " ;
887
900
break ;
@@ -890,7 +903,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
890
903
OS << Indent << " MCD::OPC_CheckPredicate, " ;
891
904
emitULEB128 (I, OS);
892
905
893
- // 24-bit numtoskip value.
906
+ // numtoskip value.
894
907
uint32_t NumToSkip = emitNumToSkip (I, OS);
895
908
OS << " // Skip to: " << ((I - Table.begin ()) + NumToSkip) << " \n " ;
896
909
break ;
@@ -920,7 +933,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
920
933
921
934
// Fallthrough for OPC_TryDecode.
922
935
923
- // 24-bit numtoskip value.
936
+ // numtoskip value.
924
937
uint32_t NumToSkip = emitNumToSkip (I, OS);
925
938
926
939
OS << " // Opcode: " << NumberedEncodings[EncodingID]
@@ -1392,9 +1405,9 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1392
1405
TableInfo.Table .push_back (NumBits);
1393
1406
TableInfo.Table .insertULEB128 (Ilnd.FieldVal );
1394
1407
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.
1398
1411
1399
1412
// Push location for NumToSkip backpatching.
1400
1413
TableInfo.FixupStack .back ().push_back (TableInfo.Table .insertNumToSkip ());
@@ -2138,7 +2151,18 @@ insertBits(InsnType &field, uint64_t bits, unsigned startBit, unsigned numBits)
2138
2151
// decodeInstruction().
2139
2152
static void emitDecodeInstruction (formatted_raw_ostream &OS,
2140
2153
bool IsVarLenInst) {
2154
+ OS << formatv (" \n constexpr unsigned NumToSkipSizeInBytes = {};\n " ,
2155
+ NumToSkipSizeInBytes);
2156
+
2141
2157
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
+
2142
2166
template <typename InsnType>
2143
2167
static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2144
2168
InsnType insn, uint64_t Address,
@@ -2176,10 +2200,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2176
2200
// Decode the field value.
2177
2201
uint64_t Val = decodeULEB128AndIncUnsafe(Ptr);
2178
2202
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);
2183
2204
2184
2205
// Perform the filter operation.
2185
2206
if (Failed)
@@ -2203,10 +2224,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2203
2224
uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen);
2204
2225
Ptr += PtrLen;
2205
2226
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);
2210
2228
2211
2229
// If the actual and expected values don't match, skip.
2212
2230
if (Failed)
@@ -2221,10 +2239,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2221
2239
case MCD::OPC_CheckPredicate: {
2222
2240
// Decode the Predicate Index value.
2223
2241
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);
2228
2243
// Check the predicate.
2229
2244
bool Failed = !checkDecoderPredicate(PIdx, Bits);
2230
2245
if (Failed)
@@ -2259,10 +2274,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2259
2274
// Decode the Opcode value.
2260
2275
unsigned Opc = decodeULEB128AndIncUnsafe(Ptr);
2261
2276
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);
2266
2278
2267
2279
// Perform the decode operation.
2268
2280
MCInst TmpMI;
@@ -2387,6 +2399,9 @@ handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
2387
2399
2388
2400
// Emits disassembler code for instruction decoding.
2389
2401
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
+
2390
2405
formatted_raw_ostream OS (o);
2391
2406
OS << R"(
2392
2407
#include "llvm/MC/MCInst.h"
0 commit comments