Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/X86MnemonicTables.cpp
213766 views
//==- X86MnemonicTables.cpp - Generate mnemonic extraction tables. -*- C++ -*-//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This tablegen backend is responsible for emitting tables that group9// instructions by their mnemonic name wrt AsmWriter Variant (e.g. isADD, etc).10//11//===----------------------------------------------------------------------===//1213#include "Common/CodeGenInstruction.h"14#include "Common/CodeGenTarget.h"15#include "X86RecognizableInstr.h"16#include "llvm/TableGen/Record.h"17#include "llvm/TableGen/TableGenBackend.h"1819using namespace llvm;2021namespace {2223class X86MnemonicTablesEmitter {24const CodeGenTarget Target;2526public:27X86MnemonicTablesEmitter(const RecordKeeper &R) : Target(R) {}2829// Output X86 mnemonic tables.30void run(raw_ostream &OS);31};3233void X86MnemonicTablesEmitter::run(raw_ostream &OS) {34emitSourceFileHeader("X86 Mnemonic tables", OS);35OS << "namespace llvm {\nnamespace X86 {\n\n";36const Record *AsmWriter = Target.getAsmWriter();37unsigned Variant = AsmWriter->getValueAsInt("Variant");3839// Hold all instructions grouped by mnemonic40StringMap<SmallVector<const CodeGenInstruction *, 0>> MnemonicToCGInstrMap;4142for (const CodeGenInstruction *I : Target.getInstructions()) {43const Record *Def = I->TheDef;44// Filter non-X86 instructions.45if (!Def->isSubClassOf("X86Inst"))46continue;47X86Disassembler::RecognizableInstrBase RI(*I);48if (!RI.shouldBeEmitted())49continue;50if ( // Non-parsable instruction defs contain prefix as part of AsmString51Def->getValueAsString("AsmVariantName") == "NonParsable" ||52// Skip prefix byte53RI.Form == X86Local::PrefixByte)54continue;55std::string Mnemonic = X86Disassembler::getMnemonic(I, Variant);56MnemonicToCGInstrMap[Mnemonic].push_back(I);57}5859OS << "#ifdef GET_X86_MNEMONIC_TABLES_H\n";60OS << "#undef GET_X86_MNEMONIC_TABLES_H\n\n";61for (StringRef Mnemonic : MnemonicToCGInstrMap.keys())62OS << "bool is" << Mnemonic << "(unsigned Opcode);\n";63OS << "#endif // GET_X86_MNEMONIC_TABLES_H\n\n";6465OS << "#ifdef GET_X86_MNEMONIC_TABLES_CPP\n";66OS << "#undef GET_X86_MNEMONIC_TABLES_CPP\n\n";67for (StringRef Mnemonic : MnemonicToCGInstrMap.keys()) {68OS << "bool is" << Mnemonic << "(unsigned Opcode) {\n";69auto Mnemonics = MnemonicToCGInstrMap[Mnemonic];70if (Mnemonics.size() == 1) {71const CodeGenInstruction *CGI = *Mnemonics.begin();72OS << "\treturn Opcode == " << CGI->TheDef->getName() << ";\n}\n\n";73} else {74OS << "\tswitch (Opcode) {\n";75for (const CodeGenInstruction *CGI : Mnemonics) {76OS << "\tcase " << CGI->TheDef->getName() << ":\n";77}78OS << "\t\treturn true;\n\t}\n\treturn false;\n}\n\n";79}80}81OS << "#endif // GET_X86_MNEMONIC_TABLES_CPP\n\n";82OS << "} // end namespace X86\n} // end namespace llvm";83}8485} // namespace8687static TableGen::Emitter::OptClass<X86MnemonicTablesEmitter>88X("gen-x86-mnemonic-tables", "Generate X86 mnemonic tables");899091