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+
7987STATISTIC (NumEncodings, " Number of encodings considered" );
8088STATISTIC (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+
137164struct 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().
21392152static void emitDecodeInstruction (formatted_raw_ostream &OS,
21402153 bool IsVarLenInst) {
2154+ OS << formatv (" \n constexpr 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+
21422166template <typename InsnType>
21432167static 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.
23892401void 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