Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 27 additions & 34 deletions llvm/utils/TableGen/DecoderEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ struct DecoderTableInfo {
DecoderTable Table;
PredicateSet Predicates;
DecoderSet Decoders;
bool HasCheckPredicate;
bool HasSoftFail;
bool HasTryDecode;

void insertPredicate(StringRef Predicate) {
Predicates.insert(CachedHashString(Predicate));
Expand Down Expand Up @@ -266,11 +269,10 @@ class DecoderEmitter {

const CodeGenTarget &getTarget() const { return Target; }

// Emit the decoder state machine table. Returns a mask of MCD decoder ops
// that were emitted.
unsigned emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
StringRef Namespace, unsigned HwModeID, unsigned BitWidth,
ArrayRef<unsigned> EncodingIDs) const;
// Emit the decoder state machine table.
void emitTable(formatted_raw_ostream &OS, DecoderTableInfo &TableInfo,
StringRef Namespace, unsigned HwModeID, unsigned BitWidth,
ArrayRef<unsigned> EncodingIDs) const;
void emitInstrLenTable(formatted_raw_ostream &OS,
ArrayRef<unsigned> InstrLen) const;
void emitPredicateFunction(formatted_raw_ostream &OS,
Expand Down Expand Up @@ -629,12 +631,11 @@ static StringRef getDecoderOpName(DecoderOps Op) {
llvm_unreachable("Unknown decoder op");
}

// Emit the decoder state machine table. Returns a mask of MCD decoder ops
// that were emitted.
unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
DecoderTable &Table, StringRef Namespace,
unsigned HwModeID, unsigned BitWidth,
ArrayRef<unsigned> EncodingIDs) const {
// Emit the decoder state machine table.
void DecoderEmitter::emitTable(formatted_raw_ostream &OS,
DecoderTableInfo &TableInfo, StringRef Namespace,
unsigned HwModeID, unsigned BitWidth,
ArrayRef<unsigned> EncodingIDs) const {
// We'll need to be able to map from a decoded opcode into the corresponding
// EncodingID for this specific combination of BitWidth and Namespace. This
// is used below to index into Encodings.
Expand All @@ -648,7 +649,7 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
OS << "static const uint8_t DecoderTable" << Namespace;
if (HwModeID != DefaultMode)
OS << '_' << Target.getHwModes().getModeName(HwModeID);
OS << BitWidth << "[" << Table.size() << "] = {\n";
OS << BitWidth << "[" << TableInfo.Table.size() << "] = {\n";

// Emit ULEB128 encoded value to OS, returning the number of bytes emitted.
auto EmitULEB128 = [](DecoderTable::const_iterator &I,
Expand Down Expand Up @@ -678,6 +679,7 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,

// FIXME: We may be able to use the NumToSkip values to recover
// appropriate indentation levels.
DecoderTable &Table = TableInfo.Table;
DecoderTable::const_iterator I = Table.begin();
DecoderTable::const_iterator E = Table.end();
const uint8_t *const EndPtr = Table.data() + Table.size();
Expand Down Expand Up @@ -719,15 +721,12 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
return Value;
};

unsigned OpcodeMask = 0;

while (I != E) {
assert(I < E && "incomplete decode table entry!");

uint32_t Pos = I - Table.begin();
EmitPos(Pos);
const uint8_t DecoderOp = *I++;
OpcodeMask |= (1 << DecoderOp);
OS << getDecoderOpName(static_cast<DecoderOps>(DecoderOp)) << ", ";
switch (DecoderOp) {
default:
Expand Down Expand Up @@ -826,8 +825,6 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
OS << '\n';
}
OS << "};\n\n";

return OpcodeMask;
}

void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS,
Expand Down Expand Up @@ -1114,6 +1111,7 @@ void DecoderTableBuilder::emitPredicateTableEntry(unsigned EncodingID) const {

TableInfo.Table.insertOpcode(OPC_CheckPredicate);
TableInfo.Table.insertULEB128(PredicateIndex);
TableInfo.HasCheckPredicate = true;
}

void DecoderTableBuilder::emitSoftFailTableEntry(unsigned EncodingID) const {
Expand All @@ -1130,6 +1128,7 @@ void DecoderTableBuilder::emitSoftFailTableEntry(unsigned EncodingID) const {
TableInfo.Table.insertOpcode(OPC_SoftFail);
TableInfo.Table.insertULEB128(PositiveMask.getZExtValue());
TableInfo.Table.insertULEB128(NegativeMask.getZExtValue());
TableInfo.HasSoftFail = true;
}

// Emits table entries to decode the singleton.
Expand Down Expand Up @@ -1180,6 +1179,7 @@ void DecoderTableBuilder::emitSingletonTableEntry(
const Record *InstDef = Encodings[EncodingID].getInstruction()->TheDef;
TableInfo.Table.insertULEB128(Target.getInstrIntValue(InstDef));
TableInfo.Table.insertULEB128(DecoderIndex);
TableInfo.HasTryDecode |= DecoderOp == OPC_TryDecode;
}

std::unique_ptr<Filter>
Expand Down Expand Up @@ -1523,11 +1523,7 @@ void DecoderTableBuilder::emitTableEntries(const FilterChooser &FC) const {
// emitDecodeInstruction - Emit the templated helper function
// decodeInstruction().
static void emitDecodeInstruction(formatted_raw_ostream &OS, bool IsVarLenInst,
unsigned OpcodeMask) {
const bool HasTryDecode = OpcodeMask & (1 << OPC_TryDecode);
const bool HasCheckPredicate = OpcodeMask & (1 << OPC_CheckPredicate);
const bool HasSoftFail = OpcodeMask & (1 << OPC_SoftFail);

const DecoderTableInfo &TableInfo) {
OS << R"(
static unsigned decodeNumToSkip(const uint8_t *&Ptr) {
unsigned NumToSkip = *Ptr++;
Expand All @@ -1548,7 +1544,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
"llvm::function_ref<void(APInt &, uint64_t)> makeUp";
}
OS << ") {\n";
if (HasCheckPredicate)
if (TableInfo.HasCheckPredicate)
OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n";
OS << " const uint8_t *Ptr = DecodeTable;\n";

Expand Down Expand Up @@ -1657,7 +1653,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
}
break;
})";
if (HasCheckPredicate) {
if (TableInfo.HasCheckPredicate) {
OS << R"(
case OPC_CheckPredicate: {
// Decode the Predicate Index value.
Expand Down Expand Up @@ -1701,7 +1697,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
<< (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n"));
return S;
})";
if (HasTryDecode) {
if (TableInfo.HasTryDecode) {
OS << R"(
case OPC_TryDecode: {
// Decode the Opcode value.
Expand Down Expand Up @@ -1735,7 +1731,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
break;
})";
}
if (HasSoftFail) {
if (TableInfo.HasSoftFail) {
OS << R"(
case OPC_SoftFail: {
// Decode the mask values.
Expand Down Expand Up @@ -1994,9 +1990,8 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;

// Entries in `EncMap` are already sorted by bitwidth. So bucketing per
// bitwidth can be done on-the-fly as we iterate over the map.
DecoderTableInfo TableInfo;
DecoderTableInfo TableInfo{};
DecoderTableBuilder TableBuilder(Target, Encodings, TableInfo);
unsigned OpcodeMask = 0;

bool HasConflict = false;
for (const auto &[BitWidth, BWMap] : EncMap) {
Expand All @@ -2021,8 +2016,8 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
TableBuilder.buildTable(FC, BitWidth);

// Print the table to the output stream.
OpcodeMask |= emitTable(OS, TableInfo.Table, DecoderNamespace, HwModeID,
BitWidth, EncodingIDs);
emitTable(OS, TableInfo, DecoderNamespace, HwModeID, BitWidth,
EncodingIDs);
}

// Each BitWidth get's its own decoders and decoder function if
Expand All @@ -2041,14 +2036,12 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
if (!SpecializeDecodersPerBitwidth)
emitDecoderFunction(OS, TableInfo.Decoders, 0);

const bool HasCheckPredicate = OpcodeMask & (1 << OPC_CheckPredicate);

// Emit the predicate function.
if (HasCheckPredicate)
if (TableInfo.HasCheckPredicate)
emitPredicateFunction(OS, TableInfo.Predicates);

// Emit the main entry point for the decoder, decodeInstruction().
emitDecodeInstruction(OS, IsVarLenInst, OpcodeMask);
emitDecodeInstruction(OS, IsVarLenInst, TableInfo);

OS << "\n} // namespace\n";
}
Expand Down