@@ -222,11 +222,11 @@ class DecoderEmitter {
222222 DecoderEmitter (const RecordKeeper &R, StringRef PredicateNamespace)
223223 : RK(R), Target(R), PredicateNamespace(PredicateNamespace) {}
224224
225- // Emit the decoder state machine table. Return true if any `TryDecode` ops
226- // were generated .
227- bool emitTable (formatted_raw_ostream &OS, DecoderTable &Table, indent Indent ,
228- unsigned BitWidth, StringRef Namespace,
229- const EncodingIDsVec &EncodingIDs) const ;
225+ // Emit the decoder state machine table. Returns a mask of MCD decoder ops
226+ // that were emitted .
227+ unsigned emitTable (formatted_raw_ostream &OS, DecoderTable &Table,
228+ indent Indent, unsigned BitWidth, StringRef Namespace,
229+ const EncodingIDsVec &EncodingIDs) const ;
230230 void emitInstrLenTable (formatted_raw_ostream &OS,
231231 ArrayRef<unsigned > InstrLen) const ;
232232 void emitPredicateFunction (formatted_raw_ostream &OS,
@@ -827,11 +827,12 @@ unsigned Filter::usefulness() const {
827827// //
828828// ////////////////////////////////
829829
830- // Emit the decoder state machine table.
831- bool DecoderEmitter::emitTable (formatted_raw_ostream &OS, DecoderTable &Table,
832- indent Indent, unsigned BitWidth,
833- StringRef Namespace,
834- const EncodingIDsVec &EncodingIDs) const {
830+ // Emit the decoder state machine table. Returns a mask of MCD decoder ops
831+ // that were emitted.
832+ unsigned DecoderEmitter::emitTable (formatted_raw_ostream &OS,
833+ DecoderTable &Table, indent Indent,
834+ unsigned BitWidth, StringRef Namespace,
835+ const EncodingIDsVec &EncodingIDs) const {
835836 // We'll need to be able to map from a decoded opcode into the corresponding
836837 // EncodingID for this specific combination of BitWidth and Namespace. This
837838 // is used below to index into NumberedEncodings.
@@ -885,7 +886,7 @@ bool DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
885886 OS << " (Fail)" ;
886887 };
887888
888- bool HasTryDecode = false ;
889+ unsigned OpcodeMask = 0 ;
889890
890891 while (I != E) {
891892 assert (I < E && " incomplete decode table entry!" );
@@ -895,6 +896,7 @@ bool DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
895896 OS.PadToColumn (12 );
896897
897898 const uint8_t DecoderOp = *I++;
899+ OpcodeMask |= (1 << DecoderOp);
898900 switch (DecoderOp) {
899901 default :
900902 PrintFatalError (" Invalid decode table opcode: " + Twine ((int )DecoderOp) +
@@ -967,7 +969,6 @@ bool DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
967969 case MCD::OPC_TryDecodeOrFail: {
968970 bool IsFail = DecoderOp == MCD::OPC_TryDecodeOrFail;
969971 bool IsTry = DecoderOp == MCD::OPC_TryDecode || IsFail;
970- HasTryDecode |= IsTry;
971972 // Decode the Opcode value.
972973 const char *ErrMsg = nullptr ;
973974 unsigned Opc = decodeULEB128 (&*I, nullptr , EndPtr, &ErrMsg);
@@ -1032,7 +1033,7 @@ bool DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
10321033
10331034 OS << Indent << " };\n\n " ;
10341035
1035- return HasTryDecode ;
1036+ return OpcodeMask ;
10361037}
10371038
10381039void DecoderEmitter::emitInstrLenTable (formatted_raw_ostream &OS,
@@ -2224,7 +2225,14 @@ static void insertBits(InsnType &field, InsnType bits, unsigned startBit,
22242225// emitDecodeInstruction - Emit the templated helper function
22252226// decodeInstruction().
22262227static void emitDecodeInstruction (formatted_raw_ostream &OS, bool IsVarLenInst,
2227- bool HasTryDecode) {
2228+ unsigned OpcodeMask) {
2229+ const bool HasTryDecode = OpcodeMask & ((1 << MCD::OPC_TryDecode) |
2230+ (1 << MCD::OPC_TryDecodeOrFail));
2231+ const bool HasCheckPredicate =
2232+ OpcodeMask &
2233+ ((1 << MCD::OPC_CheckPredicate) | (1 << MCD::OPC_CheckPredicateOrFail));
2234+ const bool HasSoftFail = OpcodeMask & (1 << MCD::OPC_SoftFail);
2235+
22282236 OS << R"(
22292237static unsigned decodeNumToSkip(const uint8_t *&Ptr) {
22302238 unsigned NumToSkip = *Ptr++;
@@ -2244,9 +2252,11 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
22442252 OS << " ,\n "
22452253 " llvm::function_ref<void(APInt &, uint64_t)> makeUp" ;
22462254 }
2247- OS << R"( ) {
2248- const FeatureBitset &Bits = STI.getFeatureBits();
2255+ OS << " ) {\n " ;
2256+ if (HasCheckPredicate)
2257+ OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n " ;
22492258
2259+ OS << R"(
22502260 const uint8_t *Ptr = DecodeTable;
22512261 uint64_t CurFieldValue = 0;
22522262 DecodeStatus S = MCDisassembler::Success;
@@ -2327,7 +2337,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
23272337 Ptr += NumToSkip;
23282338 }
23292339 break;
2330- }
2340+ })" ;
2341+ if (HasCheckPredicate) {
2342+ OS << R"(
23312343 case MCD::OPC_CheckPredicate:
23322344 case MCD::OPC_CheckPredicateOrFail: {
23332345 bool IsFail = DecoderOp == MCD::OPC_CheckPredicateOrFail;
@@ -2349,7 +2361,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
23492361 Ptr += NumToSkip;
23502362 }
23512363 break;
2352- }
2364+ })" ;
2365+ }
2366+ OS << R"(
23532367 case MCD::OPC_Decode: {
23542368 // Decode the Opcode value.
23552369 unsigned Opc = decodeULEB128AndIncUnsafe(Ptr);
@@ -2409,17 +2423,20 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
24092423 break;
24102424 })" ;
24112425 }
2426+ if (HasSoftFail) {
2427+ OS << R"(
2428+ case MCD::OPC_SoftFail: {
2429+ // Decode the mask values.
2430+ uint64_t PositiveMask = decodeULEB128AndIncUnsafe(Ptr);
2431+ uint64_t NegativeMask = decodeULEB128AndIncUnsafe(Ptr);
2432+ bool Failed = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0;
2433+ if (Failed)
2434+ S = MCDisassembler::SoftFail;
2435+ LLVM_DEBUG(dbgs() << Loc << ": OPC_SoftFail: " << (Failed ? "FAIL\n" : "PASS\n"));
2436+ break;
2437+ })" ;
2438+ }
24122439 OS << R"(
2413- case MCD::OPC_SoftFail: {
2414- // Decode the mask values.
2415- uint64_t PositiveMask = decodeULEB128AndIncUnsafe(Ptr);
2416- uint64_t NegativeMask = decodeULEB128AndIncUnsafe(Ptr);
2417- bool Failed = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0;
2418- if (Failed)
2419- S = MCDisassembler::SoftFail;
2420- LLVM_DEBUG(dbgs() << Loc << ": OPC_SoftFail: " << (Failed ? "FAIL\n" : "PASS\n"));
2421- break;
2422- }
24232440 case MCD::OPC_Fail: {
24242441 LLVM_DEBUG(dbgs() << Loc << ": OPC_Fail\n");
24252442 return MCDisassembler::Fail;
@@ -2619,7 +2636,7 @@ namespace {
26192636 }
26202637
26212638 DecoderTableInfo TableInfo;
2622- bool HasTryDecode = false ;
2639+ unsigned OpcodeMask = 0 ;
26232640 for (const auto &Opc : OpcMap) {
26242641 // Emit the decoder for this namespace+width combination.
26252642 ArrayRef<EncodingAndInst> NumberedEncodingsRef (NumberedEncodings.data (),
@@ -2645,23 +2662,29 @@ namespace {
26452662 TableInfo.Table .push_back (MCD::OPC_Fail);
26462663
26472664 // Print the table to the output stream.
2648- HasTryDecode |= emitTable (OS, TableInfo.Table , indent (0 ), FC.getBitWidth (),
2649- Opc.first .first , Opc.second );
2665+ OpcodeMask |= emitTable (OS, TableInfo.Table , indent (0 ), FC.getBitWidth (),
2666+ Opc.first .first , Opc.second );
26502667 }
26512668
26522669 // For variable instruction, we emit a instruction length table
26532670 // to let the decoder know how long the instructions are.
26542671 // You can see example usage in M68k's disassembler.
26552672 if (IsVarLenInst)
26562673 emitInstrLenTable (OS, InstrLen);
2674+
2675+ const bool HasCheckPredicate =
2676+ OpcodeMask &
2677+ ((1 << MCD::OPC_CheckPredicate) | (1 << MCD::OPC_CheckPredicateOrFail));
2678+
26572679 // Emit the predicate function.
2658- emitPredicateFunction (OS, TableInfo.Predicates , indent (0 ));
2680+ if (HasCheckPredicate)
2681+ emitPredicateFunction (OS, TableInfo.Predicates , indent (0 ));
26592682
26602683 // Emit the decoder function.
26612684 emitDecoderFunction (OS, TableInfo.Decoders , indent (0 ));
26622685
26632686 // Emit the main entry point for the decoder, decodeInstruction().
2664- emitDecodeInstruction (OS, IsVarLenInst, HasTryDecode );
2687+ emitDecodeInstruction (OS, IsVarLenInst, OpcodeMask );
26652688
26662689 OS << " \n } // namespace\n " ;
26672690}
0 commit comments