Skip to content

Commit e3966c6

Browse files
committed
Generalize to support other opcodes
1 parent d12a2d0 commit e3966c6

File tree

1 file changed

+56
-33
lines changed

1 file changed

+56
-33
lines changed

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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

10381039
void 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().
22262227
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+
22282236
OS << R"(
22292237
static 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

Comments
 (0)