@@ -222,11 +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. 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 ;
230
230
void emitInstrLenTable (formatted_raw_ostream &OS,
231
231
ArrayRef<unsigned > InstrLen) const ;
232
232
void emitPredicateFunction (formatted_raw_ostream &OS,
@@ -827,11 +827,12 @@ unsigned Filter::usefulness() const {
827
827
// //
828
828
// ////////////////////////////////
829
829
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 {
835
836
// We'll need to be able to map from a decoded opcode into the corresponding
836
837
// EncodingID for this specific combination of BitWidth and Namespace. This
837
838
// is used below to index into NumberedEncodings.
@@ -885,7 +886,7 @@ bool DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
885
886
OS << " (Fail)" ;
886
887
};
887
888
888
- bool HasTryDecode = false ;
889
+ unsigned OpcodeMask = 0 ;
889
890
890
891
while (I != E) {
891
892
assert (I < E && " incomplete decode table entry!" );
@@ -895,6 +896,7 @@ bool DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
895
896
OS.PadToColumn (12 );
896
897
897
898
const uint8_t DecoderOp = *I++;
899
+ OpcodeMask |= (1 << DecoderOp);
898
900
switch (DecoderOp) {
899
901
default :
900
902
PrintFatalError (" Invalid decode table opcode: " + Twine ((int )DecoderOp) +
@@ -967,7 +969,6 @@ bool DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
967
969
case MCD::OPC_TryDecodeOrFail: {
968
970
bool IsFail = DecoderOp == MCD::OPC_TryDecodeOrFail;
969
971
bool IsTry = DecoderOp == MCD::OPC_TryDecode || IsFail;
970
- HasTryDecode |= IsTry;
971
972
// Decode the Opcode value.
972
973
const char *ErrMsg = nullptr ;
973
974
unsigned Opc = decodeULEB128 (&*I, nullptr , EndPtr, &ErrMsg);
@@ -1032,7 +1033,7 @@ bool DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
1032
1033
1033
1034
OS << Indent << " };\n\n " ;
1034
1035
1035
- return HasTryDecode ;
1036
+ return OpcodeMask ;
1036
1037
}
1037
1038
1038
1039
void DecoderEmitter::emitInstrLenTable (formatted_raw_ostream &OS,
@@ -2224,7 +2225,14 @@ static void insertBits(InsnType &field, InsnType bits, unsigned startBit,
2224
2225
// emitDecodeInstruction - Emit the templated helper function
2225
2226
// decodeInstruction().
2226
2227
static 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
+
2228
2236
OS << R"(
2229
2237
static unsigned decodeNumToSkip(const uint8_t *&Ptr) {
2230
2238
unsigned NumToSkip = *Ptr++;
@@ -2244,9 +2252,11 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2244
2252
OS << " ,\n "
2245
2253
" llvm::function_ref<void(APInt &, uint64_t)> makeUp" ;
2246
2254
}
2247
- OS << R"( ) {
2248
- const FeatureBitset &Bits = STI.getFeatureBits();
2255
+ OS << " ) {\n " ;
2256
+ if (HasCheckPredicate)
2257
+ OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n " ;
2249
2258
2259
+ OS << R"(
2250
2260
const uint8_t *Ptr = DecodeTable;
2251
2261
uint64_t CurFieldValue = 0;
2252
2262
DecodeStatus S = MCDisassembler::Success;
@@ -2327,7 +2337,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2327
2337
Ptr += NumToSkip;
2328
2338
}
2329
2339
break;
2330
- }
2340
+ })" ;
2341
+ if (HasCheckPredicate) {
2342
+ OS << R"(
2331
2343
case MCD::OPC_CheckPredicate:
2332
2344
case MCD::OPC_CheckPredicateOrFail: {
2333
2345
bool IsFail = DecoderOp == MCD::OPC_CheckPredicateOrFail;
@@ -2349,7 +2361,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2349
2361
Ptr += NumToSkip;
2350
2362
}
2351
2363
break;
2352
- }
2364
+ })" ;
2365
+ }
2366
+ OS << R"(
2353
2367
case MCD::OPC_Decode: {
2354
2368
// Decode the Opcode value.
2355
2369
unsigned Opc = decodeULEB128AndIncUnsafe(Ptr);
@@ -2409,17 +2423,20 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2409
2423
break;
2410
2424
})" ;
2411
2425
}
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
+ }
2412
2439
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
- }
2423
2440
case MCD::OPC_Fail: {
2424
2441
LLVM_DEBUG(dbgs() << Loc << ": OPC_Fail\n");
2425
2442
return MCDisassembler::Fail;
@@ -2619,7 +2636,7 @@ namespace {
2619
2636
}
2620
2637
2621
2638
DecoderTableInfo TableInfo;
2622
- bool HasTryDecode = false ;
2639
+ unsigned OpcodeMask = 0 ;
2623
2640
for (const auto &Opc : OpcMap) {
2624
2641
// Emit the decoder for this namespace+width combination.
2625
2642
ArrayRef<EncodingAndInst> NumberedEncodingsRef (NumberedEncodings.data (),
@@ -2645,23 +2662,29 @@ namespace {
2645
2662
TableInfo.Table .push_back (MCD::OPC_Fail);
2646
2663
2647
2664
// 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 );
2650
2667
}
2651
2668
2652
2669
// For variable instruction, we emit a instruction length table
2653
2670
// to let the decoder know how long the instructions are.
2654
2671
// You can see example usage in M68k's disassembler.
2655
2672
if (IsVarLenInst)
2656
2673
emitInstrLenTable (OS, InstrLen);
2674
+
2675
+ const bool HasCheckPredicate =
2676
+ OpcodeMask &
2677
+ ((1 << MCD::OPC_CheckPredicate) | (1 << MCD::OPC_CheckPredicateOrFail));
2678
+
2657
2679
// Emit the predicate function.
2658
- emitPredicateFunction (OS, TableInfo.Predicates , indent (0 ));
2680
+ if (HasCheckPredicate)
2681
+ emitPredicateFunction (OS, TableInfo.Predicates , indent (0 ));
2659
2682
2660
2683
// Emit the decoder function.
2661
2684
emitDecoderFunction (OS, TableInfo.Decoders , indent (0 ));
2662
2685
2663
2686
// Emit the main entry point for the decoder, decodeInstruction().
2664
- emitDecodeInstruction (OS, IsVarLenInst, HasTryDecode );
2687
+ emitDecodeInstruction (OS, IsVarLenInst, OpcodeMask );
2665
2688
2666
2689
OS << " \n } // namespace\n " ;
2667
2690
}
0 commit comments