12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- //==- X86MnemonicTables.cpp - Generate mnemonic extraction tables. -*- C++ -*-//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This tablegen backend is responsible for emitting tables that group
- // instructions by their mnemonic name wrt AsmWriter Variant (e.g. isADD, etc).
- //
- //===----------------------------------------------------------------------===//
- #include "CodeGenInstruction.h"
- #include "CodeGenTarget.h"
- #include "X86RecognizableInstr.h"
- #include "llvm/TableGen/Error.h"
- #include "llvm/TableGen/TableGenBackend.h"
- using namespace llvm;
- namespace {
- class X86MnemonicTablesEmitter {
- CodeGenTarget Target;
- public:
- X86MnemonicTablesEmitter(RecordKeeper &R) : Target(R) {}
- // Output X86 mnemonic tables.
- void run(raw_ostream &OS);
- };
- void X86MnemonicTablesEmitter::run(raw_ostream &OS) {
- emitSourceFileHeader("X86 Mnemonic tables", OS);
- OS << "namespace llvm {\nnamespace X86 {\n\n";
- Record *AsmWriter = Target.getAsmWriter();
- unsigned Variant = AsmWriter->getValueAsInt("Variant");
- // Hold all instructions grouped by mnemonic
- StringMap<SmallVector<const CodeGenInstruction *, 0>> MnemonicToCGInstrMap;
- ArrayRef<const CodeGenInstruction *> NumberedInstructions =
- Target.getInstructionsByEnumValue();
- for (const CodeGenInstruction *I : NumberedInstructions) {
- const Record *Def = I->TheDef;
- // Filter non-X86 instructions.
- if (!Def->isSubClassOf("X86Inst"))
- continue;
- X86Disassembler::RecognizableInstrBase RI(*I);
- if (!RI.shouldBeEmitted())
- continue;
- if ( // Non-parsable instruction defs contain prefix as part of AsmString
- Def->getValueAsString("AsmVariantName") == "NonParsable" ||
- // Skip prefix byte
- RI.Form == X86Local::PrefixByte)
- continue;
- std::string Mnemonic = X86Disassembler::getMnemonic(I, Variant);
- MnemonicToCGInstrMap[Mnemonic].push_back(I);
- }
- OS << "#ifdef GET_X86_MNEMONIC_TABLES_H\n";
- OS << "#undef GET_X86_MNEMONIC_TABLES_H\n\n";
- for (StringRef Mnemonic : MnemonicToCGInstrMap.keys())
- OS << "bool is" << Mnemonic << "(unsigned Opcode);\n";
- OS << "#endif // GET_X86_MNEMONIC_TABLES_H\n\n";
- OS << "#ifdef GET_X86_MNEMONIC_TABLES_CPP\n";
- OS << "#undef GET_X86_MNEMONIC_TABLES_CPP\n\n";
- for (StringRef Mnemonic : MnemonicToCGInstrMap.keys()) {
- OS << "bool is" << Mnemonic << "(unsigned Opcode) {\n";
- auto Mnemonics = MnemonicToCGInstrMap[Mnemonic];
- if (Mnemonics.size() == 1) {
- const CodeGenInstruction *CGI = *Mnemonics.begin();
- OS << "\treturn Opcode == " << CGI->TheDef->getName() << ";\n}\n\n";
- } else {
- OS << "\tswitch (Opcode) {\n";
- for (const CodeGenInstruction *CGI : Mnemonics) {
- OS << "\tcase " << CGI->TheDef->getName() << ":\n";
- }
- OS << "\t\treturn true;\n\t}\n\treturn false;\n}\n\n";
- }
- }
- OS << "#endif // GET_X86_MNEMONIC_TABLES_CPP\n\n";
- OS << "} // end namespace X86\n} // end namespace llvm";
- }
- } // namespace
- namespace llvm {
- void EmitX86MnemonicTables(RecordKeeper &RK, raw_ostream &OS) {
- X86MnemonicTablesEmitter(RK).run(OS);
- }
- } // namespace llvm
|