xref: /minix3/external/bsd/llvm/dist/llvm/utils/TableGen/InstrInfoEmitter.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This tablegen backend is responsible for emitting a description of the target
11f4a2713aSLionel Sambuc // instruction set for the code generator.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc 
15f4a2713aSLionel Sambuc 
16f4a2713aSLionel Sambuc #include "CodeGenDAGPatterns.h"
17f4a2713aSLionel Sambuc #include "CodeGenSchedule.h"
18f4a2713aSLionel Sambuc #include "CodeGenTarget.h"
19f4a2713aSLionel Sambuc #include "SequenceToOffsetTable.h"
20f4a2713aSLionel Sambuc #include "TableGenBackends.h"
21f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
22f4a2713aSLionel Sambuc #include "llvm/TableGen/Error.h"
23f4a2713aSLionel Sambuc #include "llvm/TableGen/Record.h"
24f4a2713aSLionel Sambuc #include "llvm/TableGen/TableGenBackend.h"
25f4a2713aSLionel Sambuc #include <algorithm>
26f4a2713aSLionel Sambuc #include <cstdio>
27f4a2713aSLionel Sambuc #include <map>
28f4a2713aSLionel Sambuc #include <vector>
29f4a2713aSLionel Sambuc using namespace llvm;
30f4a2713aSLionel Sambuc 
31f4a2713aSLionel Sambuc namespace {
32f4a2713aSLionel Sambuc class InstrInfoEmitter {
33f4a2713aSLionel Sambuc   RecordKeeper &Records;
34f4a2713aSLionel Sambuc   CodeGenDAGPatterns CDP;
35f4a2713aSLionel Sambuc   const CodeGenSchedModels &SchedModels;
36f4a2713aSLionel Sambuc 
37f4a2713aSLionel Sambuc public:
InstrInfoEmitter(RecordKeeper & R)38f4a2713aSLionel Sambuc   InstrInfoEmitter(RecordKeeper &R):
39f4a2713aSLionel Sambuc     Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}
40f4a2713aSLionel Sambuc 
41f4a2713aSLionel Sambuc   // run - Output the instruction set description.
42f4a2713aSLionel Sambuc   void run(raw_ostream &OS);
43f4a2713aSLionel Sambuc 
44f4a2713aSLionel Sambuc private:
45f4a2713aSLionel Sambuc   void emitEnums(raw_ostream &OS);
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc   typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
48f4a2713aSLionel Sambuc 
49f4a2713aSLionel Sambuc   /// The keys of this map are maps which have OpName enum values as their keys
50f4a2713aSLionel Sambuc   /// and instruction operand indices as their values.  The values of this map
51f4a2713aSLionel Sambuc   /// are lists of instruction names.
52f4a2713aSLionel Sambuc   typedef std::map<std::map<unsigned, unsigned>,
53f4a2713aSLionel Sambuc                    std::vector<std::string> > OpNameMapTy;
54f4a2713aSLionel Sambuc   typedef std::map<std::string, unsigned>::iterator StrUintMapIter;
55f4a2713aSLionel Sambuc   void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
56f4a2713aSLionel Sambuc                   Record *InstrInfo,
57f4a2713aSLionel Sambuc                   std::map<std::vector<Record*>, unsigned> &EL,
58f4a2713aSLionel Sambuc                   const OperandInfoMapTy &OpInfo,
59f4a2713aSLionel Sambuc                   raw_ostream &OS);
60f4a2713aSLionel Sambuc   void emitOperandTypesEnum(raw_ostream &OS, const CodeGenTarget &Target);
61f4a2713aSLionel Sambuc   void initOperandMapData(
62*0a6a1f1dSLionel Sambuc             const std::vector<const CodeGenInstruction *> &NumberedInstructions,
63f4a2713aSLionel Sambuc             const std::string &Namespace,
64f4a2713aSLionel Sambuc             std::map<std::string, unsigned> &Operands,
65f4a2713aSLionel Sambuc             OpNameMapTy &OperandMap);
66f4a2713aSLionel Sambuc   void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target,
67f4a2713aSLionel Sambuc             const std::vector<const CodeGenInstruction*> &NumberedInstructions);
68f4a2713aSLionel Sambuc 
69f4a2713aSLionel Sambuc   // Operand information.
70f4a2713aSLionel Sambuc   void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
71f4a2713aSLionel Sambuc   std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
72f4a2713aSLionel Sambuc };
73f4a2713aSLionel Sambuc } // End anonymous namespace
74f4a2713aSLionel Sambuc 
PrintDefList(const std::vector<Record * > & Uses,unsigned Num,raw_ostream & OS)75f4a2713aSLionel Sambuc static void PrintDefList(const std::vector<Record*> &Uses,
76f4a2713aSLionel Sambuc                          unsigned Num, raw_ostream &OS) {
77f4a2713aSLionel Sambuc   OS << "static const uint16_t ImplicitList" << Num << "[] = { ";
78f4a2713aSLionel Sambuc   for (unsigned i = 0, e = Uses.size(); i != e; ++i)
79f4a2713aSLionel Sambuc     OS << getQualifiedName(Uses[i]) << ", ";
80f4a2713aSLionel Sambuc   OS << "0 };\n";
81f4a2713aSLionel Sambuc }
82f4a2713aSLionel Sambuc 
83f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
84f4a2713aSLionel Sambuc // Operand Info Emission.
85f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
86f4a2713aSLionel Sambuc 
87f4a2713aSLionel Sambuc std::vector<std::string>
GetOperandInfo(const CodeGenInstruction & Inst)88f4a2713aSLionel Sambuc InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
89f4a2713aSLionel Sambuc   std::vector<std::string> Result;
90f4a2713aSLionel Sambuc 
91*0a6a1f1dSLionel Sambuc   for (auto &Op : Inst.Operands) {
92f4a2713aSLionel Sambuc     // Handle aggregate operands and normal operands the same way by expanding
93f4a2713aSLionel Sambuc     // either case into a list of operands for this op.
94f4a2713aSLionel Sambuc     std::vector<CGIOperandList::OperandInfo> OperandList;
95f4a2713aSLionel Sambuc 
96f4a2713aSLionel Sambuc     // This might be a multiple operand thing.  Targets like X86 have
97f4a2713aSLionel Sambuc     // registers in their multi-operand operands.  It may also be an anonymous
98f4a2713aSLionel Sambuc     // operand, which has a single operand, but no declared class for the
99f4a2713aSLionel Sambuc     // operand.
100*0a6a1f1dSLionel Sambuc     DagInit *MIOI = Op.MIOperandInfo;
101f4a2713aSLionel Sambuc 
102f4a2713aSLionel Sambuc     if (!MIOI || MIOI->getNumArgs() == 0) {
103f4a2713aSLionel Sambuc       // Single, anonymous, operand.
104*0a6a1f1dSLionel Sambuc       OperandList.push_back(Op);
105f4a2713aSLionel Sambuc     } else {
106*0a6a1f1dSLionel Sambuc       for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) {
107*0a6a1f1dSLionel Sambuc         OperandList.push_back(Op);
108f4a2713aSLionel Sambuc 
109f4a2713aSLionel Sambuc         Record *OpR = cast<DefInit>(MIOI->getArg(j))->getDef();
110f4a2713aSLionel Sambuc         OperandList.back().Rec = OpR;
111f4a2713aSLionel Sambuc       }
112f4a2713aSLionel Sambuc     }
113f4a2713aSLionel Sambuc 
114f4a2713aSLionel Sambuc     for (unsigned j = 0, e = OperandList.size(); j != e; ++j) {
115f4a2713aSLionel Sambuc       Record *OpR = OperandList[j].Rec;
116f4a2713aSLionel Sambuc       std::string Res;
117f4a2713aSLionel Sambuc 
118f4a2713aSLionel Sambuc       if (OpR->isSubClassOf("RegisterOperand"))
119f4a2713aSLionel Sambuc         OpR = OpR->getValueAsDef("RegClass");
120f4a2713aSLionel Sambuc       if (OpR->isSubClassOf("RegisterClass"))
121f4a2713aSLionel Sambuc         Res += getQualifiedName(OpR) + "RegClassID, ";
122f4a2713aSLionel Sambuc       else if (OpR->isSubClassOf("PointerLikeRegClass"))
123f4a2713aSLionel Sambuc         Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", ";
124f4a2713aSLionel Sambuc       else
125f4a2713aSLionel Sambuc         // -1 means the operand does not have a fixed register class.
126f4a2713aSLionel Sambuc         Res += "-1, ";
127f4a2713aSLionel Sambuc 
128f4a2713aSLionel Sambuc       // Fill in applicable flags.
129f4a2713aSLionel Sambuc       Res += "0";
130f4a2713aSLionel Sambuc 
131f4a2713aSLionel Sambuc       // Ptr value whose register class is resolved via callback.
132f4a2713aSLionel Sambuc       if (OpR->isSubClassOf("PointerLikeRegClass"))
133f4a2713aSLionel Sambuc         Res += "|(1<<MCOI::LookupPtrRegClass)";
134f4a2713aSLionel Sambuc 
135f4a2713aSLionel Sambuc       // Predicate operands.  Check to see if the original unexpanded operand
136f4a2713aSLionel Sambuc       // was of type PredicateOp.
137*0a6a1f1dSLionel Sambuc       if (Op.Rec->isSubClassOf("PredicateOp"))
138f4a2713aSLionel Sambuc         Res += "|(1<<MCOI::Predicate)";
139f4a2713aSLionel Sambuc 
140f4a2713aSLionel Sambuc       // Optional def operands.  Check to see if the original unexpanded operand
141f4a2713aSLionel Sambuc       // was of type OptionalDefOperand.
142*0a6a1f1dSLionel Sambuc       if (Op.Rec->isSubClassOf("OptionalDefOperand"))
143f4a2713aSLionel Sambuc         Res += "|(1<<MCOI::OptionalDef)";
144f4a2713aSLionel Sambuc 
145f4a2713aSLionel Sambuc       // Fill in operand type.
146*0a6a1f1dSLionel Sambuc       Res += ", ";
147*0a6a1f1dSLionel Sambuc       assert(!Op.OperandType.empty() && "Invalid operand type.");
148*0a6a1f1dSLionel Sambuc       Res += Op.OperandType;
149f4a2713aSLionel Sambuc 
150f4a2713aSLionel Sambuc       // Fill in constraint info.
151f4a2713aSLionel Sambuc       Res += ", ";
152f4a2713aSLionel Sambuc 
153f4a2713aSLionel Sambuc       const CGIOperandList::ConstraintInfo &Constraint =
154*0a6a1f1dSLionel Sambuc         Op.Constraints[j];
155f4a2713aSLionel Sambuc       if (Constraint.isNone())
156f4a2713aSLionel Sambuc         Res += "0";
157f4a2713aSLionel Sambuc       else if (Constraint.isEarlyClobber())
158f4a2713aSLionel Sambuc         Res += "(1 << MCOI::EARLY_CLOBBER)";
159f4a2713aSLionel Sambuc       else {
160f4a2713aSLionel Sambuc         assert(Constraint.isTied());
161f4a2713aSLionel Sambuc         Res += "((" + utostr(Constraint.getTiedOperand()) +
162f4a2713aSLionel Sambuc                     " << 16) | (1 << MCOI::TIED_TO))";
163f4a2713aSLionel Sambuc       }
164f4a2713aSLionel Sambuc 
165f4a2713aSLionel Sambuc       Result.push_back(Res);
166f4a2713aSLionel Sambuc     }
167f4a2713aSLionel Sambuc   }
168f4a2713aSLionel Sambuc 
169f4a2713aSLionel Sambuc   return Result;
170f4a2713aSLionel Sambuc }
171f4a2713aSLionel Sambuc 
EmitOperandInfo(raw_ostream & OS,OperandInfoMapTy & OperandInfoIDs)172f4a2713aSLionel Sambuc void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
173f4a2713aSLionel Sambuc                                        OperandInfoMapTy &OperandInfoIDs) {
174f4a2713aSLionel Sambuc   // ID #0 is for no operand info.
175f4a2713aSLionel Sambuc   unsigned OperandListNum = 0;
176f4a2713aSLionel Sambuc   OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum;
177f4a2713aSLionel Sambuc 
178f4a2713aSLionel Sambuc   OS << "\n";
179f4a2713aSLionel Sambuc   const CodeGenTarget &Target = CDP.getTargetInfo();
180*0a6a1f1dSLionel Sambuc   for (const CodeGenInstruction *Inst : Target.instructions()) {
181*0a6a1f1dSLionel Sambuc     std::vector<std::string> OperandInfo = GetOperandInfo(*Inst);
182f4a2713aSLionel Sambuc     unsigned &N = OperandInfoIDs[OperandInfo];
183f4a2713aSLionel Sambuc     if (N != 0) continue;
184f4a2713aSLionel Sambuc 
185f4a2713aSLionel Sambuc     N = ++OperandListNum;
186f4a2713aSLionel Sambuc     OS << "static const MCOperandInfo OperandInfo" << N << "[] = { ";
187*0a6a1f1dSLionel Sambuc     for (const std::string &Info : OperandInfo)
188*0a6a1f1dSLionel Sambuc       OS << "{ " << Info << " }, ";
189f4a2713aSLionel Sambuc     OS << "};\n";
190f4a2713aSLionel Sambuc   }
191f4a2713aSLionel Sambuc }
192f4a2713aSLionel Sambuc 
193f4a2713aSLionel Sambuc 
194f4a2713aSLionel Sambuc /// Initialize data structures for generating operand name mappings.
195f4a2713aSLionel Sambuc ///
196f4a2713aSLionel Sambuc /// \param Operands [out] A map used to generate the OpName enum with operand
197f4a2713aSLionel Sambuc ///        names as its keys and operand enum values as its values.
198f4a2713aSLionel Sambuc /// \param OperandMap [out] A map for representing the operand name mappings for
199f4a2713aSLionel Sambuc ///        each instructions.  This is used to generate the OperandMap table as
200f4a2713aSLionel Sambuc ///        well as the getNamedOperandIdx() function.
initOperandMapData(const std::vector<const CodeGenInstruction * > & NumberedInstructions,const std::string & Namespace,std::map<std::string,unsigned> & Operands,OpNameMapTy & OperandMap)201f4a2713aSLionel Sambuc void InstrInfoEmitter::initOperandMapData(
202*0a6a1f1dSLionel Sambuc         const std::vector<const CodeGenInstruction *> &NumberedInstructions,
203f4a2713aSLionel Sambuc         const std::string &Namespace,
204f4a2713aSLionel Sambuc         std::map<std::string, unsigned> &Operands,
205f4a2713aSLionel Sambuc         OpNameMapTy &OperandMap) {
206f4a2713aSLionel Sambuc 
207f4a2713aSLionel Sambuc   unsigned NumOperands = 0;
208*0a6a1f1dSLionel Sambuc   for (const CodeGenInstruction *Inst : NumberedInstructions) {
209*0a6a1f1dSLionel Sambuc     if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable"))
210f4a2713aSLionel Sambuc       continue;
211f4a2713aSLionel Sambuc     std::map<unsigned, unsigned> OpList;
212*0a6a1f1dSLionel Sambuc     for (const auto &Info : Inst->Operands) {
213f4a2713aSLionel Sambuc       StrUintMapIter I = Operands.find(Info.Name);
214f4a2713aSLionel Sambuc 
215f4a2713aSLionel Sambuc       if (I == Operands.end()) {
216f4a2713aSLionel Sambuc         I = Operands.insert(Operands.begin(),
217f4a2713aSLionel Sambuc                     std::pair<std::string, unsigned>(Info.Name, NumOperands++));
218f4a2713aSLionel Sambuc       }
219f4a2713aSLionel Sambuc       OpList[I->second] = Info.MIOperandNo;
220f4a2713aSLionel Sambuc     }
221f4a2713aSLionel Sambuc     OperandMap[OpList].push_back(Namespace + "::" + Inst->TheDef->getName());
222f4a2713aSLionel Sambuc   }
223f4a2713aSLionel Sambuc }
224f4a2713aSLionel Sambuc 
225f4a2713aSLionel Sambuc /// Generate a table and function for looking up the indices of operands by
226f4a2713aSLionel Sambuc /// name.
227f4a2713aSLionel Sambuc ///
228f4a2713aSLionel Sambuc /// This code generates:
229f4a2713aSLionel Sambuc /// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry
230f4a2713aSLionel Sambuc ///   for each operand name.
231f4a2713aSLionel Sambuc /// - A 2-dimensional table called OperandMap for mapping OpName enum values to
232f4a2713aSLionel Sambuc ///   operand indices.
233f4a2713aSLionel Sambuc /// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
234f4a2713aSLionel Sambuc ///   for looking up the operand index for an instruction, given a value from
235f4a2713aSLionel Sambuc ///   OpName enum
emitOperandNameMappings(raw_ostream & OS,const CodeGenTarget & Target,const std::vector<const CodeGenInstruction * > & NumberedInstructions)236f4a2713aSLionel Sambuc void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS,
237f4a2713aSLionel Sambuc            const CodeGenTarget &Target,
238f4a2713aSLionel Sambuc            const std::vector<const CodeGenInstruction*> &NumberedInstructions) {
239f4a2713aSLionel Sambuc 
240f4a2713aSLionel Sambuc   const std::string &Namespace = Target.getInstNamespace();
241f4a2713aSLionel Sambuc   std::string OpNameNS = "OpName";
242f4a2713aSLionel Sambuc   // Map of operand names to their enumeration value.  This will be used to
243f4a2713aSLionel Sambuc   // generate the OpName enum.
244f4a2713aSLionel Sambuc   std::map<std::string, unsigned> Operands;
245f4a2713aSLionel Sambuc   OpNameMapTy OperandMap;
246f4a2713aSLionel Sambuc 
247f4a2713aSLionel Sambuc   initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap);
248f4a2713aSLionel Sambuc 
249f4a2713aSLionel Sambuc   OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n";
250f4a2713aSLionel Sambuc   OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n";
251f4a2713aSLionel Sambuc   OS << "namespace llvm {";
252f4a2713aSLionel Sambuc   OS << "namespace " << Namespace << " {\n";
253f4a2713aSLionel Sambuc   OS << "namespace " << OpNameNS << " { \n";
254f4a2713aSLionel Sambuc   OS << "enum {\n";
255*0a6a1f1dSLionel Sambuc   for (const auto &Op : Operands)
256*0a6a1f1dSLionel Sambuc     OS << "  " << Op.first << " = " << Op.second << ",\n";
257f4a2713aSLionel Sambuc 
258f4a2713aSLionel Sambuc   OS << "OPERAND_LAST";
259f4a2713aSLionel Sambuc   OS << "\n};\n";
260f4a2713aSLionel Sambuc   OS << "} // End namespace OpName\n";
261f4a2713aSLionel Sambuc   OS << "} // End namespace " << Namespace << "\n";
262f4a2713aSLionel Sambuc   OS << "} // End namespace llvm\n";
263f4a2713aSLionel Sambuc   OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n";
264f4a2713aSLionel Sambuc 
265f4a2713aSLionel Sambuc   OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
266f4a2713aSLionel Sambuc   OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
267f4a2713aSLionel Sambuc   OS << "namespace llvm {";
268f4a2713aSLionel Sambuc   OS << "namespace " << Namespace << " {\n";
269*0a6a1f1dSLionel Sambuc   OS << "LLVM_READONLY\n";
270f4a2713aSLionel Sambuc   OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n";
271f4a2713aSLionel Sambuc   if (!Operands.empty()) {
272f4a2713aSLionel Sambuc     OS << "  static const int16_t OperandMap [][" << Operands.size()
273f4a2713aSLionel Sambuc        << "] = {\n";
274*0a6a1f1dSLionel Sambuc     for (const auto &Entry : OperandMap) {
275*0a6a1f1dSLionel Sambuc       const std::map<unsigned, unsigned> &OpList = Entry.first;
276f4a2713aSLionel Sambuc       OS << "{";
277f4a2713aSLionel Sambuc 
278f4a2713aSLionel Sambuc       // Emit a row of the OperandMap table
279*0a6a1f1dSLionel Sambuc       for (unsigned i = 0, e = Operands.size(); i != e; ++i)
280*0a6a1f1dSLionel Sambuc         OS << (OpList.count(i) == 0 ? -1 : (int)OpList.find(i)->second) << ", ";
281f4a2713aSLionel Sambuc 
282f4a2713aSLionel Sambuc       OS << "},\n";
283f4a2713aSLionel Sambuc     }
284f4a2713aSLionel Sambuc     OS << "};\n";
285f4a2713aSLionel Sambuc 
286f4a2713aSLionel Sambuc     OS << "  switch(Opcode) {\n";
287f4a2713aSLionel Sambuc     unsigned TableIndex = 0;
288*0a6a1f1dSLionel Sambuc     for (const auto &Entry : OperandMap) {
289*0a6a1f1dSLionel Sambuc       for (const std::string &Name : Entry.second)
290*0a6a1f1dSLionel Sambuc         OS << "  case " << Name << ":\n";
291f4a2713aSLionel Sambuc 
292f4a2713aSLionel Sambuc       OS << "    return OperandMap[" << TableIndex++ << "][NamedIdx];\n";
293f4a2713aSLionel Sambuc     }
294f4a2713aSLionel Sambuc     OS << "    default: return -1;\n";
295f4a2713aSLionel Sambuc     OS << "  }\n";
296f4a2713aSLionel Sambuc   } else {
297f4a2713aSLionel Sambuc     // There are no operands, so no need to emit anything
298f4a2713aSLionel Sambuc     OS << "  return -1;\n";
299f4a2713aSLionel Sambuc   }
300f4a2713aSLionel Sambuc   OS << "}\n";
301f4a2713aSLionel Sambuc   OS << "} // End namespace " << Namespace << "\n";
302f4a2713aSLionel Sambuc   OS << "} // End namespace llvm\n";
303f4a2713aSLionel Sambuc   OS << "#endif //GET_INSTRINFO_NAMED_OPS\n";
304f4a2713aSLionel Sambuc 
305f4a2713aSLionel Sambuc }
306f4a2713aSLionel Sambuc 
307f4a2713aSLionel Sambuc /// Generate an enum for all the operand types for this target, under the
308f4a2713aSLionel Sambuc /// llvm::TargetNamespace::OpTypes namespace.
309f4a2713aSLionel Sambuc /// Operand types are all definitions derived of the Operand Target.td class.
emitOperandTypesEnum(raw_ostream & OS,const CodeGenTarget & Target)310f4a2713aSLionel Sambuc void InstrInfoEmitter::emitOperandTypesEnum(raw_ostream &OS,
311f4a2713aSLionel Sambuc                                             const CodeGenTarget &Target) {
312f4a2713aSLionel Sambuc 
313f4a2713aSLionel Sambuc   const std::string &Namespace = Target.getInstNamespace();
314f4a2713aSLionel Sambuc   std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand");
315f4a2713aSLionel Sambuc 
316f4a2713aSLionel Sambuc   OS << "\n#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
317f4a2713aSLionel Sambuc   OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
318f4a2713aSLionel Sambuc   OS << "namespace llvm {";
319f4a2713aSLionel Sambuc   OS << "namespace " << Namespace << " {\n";
320f4a2713aSLionel Sambuc   OS << "namespace OpTypes { \n";
321f4a2713aSLionel Sambuc   OS << "enum OperandType {\n";
322f4a2713aSLionel Sambuc 
323*0a6a1f1dSLionel Sambuc   unsigned EnumVal = 0;
324*0a6a1f1dSLionel Sambuc   for (const Record *Op : Operands) {
325*0a6a1f1dSLionel Sambuc     if (!Op->isAnonymous())
326*0a6a1f1dSLionel Sambuc       OS << "  " << Op->getName() << " = " << EnumVal << ",\n";
327*0a6a1f1dSLionel Sambuc     ++EnumVal;
328f4a2713aSLionel Sambuc   }
329f4a2713aSLionel Sambuc 
330f4a2713aSLionel Sambuc   OS << "  OPERAND_TYPE_LIST_END" << "\n};\n";
331f4a2713aSLionel Sambuc   OS << "} // End namespace OpTypes\n";
332f4a2713aSLionel Sambuc   OS << "} // End namespace " << Namespace << "\n";
333f4a2713aSLionel Sambuc   OS << "} // End namespace llvm\n";
334f4a2713aSLionel Sambuc   OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
335f4a2713aSLionel Sambuc }
336f4a2713aSLionel Sambuc 
337f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
338f4a2713aSLionel Sambuc // Main Output.
339f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
340f4a2713aSLionel Sambuc 
341f4a2713aSLionel Sambuc // run - Emit the main instruction description records for the target...
run(raw_ostream & OS)342f4a2713aSLionel Sambuc void InstrInfoEmitter::run(raw_ostream &OS) {
343f4a2713aSLionel Sambuc   emitSourceFileHeader("Target Instruction Enum Values", OS);
344f4a2713aSLionel Sambuc   emitEnums(OS);
345f4a2713aSLionel Sambuc 
346f4a2713aSLionel Sambuc   emitSourceFileHeader("Target Instruction Descriptors", OS);
347f4a2713aSLionel Sambuc 
348f4a2713aSLionel Sambuc   OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n";
349f4a2713aSLionel Sambuc   OS << "#undef GET_INSTRINFO_MC_DESC\n";
350f4a2713aSLionel Sambuc 
351f4a2713aSLionel Sambuc   OS << "namespace llvm {\n\n";
352f4a2713aSLionel Sambuc 
353f4a2713aSLionel Sambuc   CodeGenTarget &Target = CDP.getTargetInfo();
354f4a2713aSLionel Sambuc   const std::string &TargetName = Target.getName();
355f4a2713aSLionel Sambuc   Record *InstrInfo = Target.getInstructionSet();
356f4a2713aSLionel Sambuc 
357f4a2713aSLionel Sambuc   // Keep track of all of the def lists we have emitted already.
358f4a2713aSLionel Sambuc   std::map<std::vector<Record*>, unsigned> EmittedLists;
359f4a2713aSLionel Sambuc   unsigned ListNumber = 0;
360f4a2713aSLionel Sambuc 
361f4a2713aSLionel Sambuc   // Emit all of the instruction's implicit uses and defs.
362*0a6a1f1dSLionel Sambuc   for (const CodeGenInstruction *II : Target.instructions()) {
363*0a6a1f1dSLionel Sambuc     Record *Inst = II->TheDef;
364f4a2713aSLionel Sambuc     std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
365f4a2713aSLionel Sambuc     if (!Uses.empty()) {
366f4a2713aSLionel Sambuc       unsigned &IL = EmittedLists[Uses];
367f4a2713aSLionel Sambuc       if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS);
368f4a2713aSLionel Sambuc     }
369f4a2713aSLionel Sambuc     std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
370f4a2713aSLionel Sambuc     if (!Defs.empty()) {
371f4a2713aSLionel Sambuc       unsigned &IL = EmittedLists[Defs];
372f4a2713aSLionel Sambuc       if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS);
373f4a2713aSLionel Sambuc     }
374f4a2713aSLionel Sambuc   }
375f4a2713aSLionel Sambuc 
376f4a2713aSLionel Sambuc   OperandInfoMapTy OperandInfoIDs;
377f4a2713aSLionel Sambuc 
378f4a2713aSLionel Sambuc   // Emit all of the operand info records.
379f4a2713aSLionel Sambuc   EmitOperandInfo(OS, OperandInfoIDs);
380f4a2713aSLionel Sambuc 
381f4a2713aSLionel Sambuc   // Emit all of the MCInstrDesc records in their ENUM ordering.
382f4a2713aSLionel Sambuc   //
383f4a2713aSLionel Sambuc   OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n";
384f4a2713aSLionel Sambuc   const std::vector<const CodeGenInstruction*> &NumberedInstructions =
385f4a2713aSLionel Sambuc     Target.getInstructionsByEnumValue();
386f4a2713aSLionel Sambuc 
387*0a6a1f1dSLionel Sambuc   SequenceToOffsetTable<std::string> InstrNames;
388*0a6a1f1dSLionel Sambuc   unsigned Num = 0;
389*0a6a1f1dSLionel Sambuc   for (const CodeGenInstruction *Inst : NumberedInstructions) {
390*0a6a1f1dSLionel Sambuc     // Keep a list of the instruction names.
391*0a6a1f1dSLionel Sambuc     InstrNames.add(Inst->TheDef->getName());
392*0a6a1f1dSLionel Sambuc     // Emit the record into the table.
393*0a6a1f1dSLionel Sambuc     emitRecord(*Inst, Num++, InstrInfo, EmittedLists, OperandInfoIDs, OS);
394*0a6a1f1dSLionel Sambuc   }
395f4a2713aSLionel Sambuc   OS << "};\n\n";
396f4a2713aSLionel Sambuc 
397*0a6a1f1dSLionel Sambuc   // Emit the array of instruction names.
398f4a2713aSLionel Sambuc   InstrNames.layout();
399f4a2713aSLionel Sambuc   OS << "extern const char " << TargetName << "InstrNameData[] = {\n";
400f4a2713aSLionel Sambuc   InstrNames.emit(OS, printChar);
401f4a2713aSLionel Sambuc   OS << "};\n\n";
402f4a2713aSLionel Sambuc 
403f4a2713aSLionel Sambuc   OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {";
404*0a6a1f1dSLionel Sambuc   Num = 0;
405*0a6a1f1dSLionel Sambuc   for (const CodeGenInstruction *Inst : NumberedInstructions) {
406*0a6a1f1dSLionel Sambuc     // Newline every eight entries.
407*0a6a1f1dSLionel Sambuc     if (Num % 8 == 0)
408f4a2713aSLionel Sambuc       OS << "\n    ";
409*0a6a1f1dSLionel Sambuc     OS << InstrNames.get(Inst->TheDef->getName()) << "U, ";
410*0a6a1f1dSLionel Sambuc     ++Num;
411f4a2713aSLionel Sambuc   }
412f4a2713aSLionel Sambuc 
413f4a2713aSLionel Sambuc   OS << "\n};\n\n";
414f4a2713aSLionel Sambuc 
415f4a2713aSLionel Sambuc   // MCInstrInfo initialization routine.
416f4a2713aSLionel Sambuc   OS << "static inline void Init" << TargetName
417f4a2713aSLionel Sambuc      << "MCInstrInfo(MCInstrInfo *II) {\n";
418f4a2713aSLionel Sambuc   OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, "
419f4a2713aSLionel Sambuc      << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
420f4a2713aSLionel Sambuc      << NumberedInstructions.size() << ");\n}\n\n";
421f4a2713aSLionel Sambuc 
422f4a2713aSLionel Sambuc   OS << "} // End llvm namespace \n";
423f4a2713aSLionel Sambuc 
424f4a2713aSLionel Sambuc   OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
425f4a2713aSLionel Sambuc 
426f4a2713aSLionel Sambuc   // Create a TargetInstrInfo subclass to hide the MC layer initialization.
427f4a2713aSLionel Sambuc   OS << "\n#ifdef GET_INSTRINFO_HEADER\n";
428f4a2713aSLionel Sambuc   OS << "#undef GET_INSTRINFO_HEADER\n";
429f4a2713aSLionel Sambuc 
430f4a2713aSLionel Sambuc   std::string ClassName = TargetName + "GenInstrInfo";
431f4a2713aSLionel Sambuc   OS << "namespace llvm {\n";
432f4a2713aSLionel Sambuc   OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
433f4a2713aSLionel Sambuc      << "  explicit " << ClassName << "(int SO = -1, int DO = -1);\n"
434f4a2713aSLionel Sambuc      << "  virtual ~" << ClassName << "();\n"
435f4a2713aSLionel Sambuc      << "};\n";
436f4a2713aSLionel Sambuc   OS << "} // End llvm namespace \n";
437f4a2713aSLionel Sambuc 
438f4a2713aSLionel Sambuc   OS << "#endif // GET_INSTRINFO_HEADER\n\n";
439f4a2713aSLionel Sambuc 
440f4a2713aSLionel Sambuc   OS << "\n#ifdef GET_INSTRINFO_CTOR_DTOR\n";
441f4a2713aSLionel Sambuc   OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
442f4a2713aSLionel Sambuc 
443f4a2713aSLionel Sambuc   OS << "namespace llvm {\n";
444f4a2713aSLionel Sambuc   OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n";
445f4a2713aSLionel Sambuc   OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
446f4a2713aSLionel Sambuc   OS << "extern const char " << TargetName << "InstrNameData[];\n";
447f4a2713aSLionel Sambuc   OS << ClassName << "::" << ClassName << "(int SO, int DO)\n"
448f4a2713aSLionel Sambuc      << "  : TargetInstrInfo(SO, DO) {\n"
449f4a2713aSLionel Sambuc      << "  InitMCInstrInfo(" << TargetName << "Insts, "
450f4a2713aSLionel Sambuc      << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
451f4a2713aSLionel Sambuc      << NumberedInstructions.size() << ");\n}\n"
452f4a2713aSLionel Sambuc      << ClassName << "::~" << ClassName << "() {}\n";
453f4a2713aSLionel Sambuc   OS << "} // End llvm namespace \n";
454f4a2713aSLionel Sambuc 
455f4a2713aSLionel Sambuc   OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
456f4a2713aSLionel Sambuc 
457f4a2713aSLionel Sambuc   emitOperandNameMappings(OS, Target, NumberedInstructions);
458f4a2713aSLionel Sambuc 
459f4a2713aSLionel Sambuc   emitOperandTypesEnum(OS, Target);
460f4a2713aSLionel Sambuc }
461f4a2713aSLionel Sambuc 
emitRecord(const CodeGenInstruction & Inst,unsigned Num,Record * InstrInfo,std::map<std::vector<Record * >,unsigned> & EmittedLists,const OperandInfoMapTy & OpInfo,raw_ostream & OS)462f4a2713aSLionel Sambuc void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
463f4a2713aSLionel Sambuc                                   Record *InstrInfo,
464f4a2713aSLionel Sambuc                          std::map<std::vector<Record*>, unsigned> &EmittedLists,
465f4a2713aSLionel Sambuc                                   const OperandInfoMapTy &OpInfo,
466f4a2713aSLionel Sambuc                                   raw_ostream &OS) {
467f4a2713aSLionel Sambuc   int MinOperands = 0;
468f4a2713aSLionel Sambuc   if (!Inst.Operands.empty())
469f4a2713aSLionel Sambuc     // Each logical operand can be multiple MI operands.
470f4a2713aSLionel Sambuc     MinOperands = Inst.Operands.back().MIOperandNo +
471f4a2713aSLionel Sambuc                   Inst.Operands.back().MINumOperands;
472f4a2713aSLionel Sambuc 
473f4a2713aSLionel Sambuc   OS << "  { ";
474f4a2713aSLionel Sambuc   OS << Num << ",\t" << MinOperands << ",\t"
475f4a2713aSLionel Sambuc      << Inst.Operands.NumDefs << ",\t"
476f4a2713aSLionel Sambuc      << SchedModels.getSchedClassIdx(Inst) << ",\t"
477f4a2713aSLionel Sambuc      << Inst.TheDef->getValueAsInt("Size") << ",\t0";
478f4a2713aSLionel Sambuc 
479f4a2713aSLionel Sambuc   // Emit all of the target indepedent flags...
480f4a2713aSLionel Sambuc   if (Inst.isPseudo)           OS << "|(1<<MCID::Pseudo)";
481f4a2713aSLionel Sambuc   if (Inst.isReturn)           OS << "|(1<<MCID::Return)";
482f4a2713aSLionel Sambuc   if (Inst.isBranch)           OS << "|(1<<MCID::Branch)";
483f4a2713aSLionel Sambuc   if (Inst.isIndirectBranch)   OS << "|(1<<MCID::IndirectBranch)";
484f4a2713aSLionel Sambuc   if (Inst.isCompare)          OS << "|(1<<MCID::Compare)";
485f4a2713aSLionel Sambuc   if (Inst.isMoveImm)          OS << "|(1<<MCID::MoveImm)";
486f4a2713aSLionel Sambuc   if (Inst.isBitcast)          OS << "|(1<<MCID::Bitcast)";
487f4a2713aSLionel Sambuc   if (Inst.isSelect)           OS << "|(1<<MCID::Select)";
488f4a2713aSLionel Sambuc   if (Inst.isBarrier)          OS << "|(1<<MCID::Barrier)";
489f4a2713aSLionel Sambuc   if (Inst.hasDelaySlot)       OS << "|(1<<MCID::DelaySlot)";
490f4a2713aSLionel Sambuc   if (Inst.isCall)             OS << "|(1<<MCID::Call)";
491f4a2713aSLionel Sambuc   if (Inst.canFoldAsLoad)      OS << "|(1<<MCID::FoldableAsLoad)";
492f4a2713aSLionel Sambuc   if (Inst.mayLoad)            OS << "|(1<<MCID::MayLoad)";
493f4a2713aSLionel Sambuc   if (Inst.mayStore)           OS << "|(1<<MCID::MayStore)";
494f4a2713aSLionel Sambuc   if (Inst.isPredicable)       OS << "|(1<<MCID::Predicable)";
495f4a2713aSLionel Sambuc   if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)";
496f4a2713aSLionel Sambuc   if (Inst.isCommutable)       OS << "|(1<<MCID::Commutable)";
497f4a2713aSLionel Sambuc   if (Inst.isTerminator)       OS << "|(1<<MCID::Terminator)";
498f4a2713aSLionel Sambuc   if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)";
499f4a2713aSLionel Sambuc   if (Inst.isNotDuplicable)    OS << "|(1<<MCID::NotDuplicable)";
500f4a2713aSLionel Sambuc   if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)";
501f4a2713aSLionel Sambuc   if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)";
502f4a2713aSLionel Sambuc   if (Inst.hasPostISelHook)    OS << "|(1<<MCID::HasPostISelHook)";
503f4a2713aSLionel Sambuc   if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)";
504f4a2713aSLionel Sambuc   if (Inst.hasSideEffects)     OS << "|(1<<MCID::UnmodeledSideEffects)";
505f4a2713aSLionel Sambuc   if (Inst.isAsCheapAsAMove)   OS << "|(1<<MCID::CheapAsAMove)";
506f4a2713aSLionel Sambuc   if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)";
507f4a2713aSLionel Sambuc   if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)";
508*0a6a1f1dSLionel Sambuc   if (Inst.isRegSequence) OS << "|(1<<MCID::RegSequence)";
509*0a6a1f1dSLionel Sambuc   if (Inst.isExtractSubreg) OS << "|(1<<MCID::ExtractSubreg)";
510*0a6a1f1dSLionel Sambuc   if (Inst.isInsertSubreg) OS << "|(1<<MCID::InsertSubreg)";
511f4a2713aSLionel Sambuc 
512f4a2713aSLionel Sambuc   // Emit all of the target-specific flags...
513f4a2713aSLionel Sambuc   BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
514f4a2713aSLionel Sambuc   if (!TSF)
515f4a2713aSLionel Sambuc     PrintFatalError("no TSFlags?");
516f4a2713aSLionel Sambuc   uint64_t Value = 0;
517f4a2713aSLionel Sambuc   for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
518f4a2713aSLionel Sambuc     if (BitInit *Bit = dyn_cast<BitInit>(TSF->getBit(i)))
519f4a2713aSLionel Sambuc       Value |= uint64_t(Bit->getValue()) << i;
520f4a2713aSLionel Sambuc     else
521f4a2713aSLionel Sambuc       PrintFatalError("Invalid TSFlags bit in " + Inst.TheDef->getName());
522f4a2713aSLionel Sambuc   }
523f4a2713aSLionel Sambuc   OS << ", 0x";
524f4a2713aSLionel Sambuc   OS.write_hex(Value);
525f4a2713aSLionel Sambuc   OS << "ULL, ";
526f4a2713aSLionel Sambuc 
527f4a2713aSLionel Sambuc   // Emit the implicit uses and defs lists...
528f4a2713aSLionel Sambuc   std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
529f4a2713aSLionel Sambuc   if (UseList.empty())
530*0a6a1f1dSLionel Sambuc     OS << "nullptr, ";
531f4a2713aSLionel Sambuc   else
532f4a2713aSLionel Sambuc     OS << "ImplicitList" << EmittedLists[UseList] << ", ";
533f4a2713aSLionel Sambuc 
534f4a2713aSLionel Sambuc   std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
535f4a2713aSLionel Sambuc   if (DefList.empty())
536*0a6a1f1dSLionel Sambuc     OS << "nullptr, ";
537f4a2713aSLionel Sambuc   else
538f4a2713aSLionel Sambuc     OS << "ImplicitList" << EmittedLists[DefList] << ", ";
539f4a2713aSLionel Sambuc 
540f4a2713aSLionel Sambuc   // Emit the operand info.
541f4a2713aSLionel Sambuc   std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
542f4a2713aSLionel Sambuc   if (OperandInfo.empty())
543*0a6a1f1dSLionel Sambuc     OS << "nullptr";
544f4a2713aSLionel Sambuc   else
545f4a2713aSLionel Sambuc     OS << "OperandInfo" << OpInfo.find(OperandInfo)->second;
546f4a2713aSLionel Sambuc 
547f4a2713aSLionel Sambuc   CodeGenTarget &Target = CDP.getTargetInfo();
548f4a2713aSLionel Sambuc   if (Inst.HasComplexDeprecationPredicate)
549f4a2713aSLionel Sambuc     // Emit a function pointer to the complex predicate method.
550f4a2713aSLionel Sambuc     OS << ",0"
551f4a2713aSLionel Sambuc        << ",&get" << Inst.DeprecatedReason << "DeprecationInfo";
552f4a2713aSLionel Sambuc   else if (!Inst.DeprecatedReason.empty())
553f4a2713aSLionel Sambuc     // Emit the Subtarget feature.
554f4a2713aSLionel Sambuc     OS << "," << Target.getInstNamespace() << "::" << Inst.DeprecatedReason
555*0a6a1f1dSLionel Sambuc        << ",nullptr";
556f4a2713aSLionel Sambuc   else
557f4a2713aSLionel Sambuc     // Instruction isn't deprecated.
558*0a6a1f1dSLionel Sambuc     OS << ",0,nullptr";
559f4a2713aSLionel Sambuc 
560f4a2713aSLionel Sambuc   OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
561f4a2713aSLionel Sambuc }
562f4a2713aSLionel Sambuc 
563f4a2713aSLionel Sambuc // emitEnums - Print out enum values for all of the instructions.
emitEnums(raw_ostream & OS)564f4a2713aSLionel Sambuc void InstrInfoEmitter::emitEnums(raw_ostream &OS) {
565f4a2713aSLionel Sambuc 
566f4a2713aSLionel Sambuc   OS << "\n#ifdef GET_INSTRINFO_ENUM\n";
567f4a2713aSLionel Sambuc   OS << "#undef GET_INSTRINFO_ENUM\n";
568f4a2713aSLionel Sambuc 
569f4a2713aSLionel Sambuc   OS << "namespace llvm {\n\n";
570f4a2713aSLionel Sambuc 
571f4a2713aSLionel Sambuc   CodeGenTarget Target(Records);
572f4a2713aSLionel Sambuc 
573f4a2713aSLionel Sambuc   // We must emit the PHI opcode first...
574f4a2713aSLionel Sambuc   std::string Namespace = Target.getInstNamespace();
575f4a2713aSLionel Sambuc 
576f4a2713aSLionel Sambuc   if (Namespace.empty()) {
577f4a2713aSLionel Sambuc     fprintf(stderr, "No instructions defined!\n");
578f4a2713aSLionel Sambuc     exit(1);
579f4a2713aSLionel Sambuc   }
580f4a2713aSLionel Sambuc 
581f4a2713aSLionel Sambuc   const std::vector<const CodeGenInstruction*> &NumberedInstructions =
582f4a2713aSLionel Sambuc     Target.getInstructionsByEnumValue();
583f4a2713aSLionel Sambuc 
584f4a2713aSLionel Sambuc   OS << "namespace " << Namespace << " {\n";
585f4a2713aSLionel Sambuc   OS << "  enum {\n";
586*0a6a1f1dSLionel Sambuc   unsigned Num = 0;
587*0a6a1f1dSLionel Sambuc   for (const CodeGenInstruction *Inst : NumberedInstructions)
588*0a6a1f1dSLionel Sambuc     OS << "    " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n";
589f4a2713aSLionel Sambuc   OS << "    INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n";
590*0a6a1f1dSLionel Sambuc   OS << "  };\n\n";
591f4a2713aSLionel Sambuc   OS << "namespace Sched {\n";
592f4a2713aSLionel Sambuc   OS << "  enum {\n";
593*0a6a1f1dSLionel Sambuc   Num = 0;
594*0a6a1f1dSLionel Sambuc   for (const auto &Class : SchedModels.explicit_classes())
595*0a6a1f1dSLionel Sambuc     OS << "    " << Class.Name << "\t= " << Num++ << ",\n";
596f4a2713aSLionel Sambuc   OS << "    SCHED_LIST_END = " << SchedModels.numInstrSchedClasses() << "\n";
597*0a6a1f1dSLionel Sambuc   OS << "  };\n";
598*0a6a1f1dSLionel Sambuc   OS << "} // End Sched namespace\n";
599*0a6a1f1dSLionel Sambuc   OS << "} // End " << Namespace << " namespace\n";
600f4a2713aSLionel Sambuc   OS << "} // End llvm namespace \n";
601f4a2713aSLionel Sambuc 
602f4a2713aSLionel Sambuc   OS << "#endif // GET_INSTRINFO_ENUM\n\n";
603f4a2713aSLionel Sambuc }
604f4a2713aSLionel Sambuc 
605f4a2713aSLionel Sambuc namespace llvm {
606f4a2713aSLionel Sambuc 
EmitInstrInfo(RecordKeeper & RK,raw_ostream & OS)607f4a2713aSLionel Sambuc void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
608f4a2713aSLionel Sambuc   InstrInfoEmitter(RK).run(OS);
609f4a2713aSLionel Sambuc   EmitMapTable(RK, OS);
610f4a2713aSLionel Sambuc }
611f4a2713aSLionel Sambuc 
612f4a2713aSLionel Sambuc } // End llvm namespace
613