@@ -222,10 +222,11 @@ class DecoderEmitter {
222
222
DecoderEmitter (const RecordKeeper &R, StringRef PredicateNamespace)
223
223
: RK(R), Target(R), PredicateNamespace(PredicateNamespace) {}
224
224
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 ;
229
230
void emitInstrLenTable (formatted_raw_ostream &OS,
230
231
ArrayRef<unsigned > InstrLen) const ;
231
232
void emitPredicateFunction (formatted_raw_ostream &OS,
@@ -826,11 +827,12 @@ unsigned Filter::usefulness() const {
826
827
// //
827
828
// ////////////////////////////////
828
829
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 {
834
836
// We'll need to be able to map from a decoded opcode into the corresponding
835
837
// EncodingID for this specific combination of BitWidth and Namespace. This
836
838
// is used below to index into NumberedEncodings.
@@ -884,6 +886,8 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
884
886
OS << " (Fail)" ;
885
887
};
886
888
889
+ unsigned OpcodeMask = 0 ;
890
+
887
891
while (I != E) {
888
892
assert (I < E && " incomplete decode table entry!" );
889
893
@@ -892,6 +896,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
892
896
OS.PadToColumn (12 );
893
897
894
898
const uint8_t DecoderOp = *I++;
899
+ OpcodeMask |= (1 << DecoderOp);
895
900
switch (DecoderOp) {
896
901
default :
897
902
PrintFatalError (" Invalid decode table opcode: " + Twine ((int )DecoderOp) +
@@ -1027,6 +1032,8 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
1027
1032
Indent -= 2 ;
1028
1033
1029
1034
OS << Indent << " };\n\n " ;
1035
+
1036
+ return OpcodeMask;
1030
1037
}
1031
1038
1032
1039
void DecoderEmitter::emitInstrLenTable (formatted_raw_ostream &OS,
@@ -1045,19 +1052,13 @@ void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
1045
1052
OS << Indent << " static bool checkDecoderPredicate(unsigned Idx, "
1046
1053
<< " const FeatureBitset &Bits) {\n " ;
1047
1054
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 " ;
1060
1060
}
1061
+ OS << Indent << " }\n " ;
1061
1062
Indent -= 2 ;
1062
1063
OS << Indent << " }\n\n " ;
1063
1064
}
@@ -2217,8 +2218,15 @@ static void insertBits(InsnType &field, InsnType bits, unsigned startBit,
2217
2218
2218
2219
// emitDecodeInstruction - Emit the templated helper function
2219
2220
// 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
+
2222
2230
OS << R"(
2223
2231
static unsigned decodeNumToSkip(const uint8_t *&Ptr) {
2224
2232
unsigned NumToSkip = *Ptr++;
@@ -2238,9 +2246,11 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2238
2246
OS << " ,\n "
2239
2247
" llvm::function_ref<void(APInt &, uint64_t)> makeUp" ;
2240
2248
}
2241
- OS << R"( ) {
2242
- const FeatureBitset &Bits = STI.getFeatureBits();
2249
+ OS << " ) {\n " ;
2250
+ if (HasCheckPredicate)
2251
+ OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n " ;
2243
2252
2253
+ OS << R"(
2244
2254
const uint8_t *Ptr = DecodeTable;
2245
2255
uint64_t CurFieldValue = 0;
2246
2256
DecodeStatus S = MCDisassembler::Success;
@@ -2321,7 +2331,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2321
2331
Ptr += NumToSkip;
2322
2332
}
2323
2333
break;
2324
- }
2334
+ })" ;
2335
+ if (HasCheckPredicate) {
2336
+ OS << R"(
2325
2337
case MCD::OPC_CheckPredicate:
2326
2338
case MCD::OPC_CheckPredicateOrFail: {
2327
2339
bool IsFail = DecoderOp == MCD::OPC_CheckPredicateOrFail;
@@ -2343,7 +2355,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2343
2355
Ptr += NumToSkip;
2344
2356
}
2345
2357
break;
2346
- }
2358
+ })" ;
2359
+ }
2360
+ OS << R"(
2347
2361
case MCD::OPC_Decode: {
2348
2362
// Decode the Opcode value.
2349
2363
unsigned Opc = decodeULEB128AndIncUnsafe(Ptr);
@@ -2364,7 +2378,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2364
2378
<< ", using decoder " << DecodeIdx << ": "
2365
2379
<< (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n"));
2366
2380
return S;
2367
- }
2381
+ })" ;
2382
+ if (HasTryDecode) {
2383
+ OS << R"(
2368
2384
case MCD::OPC_TryDecode:
2369
2385
case MCD::OPC_TryDecodeOrFail: {
2370
2386
bool IsFail = DecoderOp == MCD::OPC_TryDecodeOrFail;
@@ -2399,17 +2415,22 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2399
2415
// set before the decode attempt.
2400
2416
S = MCDisassembler::Success;
2401
2417
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"(
2413
2434
case MCD::OPC_Fail: {
2414
2435
LLVM_DEBUG(dbgs() << Loc << ": OPC_Fail\n");
2415
2436
return MCDisassembler::Fail;
@@ -2609,6 +2630,7 @@ namespace {
2609
2630
}
2610
2631
2611
2632
DecoderTableInfo TableInfo;
2633
+ unsigned OpcodeMask = 0 ;
2612
2634
for (const auto &Opc : OpcMap) {
2613
2635
// Emit the decoder for this namespace+width combination.
2614
2636
ArrayRef<EncodingAndInst> NumberedEncodingsRef (NumberedEncodings.data (),
@@ -2634,23 +2656,29 @@ namespace {
2634
2656
TableInfo.Table .push_back (MCD::OPC_Fail);
2635
2657
2636
2658
// 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 );
2639
2661
}
2640
2662
2641
2663
// For variable instruction, we emit a instruction length table
2642
2664
// to let the decoder know how long the instructions are.
2643
2665
// You can see example usage in M68k's disassembler.
2644
2666
if (IsVarLenInst)
2645
2667
emitInstrLenTable (OS, InstrLen);
2668
+
2669
+ const bool HasCheckPredicate =
2670
+ OpcodeMask &
2671
+ ((1 << MCD::OPC_CheckPredicate) | (1 << MCD::OPC_CheckPredicateOrFail));
2672
+
2646
2673
// Emit the predicate function.
2647
- emitPredicateFunction (OS, TableInfo.Predicates , indent (0 ));
2674
+ if (HasCheckPredicate)
2675
+ emitPredicateFunction (OS, TableInfo.Predicates , indent (0 ));
2648
2676
2649
2677
// Emit the decoder function.
2650
2678
emitDecoderFunction (OS, TableInfo.Decoders , indent (0 ));
2651
2679
2652
2680
// Emit the main entry point for the decoder, decodeInstruction().
2653
- emitDecodeInstruction (OS, IsVarLenInst);
2681
+ emitDecodeInstruction (OS, IsVarLenInst, OpcodeMask );
2654
2682
2655
2683
OS << " \n } // namespace\n " ;
2656
2684
}
0 commit comments