@@ -222,10 +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.
226- void emitTable (formatted_raw_ostream &OS, DecoderTable &Table, indent Indent,
227- unsigned BitWidth, StringRef Namespace,
228- 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 ;
229230 void emitInstrLenTable (formatted_raw_ostream &OS,
230231 ArrayRef<unsigned > InstrLen) const ;
231232 void emitPredicateFunction (formatted_raw_ostream &OS,
@@ -826,11 +827,12 @@ unsigned Filter::usefulness() const {
826827// //
827828// ////////////////////////////////
828829
829- // Emit the decoder state machine table.
830- void DecoderEmitter::emitTable (formatted_raw_ostream &OS, DecoderTable &Table,
831- indent Indent, unsigned BitWidth,
832- StringRef Namespace,
833- 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 {
834836 // We'll need to be able to map from a decoded opcode into the corresponding
835837 // EncodingID for this specific combination of BitWidth and Namespace. This
836838 // is used below to index into NumberedEncodings.
@@ -884,6 +886,8 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
884886 OS << " (Fail)" ;
885887 };
886888
889+ unsigned OpcodeMask = 0 ;
890+
887891 while (I != E) {
888892 assert (I < E && " incomplete decode table entry!" );
889893
@@ -892,6 +896,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
892896 OS.PadToColumn (12 );
893897
894898 const uint8_t DecoderOp = *I++;
899+ OpcodeMask |= (1 << DecoderOp);
895900 switch (DecoderOp) {
896901 default :
897902 PrintFatalError (" Invalid decode table opcode: " + Twine ((int )DecoderOp) +
@@ -1027,6 +1032,8 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
10271032 Indent -= 2 ;
10281033
10291034 OS << Indent << " };\n\n " ;
1035+
1036+ return OpcodeMask;
10301037}
10311038
10321039void DecoderEmitter::emitInstrLenTable (formatted_raw_ostream &OS,
@@ -1045,19 +1052,13 @@ void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
10451052 OS << Indent << " static bool checkDecoderPredicate(unsigned Idx, "
10461053 << " const FeatureBitset &Bits) {\n " ;
10471054 Indent += 2 ;
1048- if (!Predicates.empty ()) {
1049- OS << Indent << " switch (Idx) {\n " ;
1050- OS << Indent << " default: llvm_unreachable(\" Invalid index!\" );\n " ;
1051- unsigned Index = 0 ;
1052- for (const auto &Predicate : Predicates) {
1053- OS << Indent << " case " << Index++ << " :\n " ;
1054- OS << Indent + 2 << " return (" << Predicate << " );\n " ;
1055- }
1056- OS << Indent << " }\n " ;
1057- } else {
1058- // No case statement to emit
1059- OS << Indent << " llvm_unreachable(\" Invalid index!\" );\n " ;
1055+ OS << Indent << " switch (Idx) {\n " ;
1056+ OS << Indent << " default: llvm_unreachable(\" Invalid index!\" );\n " ;
1057+ for (const auto &[Index, Predicate] : enumerate(Predicates)) {
1058+ OS << Indent << " case " << Index << " :\n " ;
1059+ OS << Indent + 2 << " return (" << Predicate << " );\n " ;
10601060 }
1061+ OS << Indent << " }\n " ;
10611062 Indent -= 2 ;
10621063 OS << Indent << " }\n\n " ;
10631064}
@@ -2217,8 +2218,15 @@ static void insertBits(InsnType &field, InsnType bits, unsigned startBit,
22172218
22182219// emitDecodeInstruction - Emit the templated helper function
22192220// decodeInstruction().
2220- static void emitDecodeInstruction (formatted_raw_ostream &OS,
2221- bool IsVarLenInst) {
2221+ static void emitDecodeInstruction (formatted_raw_ostream &OS, bool IsVarLenInst,
2222+ unsigned OpcodeMask) {
2223+ const bool HasTryDecode = OpcodeMask & ((1 << MCD::OPC_TryDecode) |
2224+ (1 << MCD::OPC_TryDecodeOrFail));
2225+ const bool HasCheckPredicate =
2226+ OpcodeMask &
2227+ ((1 << MCD::OPC_CheckPredicate) | (1 << MCD::OPC_CheckPredicateOrFail));
2228+ const bool HasSoftFail = OpcodeMask & (1 << MCD::OPC_SoftFail);
2229+
22222230 OS << R"(
22232231static unsigned decodeNumToSkip(const uint8_t *&Ptr) {
22242232 unsigned NumToSkip = *Ptr++;
@@ -2238,9 +2246,11 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
22382246 OS << " ,\n "
22392247 " llvm::function_ref<void(APInt &, uint64_t)> makeUp" ;
22402248 }
2241- OS << R"( ) {
2242- const FeatureBitset &Bits = STI.getFeatureBits();
2249+ OS << " ) {\n " ;
2250+ if (HasCheckPredicate)
2251+ OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n " ;
22432252
2253+ OS << R"(
22442254 const uint8_t *Ptr = DecodeTable;
22452255 uint64_t CurFieldValue = 0;
22462256 DecodeStatus S = MCDisassembler::Success;
@@ -2321,7 +2331,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
23212331 Ptr += NumToSkip;
23222332 }
23232333 break;
2324- }
2334+ })" ;
2335+ if (HasCheckPredicate) {
2336+ OS << R"(
23252337 case MCD::OPC_CheckPredicate:
23262338 case MCD::OPC_CheckPredicateOrFail: {
23272339 bool IsFail = DecoderOp == MCD::OPC_CheckPredicateOrFail;
@@ -2343,7 +2355,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
23432355 Ptr += NumToSkip;
23442356 }
23452357 break;
2346- }
2358+ })" ;
2359+ }
2360+ OS << R"(
23472361 case MCD::OPC_Decode: {
23482362 // Decode the Opcode value.
23492363 unsigned Opc = decodeULEB128AndIncUnsafe(Ptr);
@@ -2364,7 +2378,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
23642378 << ", using decoder " << DecodeIdx << ": "
23652379 << (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n"));
23662380 return S;
2367- }
2381+ })" ;
2382+ if (HasTryDecode) {
2383+ OS << R"(
23682384 case MCD::OPC_TryDecode:
23692385 case MCD::OPC_TryDecodeOrFail: {
23702386 bool IsFail = DecoderOp == MCD::OPC_TryDecodeOrFail;
@@ -2399,17 +2415,22 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
23992415 // set before the decode attempt.
24002416 S = MCDisassembler::Success;
24012417 break;
2402- }
2403- case MCD::OPC_SoftFail: {
2404- // Decode the mask values.
2405- uint64_t PositiveMask = decodeULEB128AndIncUnsafe(Ptr);
2406- uint64_t NegativeMask = decodeULEB128AndIncUnsafe(Ptr);
2407- bool Failed = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0;
2408- if (Failed)
2409- S = MCDisassembler::SoftFail;
2410- LLVM_DEBUG(dbgs() << Loc << ": OPC_SoftFail: " << (Failed ? "FAIL\n" : "PASS\n"));
2411- break;
2412- }
2418+ })" ;
2419+ }
2420+ if (HasSoftFail) {
2421+ OS << R"(
2422+ case MCD::OPC_SoftFail: {
2423+ // Decode the mask values.
2424+ uint64_t PositiveMask = decodeULEB128AndIncUnsafe(Ptr);
2425+ uint64_t NegativeMask = decodeULEB128AndIncUnsafe(Ptr);
2426+ bool Failed = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0;
2427+ if (Failed)
2428+ S = MCDisassembler::SoftFail;
2429+ LLVM_DEBUG(dbgs() << Loc << ": OPC_SoftFail: " << (Failed ? "FAIL\n" : "PASS\n"));
2430+ break;
2431+ })" ;
2432+ }
2433+ OS << R"(
24132434 case MCD::OPC_Fail: {
24142435 LLVM_DEBUG(dbgs() << Loc << ": OPC_Fail\n");
24152436 return MCDisassembler::Fail;
@@ -2609,6 +2630,7 @@ namespace {
26092630 }
26102631
26112632 DecoderTableInfo TableInfo;
2633+ unsigned OpcodeMask = 0 ;
26122634 for (const auto &Opc : OpcMap) {
26132635 // Emit the decoder for this namespace+width combination.
26142636 ArrayRef<EncodingAndInst> NumberedEncodingsRef (NumberedEncodings.data (),
@@ -2634,23 +2656,29 @@ namespace {
26342656 TableInfo.Table .push_back (MCD::OPC_Fail);
26352657
26362658 // Print the table to the output stream.
2637- emitTable (OS, TableInfo.Table , indent (0 ), FC.getBitWidth (), Opc. first . first ,
2638- Opc.second );
2659+ OpcodeMask |= emitTable (OS, TableInfo.Table , indent (0 ), FC.getBitWidth (),
2660+ Opc. first . first , Opc.second );
26392661 }
26402662
26412663 // For variable instruction, we emit a instruction length table
26422664 // to let the decoder know how long the instructions are.
26432665 // You can see example usage in M68k's disassembler.
26442666 if (IsVarLenInst)
26452667 emitInstrLenTable (OS, InstrLen);
2668+
2669+ const bool HasCheckPredicate =
2670+ OpcodeMask &
2671+ ((1 << MCD::OPC_CheckPredicate) | (1 << MCD::OPC_CheckPredicateOrFail));
2672+
26462673 // Emit the predicate function.
2647- emitPredicateFunction (OS, TableInfo.Predicates , indent (0 ));
2674+ if (HasCheckPredicate)
2675+ emitPredicateFunction (OS, TableInfo.Predicates , indent (0 ));
26482676
26492677 // Emit the decoder function.
26502678 emitDecoderFunction (OS, TableInfo.Decoders , indent (0 ));
26512679
26522680 // Emit the main entry point for the decoder, decodeInstruction().
2653- emitDecodeInstruction (OS, IsVarLenInst);
2681+ emitDecodeInstruction (OS, IsVarLenInst, OpcodeMask );
26542682
26552683 OS << " \n } // namespace\n " ;
26562684}
0 commit comments