Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/X86MnemonicTables.cpp
213766 views
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).
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "Common/CodeGenInstruction.h"
15
#include "Common/CodeGenTarget.h"
16
#include "X86RecognizableInstr.h"
17
#include "llvm/TableGen/Record.h"
18
#include "llvm/TableGen/TableGenBackend.h"
19
20
using namespace llvm;
21
22
namespace {
23
24
class X86MnemonicTablesEmitter {
25
const CodeGenTarget Target;
26
27
public:
28
X86MnemonicTablesEmitter(const RecordKeeper &R) : Target(R) {}
29
30
// Output X86 mnemonic tables.
31
void run(raw_ostream &OS);
32
};
33
34
void X86MnemonicTablesEmitter::run(raw_ostream &OS) {
35
emitSourceFileHeader("X86 Mnemonic tables", OS);
36
OS << "namespace llvm {\nnamespace X86 {\n\n";
37
const Record *AsmWriter = Target.getAsmWriter();
38
unsigned Variant = AsmWriter->getValueAsInt("Variant");
39
40
// Hold all instructions grouped by mnemonic
41
StringMap<SmallVector<const CodeGenInstruction *, 0>> MnemonicToCGInstrMap;
42
43
for (const CodeGenInstruction *I : Target.getInstructions()) {
44
const Record *Def = I->TheDef;
45
// Filter non-X86 instructions.
46
if (!Def->isSubClassOf("X86Inst"))
47
continue;
48
X86Disassembler::RecognizableInstrBase RI(*I);
49
if (!RI.shouldBeEmitted())
50
continue;
51
if ( // Non-parsable instruction defs contain prefix as part of AsmString
52
Def->getValueAsString("AsmVariantName") == "NonParsable" ||
53
// Skip prefix byte
54
RI.Form == X86Local::PrefixByte)
55
continue;
56
std::string Mnemonic = X86Disassembler::getMnemonic(I, Variant);
57
MnemonicToCGInstrMap[Mnemonic].push_back(I);
58
}
59
60
OS << "#ifdef GET_X86_MNEMONIC_TABLES_H\n";
61
OS << "#undef GET_X86_MNEMONIC_TABLES_H\n\n";
62
for (StringRef Mnemonic : MnemonicToCGInstrMap.keys())
63
OS << "bool is" << Mnemonic << "(unsigned Opcode);\n";
64
OS << "#endif // GET_X86_MNEMONIC_TABLES_H\n\n";
65
66
OS << "#ifdef GET_X86_MNEMONIC_TABLES_CPP\n";
67
OS << "#undef GET_X86_MNEMONIC_TABLES_CPP\n\n";
68
for (StringRef Mnemonic : MnemonicToCGInstrMap.keys()) {
69
OS << "bool is" << Mnemonic << "(unsigned Opcode) {\n";
70
auto Mnemonics = MnemonicToCGInstrMap[Mnemonic];
71
if (Mnemonics.size() == 1) {
72
const CodeGenInstruction *CGI = *Mnemonics.begin();
73
OS << "\treturn Opcode == " << CGI->TheDef->getName() << ";\n}\n\n";
74
} else {
75
OS << "\tswitch (Opcode) {\n";
76
for (const CodeGenInstruction *CGI : Mnemonics) {
77
OS << "\tcase " << CGI->TheDef->getName() << ":\n";
78
}
79
OS << "\t\treturn true;\n\t}\n\treturn false;\n}\n\n";
80
}
81
}
82
OS << "#endif // GET_X86_MNEMONIC_TABLES_CPP\n\n";
83
OS << "} // end namespace X86\n} // end namespace llvm";
84
}
85
86
} // namespace
87
88
static TableGen::Emitter::OptClass<X86MnemonicTablesEmitter>
89
X("gen-x86-mnemonic-tables", "Generate X86 mnemonic tables");
90
91