1
- // ==- utils/TableGen/X86CompressEVEXTablesEmitter .cpp - X86 backend-*- C++ -*-//
1
+ // ======== - utils/TableGen/X86InstrMappingEmitter .cpp - X86 backend-*- C++ -*-//
2
2
//
3
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
4
// See https://llvm.org/LICENSE.txt for license information.
5
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
// /
9
- // / This tablegen backend is responsible for emitting the X86 backend EVEX
10
- // / compression tables .
9
+ // / This tablegen backend is responsible for emitting the X86 backend
10
+ // / instruction mapping .
11
11
// /
12
12
// ===----------------------------------------------------------------------===//
13
13
@@ -34,7 +34,7 @@ const std::set<StringRef> NoCompressSet = {
34
34
#include " X86ManualCompressEVEXTables.def"
35
35
};
36
36
37
- class X86CompressEVEXTablesEmitter {
37
+ class X86InstrMappingEmitter {
38
38
RecordKeeper &Records;
39
39
CodeGenTarget Target;
40
40
@@ -49,52 +49,67 @@ class X86CompressEVEXTablesEmitter {
49
49
typedef std::map<StringRef, std::vector<const CodeGenInstruction *>>
50
50
PredicateInstMap;
51
51
52
- std::vector<Entry> Table;
53
52
// Hold all compressed instructions that need to check predicate
54
53
PredicateInstMap PredicateInsts;
55
54
56
55
public:
57
- X86CompressEVEXTablesEmitter (RecordKeeper &R) : Records(R), Target(R) {}
56
+ X86InstrMappingEmitter (RecordKeeper &R) : Records(R), Target(R) {}
58
57
59
58
// run - Output X86 EVEX compression tables.
60
59
void run (raw_ostream &OS);
61
60
62
61
private:
63
- // Prints the given table as a C++ array of type X86CompressEVEXTableEntry
64
- void printTable (const std::vector<Entry> &Table, raw_ostream &OS);
65
- // Prints function which checks target feature for compressed instructions.
66
- void printCheckPredicate (const PredicateInstMap &PredicateInsts,
67
- raw_ostream &OS);
62
+ void emitCompressEVEXTable (ArrayRef<const CodeGenInstruction *> Insts,
63
+ raw_ostream &OS);
64
+ void emitNFTransformTable (ArrayRef<const CodeGenInstruction *> Insts,
65
+ raw_ostream &OS);
66
+
67
+ // Prints the definition of class X86TableEntry.
68
+ void printClassDef (raw_ostream &OS);
69
+ // Prints the given table as a C++ array of type X86TableEntry under the guard
70
+ // \p Macro.
71
+ void printTable (const std::vector<Entry> &Table, StringRef Name,
72
+ StringRef Macro, raw_ostream &OS);
68
73
};
69
74
70
- void X86CompressEVEXTablesEmitter::printTable (const std::vector<Entry> &Table,
71
- raw_ostream &OS) {
75
+ void X86InstrMappingEmitter::printClassDef (raw_ostream &OS) {
76
+ OS << " struct X86TableEntry {\n "
77
+ " uint16_t OldOpc;\n "
78
+ " uint16_t NewOpc;\n "
79
+ " bool operator<(const X86TableEntry &RHS) const {\n "
80
+ " return OldOpc < RHS.OldOpc;\n "
81
+ " }"
82
+ " friend bool operator<(const X86TableEntry &TE, unsigned Opc) {\n "
83
+ " return TE.OldOpc < Opc;\n "
84
+ " }\n "
85
+ " };" ;
86
+
87
+ OS << " \n\n " ;
88
+ }
89
+
90
+ static void printMacroBegin (StringRef Macro, raw_ostream &OS) {
91
+ OS << " \n #ifdef " << Macro << " \n " ;
92
+ }
93
+
94
+ static void printMacroEnd (StringRef Macro, raw_ostream &OS) {
95
+ OS << " #endif // " << Macro << " \n\n " ;
96
+ }
72
97
73
- OS << " static const X86CompressEVEXTableEntry X86CompressEVEXTable[] = {\n " ;
98
+ void X86InstrMappingEmitter::printTable (const std::vector<Entry> &Table,
99
+ StringRef Name, StringRef Macro,
100
+ raw_ostream &OS) {
101
+ printMacroBegin (Macro, OS);
102
+
103
+ OS << " static const X86TableEntry " << Name << " [] = {\n " ;
74
104
75
105
// Print all entries added to the table
76
106
for (const auto &Pair : Table)
77
107
OS << " { X86::" << Pair.first ->TheDef ->getName ()
78
108
<< " , X86::" << Pair.second ->TheDef ->getName () << " },\n " ;
79
109
80
110
OS << " };\n\n " ;
81
- }
82
-
83
- void X86CompressEVEXTablesEmitter::printCheckPredicate (
84
- const PredicateInstMap &PredicateInsts, raw_ostream &OS) {
85
-
86
- OS << " static bool checkPredicate(unsigned Opc, const X86Subtarget "
87
- " *Subtarget) {\n "
88
- << " switch (Opc) {\n "
89
- << " default: return true;\n " ;
90
- for (const auto &[Key, Val] : PredicateInsts) {
91
- for (const auto &Inst : Val)
92
- OS << " case X86::" << Inst->TheDef ->getName () << " :\n " ;
93
- OS << " return " << Key << " ;\n " ;
94
- }
95
111
96
- OS << " }\n " ;
97
- OS << " }\n\n " ;
112
+ printMacroEnd (Macro, OS);
98
113
}
99
114
100
115
static uint8_t byteFromBitsInit (const BitsInit *B) {
@@ -150,18 +165,19 @@ class IsMatch {
150
165
}
151
166
};
152
167
153
- void X86CompressEVEXTablesEmitter::run (raw_ostream &OS) {
154
- emitSourceFileHeader (" X86 EVEX compression tables" , OS);
155
-
156
- ArrayRef<const CodeGenInstruction *> NumberedInstructions =
157
- Target.getInstructionsByEnumValue ();
168
+ static bool isInteresting (const Record *Rec) {
169
+ // _REV instruction should not appear before encoding optimization
170
+ return Rec->isSubClassOf (" X86Inst" ) &&
171
+ !Rec->getValueAsBit (" isAsmParserOnly" ) &&
172
+ !Rec->getName ().ends_with (" _REV" );
173
+ }
158
174
159
- for (const CodeGenInstruction *Inst : NumberedInstructions) {
175
+ void X86InstrMappingEmitter::emitCompressEVEXTable (
176
+ ArrayRef<const CodeGenInstruction *> Insts, raw_ostream &OS) {
177
+ for (const CodeGenInstruction *Inst : Insts) {
160
178
const Record *Rec = Inst->TheDef ;
161
179
StringRef Name = Rec->getName ();
162
- // _REV instruction should not appear before encoding optimization
163
- if (!Rec->isSubClassOf (" X86Inst" ) ||
164
- Rec->getValueAsBit (" isAsmParserOnly" ) || Name.ends_with (" _REV" ))
180
+ if (!isInteresting (Rec))
165
181
continue ;
166
182
167
183
// Promoted legacy instruction is in EVEX space, and has REX2-encoding
@@ -188,6 +204,7 @@ void X86CompressEVEXTablesEmitter::run(raw_ostream &OS) {
188
204
PreCompressionInsts.push_back (Inst);
189
205
}
190
206
207
+ std::vector<Entry> Table;
191
208
for (const CodeGenInstruction *Inst : PreCompressionInsts) {
192
209
const Record *Rec = Inst->TheDef ;
193
210
uint8_t Opcode = byteFromBitsInit (Rec->getValueAsBitsInit (" Opcode" ));
@@ -229,10 +246,53 @@ void X86CompressEVEXTablesEmitter::run(raw_ostream &OS) {
229
246
PredicateInsts[(*It)->getValueAsString (" CondString" )].push_back (NewInst);
230
247
}
231
248
232
- printTable (Table, OS);
233
- printCheckPredicate (PredicateInsts, OS);
249
+ StringRef Macro = " GET_X86_COMPRESS_EVEX_TABLE" ;
250
+ printTable (Table, " X86CompressEVEXTable" , Macro, OS);
251
+
252
+ // Prints function which checks target feature for compressed instructions.
253
+ printMacroBegin (Macro, OS);
254
+ OS << " static bool checkPredicate(unsigned Opc, const X86Subtarget "
255
+ " *Subtarget) {\n "
256
+ << " switch (Opc) {\n "
257
+ << " default: return true;\n " ;
258
+ for (const auto &[Key, Val] : PredicateInsts) {
259
+ for (const auto &Inst : Val)
260
+ OS << " case X86::" << Inst->TheDef ->getName () << " :\n " ;
261
+ OS << " return " << Key << " ;\n " ;
262
+ }
263
+ OS << " }\n " ;
264
+ OS << " }\n\n " ;
265
+ printMacroEnd (Macro, OS);
266
+ }
267
+
268
+ void X86InstrMappingEmitter::emitNFTransformTable (
269
+ ArrayRef<const CodeGenInstruction *> Insts, raw_ostream &OS) {
270
+ std::vector<Entry> Table;
271
+ for (const CodeGenInstruction *Inst : Insts) {
272
+ const Record *Rec = Inst->TheDef ;
273
+ if (!isInteresting (Rec))
274
+ continue ;
275
+ std::string Name = Rec->getName ().str ();
276
+ auto Pos = Name.find (" _NF" );
277
+ if (Pos == std::string::npos)
278
+ continue ;
279
+
280
+ if (auto *NewRec = Records.getDef (Name.erase (Pos, 3 )))
281
+ Table.push_back (std::pair (&Target.getInstruction (NewRec), Inst));
282
+ }
283
+ printTable (Table, " X86NFTransformTable" , " GET_X86_NF_TRANSFORM_TABLE" , OS);
284
+ }
285
+
286
+ void X86InstrMappingEmitter::run (raw_ostream &OS) {
287
+ emitSourceFileHeader (" X86 instruction mapping" , OS);
288
+
289
+ ArrayRef<const CodeGenInstruction *> Insts =
290
+ Target.getInstructionsByEnumValue ();
291
+ printClassDef (OS);
292
+ emitCompressEVEXTable (Insts, OS);
293
+ emitNFTransformTable (Insts, OS);
234
294
}
235
295
} // namespace
236
296
237
- static TableGen::Emitter::OptClass<X86CompressEVEXTablesEmitter >
238
- X (" gen-x86-compress-evex-tables " , " Generate X86 EVEX compression tables " );
297
+ static TableGen::Emitter::OptClass<X86InstrMappingEmitter >
298
+ X (" gen-x86-instr-mapping " , " Generate X86 instruction mapping " );
0 commit comments