Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / utils / TableGen / X86MnemonicTables.cpp
blobaeafee15746235d79e018b55a50285f948436285
1 //==- X86MnemonicTables.cpp - Generate mnemonic extraction tables. -*- C++ -*-//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This tablegen backend is responsible for emitting tables that group
10 // instructions by their mnemonic name wrt AsmWriter Variant (e.g. isADD, etc).
12 //===----------------------------------------------------------------------===//
14 #include "CodeGenInstruction.h"
15 #include "CodeGenTarget.h"
16 #include "X86RecognizableInstr.h"
17 #include "llvm/TableGen/Record.h"
18 #include "llvm/TableGen/TableGenBackend.h"
20 using namespace llvm;
22 namespace {
24 class X86MnemonicTablesEmitter {
25 CodeGenTarget Target;
27 public:
28 X86MnemonicTablesEmitter(RecordKeeper &R) : Target(R) {}
30 // Output X86 mnemonic tables.
31 void run(raw_ostream &OS);
34 void X86MnemonicTablesEmitter::run(raw_ostream &OS) {
35 emitSourceFileHeader("X86 Mnemonic tables", OS);
36 OS << "namespace llvm {\nnamespace X86 {\n\n";
37 Record *AsmWriter = Target.getAsmWriter();
38 unsigned Variant = AsmWriter->getValueAsInt("Variant");
40 // Hold all instructions grouped by mnemonic
41 StringMap<SmallVector<const CodeGenInstruction *, 0>> MnemonicToCGInstrMap;
43 ArrayRef<const CodeGenInstruction *> NumberedInstructions =
44 Target.getInstructionsByEnumValue();
45 for (const CodeGenInstruction *I : NumberedInstructions) {
46 const Record *Def = I->TheDef;
47 // Filter non-X86 instructions.
48 if (!Def->isSubClassOf("X86Inst"))
49 continue;
50 X86Disassembler::RecognizableInstrBase RI(*I);
51 if (!RI.shouldBeEmitted())
52 continue;
53 if ( // Non-parsable instruction defs contain prefix as part of AsmString
54 Def->getValueAsString("AsmVariantName") == "NonParsable" ||
55 // Skip prefix byte
56 RI.Form == X86Local::PrefixByte)
57 continue;
58 std::string Mnemonic = X86Disassembler::getMnemonic(I, Variant);
59 MnemonicToCGInstrMap[Mnemonic].push_back(I);
62 OS << "#ifdef GET_X86_MNEMONIC_TABLES_H\n";
63 OS << "#undef GET_X86_MNEMONIC_TABLES_H\n\n";
64 for (StringRef Mnemonic : MnemonicToCGInstrMap.keys())
65 OS << "bool is" << Mnemonic << "(unsigned Opcode);\n";
66 OS << "#endif // GET_X86_MNEMONIC_TABLES_H\n\n";
68 OS << "#ifdef GET_X86_MNEMONIC_TABLES_CPP\n";
69 OS << "#undef GET_X86_MNEMONIC_TABLES_CPP\n\n";
70 for (StringRef Mnemonic : MnemonicToCGInstrMap.keys()) {
71 OS << "bool is" << Mnemonic << "(unsigned Opcode) {\n";
72 auto Mnemonics = MnemonicToCGInstrMap[Mnemonic];
73 if (Mnemonics.size() == 1) {
74 const CodeGenInstruction *CGI = *Mnemonics.begin();
75 OS << "\treturn Opcode == " << CGI->TheDef->getName() << ";\n}\n\n";
76 } else {
77 OS << "\tswitch (Opcode) {\n";
78 for (const CodeGenInstruction *CGI : Mnemonics) {
79 OS << "\tcase " << CGI->TheDef->getName() << ":\n";
81 OS << "\t\treturn true;\n\t}\n\treturn false;\n}\n\n";
84 OS << "#endif // GET_X86_MNEMONIC_TABLES_CPP\n\n";
85 OS << "} // end namespace X86\n} // end namespace llvm";
88 } // namespace
90 static TableGen::Emitter::OptClass<X86MnemonicTablesEmitter>
91 X("gen-x86-mnemonic-tables", "Generate X86 mnemonic tables");