1- // ==- utils/TableGen/X86CompressEVEXTablesEmitter .cpp - X86 backend-*- C++ -*-//
1+ // ======== - utils/TableGen/X86InstrMappingEmitter .cpp - X86 backend-*- C++ -*-//
22//
33// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44// See https://llvm.org/LICENSE.txt for license information.
55// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66//
77// ===----------------------------------------------------------------------===//
88// /
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 .
1111// /
1212// ===----------------------------------------------------------------------===//
1313
@@ -34,7 +34,7 @@ const std::set<StringRef> NoCompressSet = {
3434#include " X86ManualCompressEVEXTables.def"
3535};
3636
37- class X86CompressEVEXTablesEmitter {
37+ class X86InstrMappingEmitter {
3838 RecordKeeper &Records;
3939 CodeGenTarget Target;
4040
@@ -49,52 +49,67 @@ class X86CompressEVEXTablesEmitter {
4949 typedef std::map<StringRef, std::vector<const CodeGenInstruction *>>
5050 PredicateInstMap;
5151
52- std::vector<Entry> Table;
5352 // Hold all compressed instructions that need to check predicate
5453 PredicateInstMap PredicateInsts;
5554
5655public:
57- X86CompressEVEXTablesEmitter (RecordKeeper &R) : Records(R), Target(R) {}
56+ X86InstrMappingEmitter (RecordKeeper &R) : Records(R), Target(R) {}
5857
5958 // run - Output X86 EVEX compression tables.
6059 void run (raw_ostream &OS);
6160
6261private:
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);
6873};
6974
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+ }
7297
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 " ;
74104
75105 // Print all entries added to the table
76106 for (const auto &Pair : Table)
77107 OS << " { X86::" << Pair.first ->TheDef ->getName ()
78108 << " , X86::" << Pair.second ->TheDef ->getName () << " },\n " ;
79109
80110 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- }
95111
96- OS << " }\n " ;
97- OS << " }\n\n " ;
112+ printMacroEnd (Macro, OS);
98113}
99114
100115static uint8_t byteFromBitsInit (const BitsInit *B) {
@@ -150,18 +165,19 @@ class IsMatch {
150165 }
151166};
152167
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+ }
158174
159- for (const CodeGenInstruction *Inst : NumberedInstructions) {
175+ void X86InstrMappingEmitter::emitCompressEVEXTable (
176+ ArrayRef<const CodeGenInstruction *> Insts, raw_ostream &OS) {
177+ for (const CodeGenInstruction *Inst : Insts) {
160178 const Record *Rec = Inst->TheDef ;
161179 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))
165181 continue ;
166182
167183 // Promoted legacy instruction is in EVEX space, and has REX2-encoding
@@ -188,6 +204,7 @@ void X86CompressEVEXTablesEmitter::run(raw_ostream &OS) {
188204 PreCompressionInsts.push_back (Inst);
189205 }
190206
207+ std::vector<Entry> Table;
191208 for (const CodeGenInstruction *Inst : PreCompressionInsts) {
192209 const Record *Rec = Inst->TheDef ;
193210 uint8_t Opcode = byteFromBitsInit (Rec->getValueAsBitsInit (" Opcode" ));
@@ -229,10 +246,53 @@ void X86CompressEVEXTablesEmitter::run(raw_ostream &OS) {
229246 PredicateInsts[(*It)->getValueAsString (" CondString" )].push_back (NewInst);
230247 }
231248
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);
234294}
235295} // namespace
236296
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