forked from OSchip/llvm-project
[TableGen] Added a function for identification of unsupported opcodes.
This change implements generation of a function which may be used by a backend to check if a given instruction is supported for a specific subtarget. Reviewers: sdesmalen Differential Revision: https://reviews.llvm.org/D88214
This commit is contained in:
parent
96c8a17c80
commit
e70e7d1019
|
@ -3094,6 +3094,67 @@ static void emitMnemonicSpellChecker(raw_ostream &OS, CodeGenTarget &Target,
|
|||
OS << "\n";
|
||||
}
|
||||
|
||||
static void emitMnemonicChecker(raw_ostream &OS,
|
||||
CodeGenTarget &Target,
|
||||
unsigned VariantCount,
|
||||
bool HasMnemonicFirst,
|
||||
bool HasMnemonicAliases) {
|
||||
OS << "static bool " << Target.getName()
|
||||
<< "CheckMnemonic(StringRef Mnemonic,\n";
|
||||
OS << " "
|
||||
<< "const FeatureBitset &AvailableFeatures,\n";
|
||||
OS << " "
|
||||
<< "unsigned VariantID) {\n";
|
||||
|
||||
if (!VariantCount) {
|
||||
OS << " return false;\n";
|
||||
} else {
|
||||
if (HasMnemonicAliases) {
|
||||
OS << " // Process all MnemonicAliases to remap the mnemonic.\n";
|
||||
OS << " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);";
|
||||
OS << "\n\n";
|
||||
}
|
||||
OS << " // Find the appropriate table for this asm variant.\n";
|
||||
OS << " const MatchEntry *Start, *End;\n";
|
||||
OS << " switch (VariantID) {\n";
|
||||
OS << " default: llvm_unreachable(\"invalid variant!\");\n";
|
||||
for (unsigned VC = 0; VC != VariantCount; ++VC) {
|
||||
Record *AsmVariant = Target.getAsmParserVariant(VC);
|
||||
int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
|
||||
OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC
|
||||
<< "); End = std::end(MatchTable" << VC << "); break;\n";
|
||||
}
|
||||
OS << " }\n\n";
|
||||
|
||||
OS << " // Search the table.\n";
|
||||
if (HasMnemonicFirst) {
|
||||
OS << " auto MnemonicRange = "
|
||||
"std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
|
||||
} else {
|
||||
OS << " auto MnemonicRange = std::make_pair(Start, End);\n";
|
||||
OS << " unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
|
||||
OS << " if (!Mnemonic.empty())\n";
|
||||
OS << " MnemonicRange = "
|
||||
<< "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
|
||||
}
|
||||
|
||||
OS << " if (MnemonicRange.first == MnemonicRange.second)\n";
|
||||
OS << " return false;\n\n";
|
||||
|
||||
OS << " for (const MatchEntry *it = MnemonicRange.first, "
|
||||
<< "*ie = MnemonicRange.second;\n";
|
||||
OS << " it != ie; ++it) {\n";
|
||||
OS << " const FeatureBitset &RequiredFeatures =\n";
|
||||
OS << " FeatureBitsets[it->RequiredFeaturesIdx];\n";
|
||||
OS << " if ((AvailableFeatures & RequiredFeatures) == ";
|
||||
OS << "RequiredFeatures)\n";
|
||||
OS << " return true;\n";
|
||||
OS << " }\n";
|
||||
OS << " return false;\n";
|
||||
}
|
||||
OS << "}\n";
|
||||
OS << "\n";
|
||||
}
|
||||
|
||||
// Emit a function mapping match classes to strings, for debugging.
|
||||
static void emitMatchClassKindNames(std::forward_list<ClassInfo> &Infos,
|
||||
|
@ -3909,6 +3970,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||
emitMnemonicSpellChecker(OS, Target, VariantCount);
|
||||
|
||||
OS << "#endif // GET_MNEMONIC_SPELL_CHECKER\n\n";
|
||||
|
||||
OS << "\n#ifdef GET_MNEMONIC_CHECKER\n";
|
||||
OS << "#undef GET_MNEMONIC_CHECKER\n\n";
|
||||
|
||||
emitMnemonicChecker(OS, Target, VariantCount,
|
||||
HasMnemonicFirst, HasMnemonicAliases);
|
||||
|
||||
OS << "#endif // GET_MNEMONIC_CHECKER\n\n";
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
|
|
Loading…
Reference in New Issue