1 //==- X86MnemonicTables.cpp - Generate mnemonic extraction tables. -*- C++ -*-//
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
7 //===----------------------------------------------------------------------===//
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"
24 class X86MnemonicTablesEmitter
{
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"))
50 X86Disassembler::RecognizableInstrBase
RI(*I
);
51 if (!RI
.shouldBeEmitted())
53 if ( // Non-parsable instruction defs contain prefix as part of AsmString
54 Def
->getValueAsString("AsmVariantName") == "NonParsable" ||
56 RI
.Form
== X86Local::PrefixByte
)
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";
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";
90 static TableGen::Emitter::OptClass
<X86MnemonicTablesEmitter
>
91 X("gen-x86-mnemonic-tables", "Generate X86 mnemonic tables");