133ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===//
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
301d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//                     The LLVM Compiler Infrastructure
401d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//
53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source
63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details.
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
801d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//===----------------------------------------------------------------------===//
933ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner//
1033ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner// This tablegen backend is responsible for emitting a description of the target
1133ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner// instruction set for the code generator.
1233ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner//
1333ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner//===----------------------------------------------------------------------===//
1433ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner
156f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
166f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "CodeGenDAGPatterns.h"
172661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick#include "CodeGenSchedule.h"
18803a5f6ecb1823280f80e3c4459aa58627d0484cChris Lattner#include "CodeGenTarget.h"
19413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper#include "SequenceToOffsetTable.h"
204ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "TableGenBackends.h"
2123132b188ba651ba172380cd082cc286df73d440Chris Lattner#include "llvm/ADT/StringExtras.h"
2261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger#include "llvm/TableGen/Error.h"
236f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/Record.h"
246f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h"
25cb366d980a389e5b9c3fc2b9aae373c0ba2903c6Jeff Cohen#include <algorithm>
26901b85888c2de6bf982c47ab69b7e83908b6a216Benjamin Kramer#include <cstdio>
276f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <map>
286f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <vector>
292082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnerusing namespace llvm;
30d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace {
326f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass InstrInfoEmitter {
336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  RecordKeeper &Records;
346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  CodeGenDAGPatterns CDP;
352661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  const CodeGenSchedModels &SchedModels;
366f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
376f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic:
382661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  InstrInfoEmitter(RecordKeeper &R):
392661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick    Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}
406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  // run - Output the instruction set description.
426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void run(raw_ostream &OS);
436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenprivate:
456f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void emitEnums(raw_ostream &OS);
466f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
476f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
48898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
49898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  /// The keys of this map are maps which have OpName enum values as their keys
50898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  /// and instruction operand indices as their values.  The values of this map
51898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  /// are lists of instruction names.
52898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  typedef std::map<std::map<unsigned, unsigned>,
53898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard                   std::vector<std::string> > OpNameMapTy;
54898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  typedef std::map<std::string, unsigned>::iterator StrUintMapIter;
556f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                  Record *InstrInfo,
576f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                  std::map<std::vector<Record*>, unsigned> &EL,
586f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                  const OperandInfoMapTy &OpInfo,
596f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                  raw_ostream &OS);
60b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  void emitOperandTypesEnum(raw_ostream &OS, const CodeGenTarget &Target);
61898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  void initOperandMapData(
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            const std::vector<const CodeGenInstruction *> &NumberedInstructions,
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            const std::string &Namespace,
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            std::map<std::string, unsigned> &Operands,
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            OpNameMapTy &OperandMap);
66898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target,
67898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard            const std::vector<const CodeGenInstruction*> &NumberedInstructions);
686f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
696f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  // Operand information.
706f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
716f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
726f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen};
736f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace
746f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
755fbe27530415dcacd7afd591c4ba1d6df4374873Chris Lattnerstatic void PrintDefList(const std::vector<Record*> &Uses,
761a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar                         unsigned Num, raw_ostream &OS) {
77fac259814923d091942b230e7bd002a8d1130bc3Craig Topper  OS << "static const uint16_t ImplicitList" << Num << "[] = { ";
78a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner  for (unsigned i = 0, e = Uses.size(); i != e; ++i)
79a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner    OS << getQualifiedName(Uses[i]) << ", ";
80a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner  OS << "0 };\n";
81a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner}
82a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
83ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner//===----------------------------------------------------------------------===//
84ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner// Operand Info Emission.
85ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner//===----------------------------------------------------------------------===//
86ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner
87a0cca4ae267bc28143e8f4737e119349d95e4825Chris Lattnerstd::vector<std::string>
88a0cca4ae267bc28143e8f4737e119349d95e4825Chris LattnerInstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
89a0cca4ae267bc28143e8f4737e119349d95e4825Chris Lattner  std::vector<std::string> Result;
90bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (auto &Op : Inst.Operands) {
92f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // Handle aggregate operands and normal operands the same way by expanding
93f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // either case into a list of operands for this op.
94c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    std::vector<CGIOperandList::OperandInfo> OperandList;
95f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner
96f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // This might be a multiple operand thing.  Targets like X86 have
97f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // registers in their multi-operand operands.  It may also be an anonymous
98f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // operand, which has a single operand, but no declared class for the
99f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // operand.
100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DagInit *MIOI = Op.MIOperandInfo;
101bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
102f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    if (!MIOI || MIOI->getNumArgs() == 0) {
103f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // Single, anonymous, operand.
104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OperandList.push_back(Op);
10565303d6bd777b76735ef179870678a1d14671c54Chris Lattner    } else {
106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) {
107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        OperandList.push_back(Op);
108a0cca4ae267bc28143e8f4737e119349d95e4825Chris Lattner
1093f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva        Record *OpR = cast<DefInit>(MIOI->getArg(j))->getDef();
110f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner        OperandList.back().Rec = OpR;
111f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      }
112f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    }
113d9a7f4db5f996cce8b3a7f95f8dbac3c996a6625Chris Lattner
114f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    for (unsigned j = 0, e = OperandList.size(); j != e; ++j) {
115f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      Record *OpR = OperandList[j].Rec;
116f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      std::string Res;
117bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
118bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson      if (OpR->isSubClassOf("RegisterOperand"))
119bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson        OpR = OpR->getValueAsDef("RegClass");
120f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      if (OpR->isSubClassOf("RegisterClass"))
121f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner        Res += getQualifiedName(OpR) + "RegClassID, ";
122cb778a8634454c70d88955b3732f330a6cbe5b07Chris Lattner      else if (OpR->isSubClassOf("PointerLikeRegClass"))
123cb778a8634454c70d88955b3732f330a6cbe5b07Chris Lattner        Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", ";
124f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      else
125a606d955de3b0f777131d74162eb6f11b5f95d75Dan Gohman        // -1 means the operand does not have a fixed register class.
126a606d955de3b0f777131d74162eb6f11b5f95d75Dan Gohman        Res += "-1, ";
127bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
128f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // Fill in applicable flags.
129f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      Res += "0";
130bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
131f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // Ptr value whose register class is resolved via callback.
132a938ac6223c5fd315ab745086d843df5e0604e09Chris Lattner      if (OpR->isSubClassOf("PointerLikeRegClass"))
133e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng        Res += "|(1<<MCOI::LookupPtrRegClass)";
134f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner
135f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // Predicate operands.  Check to see if the original unexpanded operand
136f7ab3a84b3e1b5a647ae9456a5edb99d86b35329Tim Northover      // was of type PredicateOp.
137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Op.Rec->isSubClassOf("PredicateOp"))
138e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng        Res += "|(1<<MCOI::Predicate)";
139bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
14088cc092ca5bd79480205ee7b01aa39c13f3e35d7Evan Cheng      // Optional def operands.  Check to see if the original unexpanded operand
14188cc092ca5bd79480205ee7b01aa39c13f3e35d7Evan Cheng      // was of type OptionalDefOperand.
142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Op.Rec->isSubClassOf("OptionalDefOperand"))
143e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng        Res += "|(1<<MCOI::OptionalDef)";
14488cc092ca5bd79480205ee7b01aa39c13f3e35d7Evan Cheng
14539bdc5526f9bb4985c5ea7711e603bb44707ed42Craig Topper      // Fill in operand type.
14639bdc5526f9bb4985c5ea7711e603bb44707ed42Craig Topper      Res += ", MCOI::";
147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(!Op.OperandType.empty() && "Invalid operand type.");
148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Res += Op.OperandType;
14939bdc5526f9bb4985c5ea7711e603bb44707ed42Craig Topper
150f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // Fill in constraint info.
151a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      Res += ", ";
152bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
153c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner      const CGIOperandList::ConstraintInfo &Constraint =
154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Op.Constraints[j];
155a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      if (Constraint.isNone())
156a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        Res += "0";
157a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      else if (Constraint.isEarlyClobber())
158e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng        Res += "(1 << MCOI::EARLY_CLOBBER)";
159a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      else {
160a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        assert(Constraint.isTied());
161a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        Res += "((" + utostr(Constraint.getTiedOperand()) +
162e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                    " << 16) | (1 << MCOI::TIED_TO))";
163a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      }
164bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
165f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      Result.push_back(Res);
166d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner    }
167d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner  }
168e2ba8975883874633a1035c245af3b948b940b25Evan Cheng
169d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner  return Result;
170d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner}
171d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner
172bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Andersonvoid InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
173ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner                                       OperandInfoMapTy &OperandInfoIDs) {
174ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  // ID #0 is for no operand info.
175ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  unsigned OperandListNum = 0;
176ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum;
177bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
178ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  OS << "\n";
179ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  const CodeGenTarget &Target = CDP.getTargetInfo();
180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const CodeGenInstruction *Inst : Target.instructions()) {
181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    std::vector<std::string> OperandInfo = GetOperandInfo(*Inst);
182ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    unsigned &N = OperandInfoIDs[OperandInfo];
183ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    if (N != 0) continue;
184bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
185ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    N = ++OperandListNum;
186e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    OS << "static const MCOperandInfo OperandInfo" << N << "[] = { ";
187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (const std::string &Info : OperandInfo)
188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OS << "{ " << Info << " }, ";
189ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    OS << "};\n";
190ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  }
191ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner}
192ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner
193898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
194898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard/// Initialize data structures for generating operand name mappings.
195898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard///
196898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard/// \param Operands [out] A map used to generate the OpName enum with operand
197898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard///        names as its keys and operand enum values as its values.
198898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard/// \param OperandMap [out] A map for representing the operand name mappings for
199898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard///        each instructions.  This is used to generate the OperandMap table as
200898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard///        well as the getNamedOperandIdx() function.
201898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellardvoid InstrInfoEmitter::initOperandMapData(
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        const std::vector<const CodeGenInstruction *> &NumberedInstructions,
203898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard        const std::string &Namespace,
204898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard        std::map<std::string, unsigned> &Operands,
205898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard        OpNameMapTy &OperandMap) {
206898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
207898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  unsigned NumOperands = 0;
208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const CodeGenInstruction *Inst : NumberedInstructions) {
209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable"))
210898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard      continue;
211898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard    std::map<unsigned, unsigned> OpList;
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (const auto &Info : Inst->Operands) {
213898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard      StrUintMapIter I = Operands.find(Info.Name);
214898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
215898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard      if (I == Operands.end()) {
216898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard        I = Operands.insert(Operands.begin(),
217898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard                    std::pair<std::string, unsigned>(Info.Name, NumOperands++));
218898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard      }
219898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard      OpList[I->second] = Info.MIOperandNo;
220898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard    }
221898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard    OperandMap[OpList].push_back(Namespace + "::" + Inst->TheDef->getName());
222898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  }
223898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard}
224898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
225898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard/// Generate a table and function for looking up the indices of operands by
226898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard/// name.
227898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard///
228898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard/// This code generates:
229898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard/// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry
230898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard///   for each operand name.
231898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard/// - A 2-dimensional table called OperandMap for mapping OpName enum values to
232898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard///   operand indices.
233898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard/// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
234898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard///   for looking up the operand index for an instruction, given a value from
235898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard///   OpName enum
236898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellardvoid InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS,
237898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard           const CodeGenTarget &Target,
238898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard           const std::vector<const CodeGenInstruction*> &NumberedInstructions) {
239898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
240898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  const std::string &Namespace = Target.getInstNamespace();
241898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  std::string OpNameNS = "OpName";
242898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  // Map of operand names to their enumeration value.  This will be used to
243898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  // generate the OpName enum.
244898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  std::map<std::string, unsigned> Operands;
245898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OpNameMapTy OperandMap;
246898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
247898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap);
248898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
249898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n";
250898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n";
251898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "namespace llvm {";
252898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "namespace " << Namespace << " {\n";
253898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "namespace " << OpNameNS << " { \n";
254898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "enum {\n";
255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const auto &Op : Operands)
256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "  " << Op.first << " = " << Op.second << ",\n";
257898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
258898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "OPERAND_LAST";
259898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "\n};\n";
260898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "} // End namespace OpName\n";
261898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "} // End namespace " << Namespace << "\n";
262898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "} // End namespace llvm\n";
263898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n";
264898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
265898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
266898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
267898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "namespace llvm {";
268898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "namespace " << Namespace << " {\n";
269898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n";
27054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  if (!Operands.empty()) {
27154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "  static const int16_t OperandMap [][" << Operands.size()
27254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman       << "] = {\n";
273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (const auto &Entry : OperandMap) {
274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      const std::map<unsigned, unsigned> &OpList = Entry.first;
27554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      OS << "{";
27654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman
27754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      // Emit a row of the OperandMap table
278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      for (unsigned i = 0, e = Operands.size(); i != e; ++i)
279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        OS << (OpList.count(i) == 0 ? -1 : (int)OpList.find(i)->second) << ", ";
28054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman
28154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      OS << "},\n";
28254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    }
28354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "};\n";
284898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
28554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "  switch(Opcode) {\n";
28654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    unsigned TableIndex = 0;
287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (const auto &Entry : OperandMap) {
288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      for (const std::string &Name : Entry.second)
289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        OS << "  case " << Name << ":\n";
290898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
29154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      OS << "    return OperandMap[" << TableIndex++ << "][NamedIdx];\n";
29254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    }
29354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "    default: return -1;\n";
29454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "  }\n";
29554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  } else {
29654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    // There are no operands, so no need to emit anything
29754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "  return -1;\n";
298898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  }
299898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "}\n";
300898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "} // End namespace " << Namespace << "\n";
301898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "} // End namespace llvm\n";
302898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  OS << "#endif //GET_INSTRINFO_NAMED_OPS\n";
303898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
304898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard}
305898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
306b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha/// Generate an enum for all the operand types for this target, under the
307b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha/// llvm::TargetNamespace::OpTypes namespace.
308b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha/// Operand types are all definitions derived of the Operand Target.td class.
309b923d2f5f5958719214472906e9810de262ab447Ahmed Bougachavoid InstrInfoEmitter::emitOperandTypesEnum(raw_ostream &OS,
310b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha                                            const CodeGenTarget &Target) {
311b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha
312b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  const std::string &Namespace = Target.getInstNamespace();
313b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand");
314b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha
315b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "\n#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
316b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
317b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "namespace llvm {";
318b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "namespace " << Namespace << " {\n";
319b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "namespace OpTypes { \n";
320b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "enum OperandType {\n";
321b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha
322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned EnumVal = 0;
323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const Record *Op : Operands) {
324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Op->isAnonymous())
325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OS << "  " << Op->getName() << " = " << EnumVal << ",\n";
326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ++EnumVal;
327b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  }
328b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha
329b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "  OPERAND_TYPE_LIST_END" << "\n};\n";
330b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "} // End namespace OpTypes\n";
331b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "} // End namespace " << Namespace << "\n";
332b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "} // End namespace llvm\n";
333b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
334b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha}
335b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha
336ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner//===----------------------------------------------------------------------===//
337ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner// Main Output.
338ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner//===----------------------------------------------------------------------===//
339a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
340a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner// run - Emit the main instruction description records for the target...
3411a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid InstrInfoEmitter::run(raw_ostream &OS) {
3426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  emitSourceFileHeader("Target Instruction Enum Values", OS);
34322fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  emitEnums(OS);
34422fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
3456f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  emitSourceFileHeader("Target Instruction Descriptors", OS);
34622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
34722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n";
34822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "#undef GET_INSTRINFO_MC_DESC\n";
34922fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
3502c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner  OS << "namespace llvm {\n\n";
3512c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner
352ee4fa1977dd3a495a8857eef924ee5961db765c6Dan Gohman  CodeGenTarget &Target = CDP.getTargetInfo();
3537884b750c33b750177b3f22af75c874c97f728d8Chris Lattner  const std::string &TargetName = Target.getName();
3547884b750c33b750177b3f22af75c874c97f728d8Chris Lattner  Record *InstrInfo = Target.getInstructionSet();
355a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
356a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner  // Keep track of all of the def lists we have emitted already.
357a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner  std::map<std::vector<Record*>, unsigned> EmittedLists;
358a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner  unsigned ListNumber = 0;
359bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
360a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner  // Emit all of the instruction's implicit uses and defs.
361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const CodeGenInstruction *II : Target.instructions()) {
362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Record *Inst = II->TheDef;
363366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
364366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    if (!Uses.empty()) {
365a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner      unsigned &IL = EmittedLists[Uses];
3665fbe27530415dcacd7afd591c4ba1d6df4374873Chris Lattner      if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS);
367a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner    }
368366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
369366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    if (!Defs.empty()) {
370366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner      unsigned &IL = EmittedLists[Defs];
3715fbe27530415dcacd7afd591c4ba1d6df4374873Chris Lattner      if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS);
372a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner    }
373a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner  }
374a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
375ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  OperandInfoMapTy OperandInfoIDs;
376bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
3770e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner  // Emit all of the operand info records.
378ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  EmitOperandInfo(OS, OperandInfoIDs);
379bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
380e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  // Emit all of the MCInstrDesc records in their ENUM ordering.
3810e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner  //
3821a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n";
383f65027842e82027dd6e8020586a299aaa548e355Chris Lattner  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
384f65027842e82027dd6e8020586a299aaa548e355Chris Lattner    Target.getInstructionsByEnumValue();
385a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
386413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  SequenceToOffsetTable<std::string> InstrNames;
387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Num = 0;
388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const CodeGenInstruction *Inst : NumberedInstructions) {
389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Keep a list of the instruction names.
390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    InstrNames.add(Inst->TheDef->getName());
391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Emit the record into the table.
392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    emitRecord(*Inst, Num++, InstrInfo, EmittedLists, OperandInfoIDs, OS);
393413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  }
394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OS << "};\n\n";
395413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper
396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Emit the array of instruction names.
397413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  InstrNames.layout();
398413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  OS << "extern const char " << TargetName << "InstrNameData[] = {\n";
399413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  InstrNames.emit(OS, printChar);
400413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  OS << "};\n\n";
401413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper
402413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {";
403dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Num = 0;
404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const CodeGenInstruction *Inst : NumberedInstructions) {
405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Newline every eight entries.
406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Num % 8 == 0)
407c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer      OS << "\n    ";
408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << InstrNames.get(Inst->TheDef->getName()) << "U, ";
409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ++Num;
410c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer  }
411c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer
412c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer  OS << "\n};\n\n";
413c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer
41494b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng  // MCInstrInfo initialization routine.
41594b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng  OS << "static inline void Init" << TargetName
41694b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng     << "MCInstrInfo(MCInstrInfo *II) {\n";
41794b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng  OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, "
418c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer     << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
41994b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng     << NumberedInstructions.size() << ");\n}\n\n";
42094b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng
4212c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner  OS << "} // End llvm namespace \n";
42222fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
42322fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
4244db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
4254db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  // Create a TargetInstrInfo subclass to hide the MC layer initialization.
4264db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "\n#ifdef GET_INSTRINFO_HEADER\n";
4274db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "#undef GET_INSTRINFO_HEADER\n";
4284db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
4294db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  std::string ClassName = TargetName + "GenInstrInfo";
43094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "namespace llvm {\n";
431a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen  OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
4324db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng     << "  explicit " << ClassName << "(int SO = -1, int DO = -1);\n"
433354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka     << "  virtual ~" << ClassName << "();\n"
4344db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng     << "};\n";
4354db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "} // End llvm namespace \n";
4364db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
4374db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "#endif // GET_INSTRINFO_HEADER\n\n";
4384db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
439354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka  OS << "\n#ifdef GET_INSTRINFO_CTOR_DTOR\n";
440354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka  OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
4414db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
44294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "namespace llvm {\n";
4431a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n";
444bcfa982c4866fee5f86dca8c4bfc7425a9629f0dJakob Stoklund Olesen  OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
445413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  OS << "extern const char " << TargetName << "InstrNameData[];\n";
4464db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << ClassName << "::" << ClassName << "(int SO, int DO)\n"
447a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen     << "  : TargetInstrInfo(SO, DO) {\n"
4484db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng     << "  InitMCInstrInfo(" << TargetName << "Insts, "
449c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer     << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
450354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka     << NumberedInstructions.size() << ");\n}\n"
451354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka     << ClassName << "::~" << ClassName << "() {}\n";
4524db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "} // End llvm namespace \n";
4534db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
454354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka  OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
455898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard
456898b9f020d1089f679d1b1939fd6aafa9de4b411Tom Stellard  emitOperandNameMappings(OS, Target, NumberedInstructions);
457b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha
458b923d2f5f5958719214472906e9810de262ab447Ahmed Bougacha  emitOperandTypesEnum(OS, Target);
459a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner}
460a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
461ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattnervoid InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
462a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner                                  Record *InstrInfo,
463366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner                         std::map<std::vector<Record*>, unsigned> &EmittedLists,
464ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner                                  const OperandInfoMapTy &OpInfo,
4651a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar                                  raw_ostream &OS) {
466a529a37fbd602d748e3e1b345db059ebe3ccf5b1Chris Lattner  int MinOperands = 0;
467562892034651ee4e29c31d03e55e8b8576f56369Richard Trieu  if (!Inst.Operands.empty())
468d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner    // Each logical operand can be multiple MI operands.
469c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    MinOperands = Inst.Operands.back().MIOperandNo +
470c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner                  Inst.Operands.back().MINumOperands;
471d35121ad00667d93ea779a722dbee7d022410815Dan Gohman
472fb1aab0673a699c39281e3bdc1091c0ed8fd1d1cEvan Cheng  OS << "  { ";
473b5910820ce8608b75cb88e6c4efd2d1a5858159aEvan Cheng  OS << Num << ",\t" << MinOperands << ",\t"
47416884415db751c75f2133bd04921393c792b1158Owen Anderson     << Inst.Operands.NumDefs << ",\t"
475e3dbc98a4fc2a31102e4ace6317eac9cf16afb9cAndrew Trick     << SchedModels.getSchedClassIdx(Inst) << ",\t"
476133f9d989485376ce8ad0d6c61ba12e913fa6366Benjamin Kramer     << Inst.TheDef->getValueAsInt("Size") << ",\t0";
477a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
478a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner  // Emit all of the target indepedent flags...
479c291e2f5780c3a8470113a2a58c1fa680cd54b20Jakob Stoklund Olesen  if (Inst.isPseudo)           OS << "|(1<<MCID::Pseudo)";
480e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isReturn)           OS << "|(1<<MCID::Return)";
481e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isBranch)           OS << "|(1<<MCID::Branch)";
482e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isIndirectBranch)   OS << "|(1<<MCID::IndirectBranch)";
483e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isCompare)          OS << "|(1<<MCID::Compare)";
484e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isMoveImm)          OS << "|(1<<MCID::MoveImm)";
485e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isBitcast)          OS << "|(1<<MCID::Bitcast)";
486f2c64ef519b38a4328809b27b4a3a8e0c26e9709Jakob Stoklund Olesen  if (Inst.isSelect)           OS << "|(1<<MCID::Select)";
487e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isBarrier)          OS << "|(1<<MCID::Barrier)";
488e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.hasDelaySlot)       OS << "|(1<<MCID::DelaySlot)";
489e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isCall)             OS << "|(1<<MCID::Call)";
490e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.canFoldAsLoad)      OS << "|(1<<MCID::FoldableAsLoad)";
491e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.mayLoad)            OS << "|(1<<MCID::MayLoad)";
492e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.mayStore)           OS << "|(1<<MCID::MayStore)";
493e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isPredicable)       OS << "|(1<<MCID::Predicable)";
494e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)";
495e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isCommutable)       OS << "|(1<<MCID::Commutable)";
496e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isTerminator)       OS << "|(1<<MCID::Terminator)";
497e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)";
498e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isNotDuplicable)    OS << "|(1<<MCID::NotDuplicable)";
499e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)";
500e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)";
50183a8031336a1155e6b0c3e9a84164324e08d1c8bAndrew Trick  if (Inst.hasPostISelHook)    OS << "|(1<<MCID::HasPostISelHook)";
502e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)";
503e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.hasSideEffects)     OS << "|(1<<MCID::UnmodeledSideEffects)";
504e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isAsCheapAsAMove)   OS << "|(1<<MCID::CheapAsAMove)";
505e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)";
506e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)";
507a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
508a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner  // Emit all of the target-specific flags...
50905bce0beee87512e52428d4b80f5a8e79a949576David Greene  BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
51061131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger  if (!TSF)
51161131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError("no TSFlags?");
512fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  uint64_t Value = 0;
513fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
5146cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva    if (BitInit *Bit = dyn_cast<BitInit>(TSF->getBit(i)))
515fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen      Value |= uint64_t(Bit->getValue()) << i;
516fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen    else
51761131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger      PrintFatalError("Invalid TSFlags bit in " + Inst.TheDef->getName());
518fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  }
519fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  OS << ", 0x";
520fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  OS.write_hex(Value);
521622dffde8691a33180e2368184b9f4efa6a86fbcEric Christopher  OS << "ULL, ";
522a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
523a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner  // Emit the implicit uses and defs lists...
524366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner  std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
525366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner  if (UseList.empty())
526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "nullptr, ";
5273da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman  else
528366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    OS << "ImplicitList" << EmittedLists[UseList] << ", ";
529a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
530366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner  std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
531366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner  if (DefList.empty())
532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "nullptr, ";
5333da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman  else
534366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    OS << "ImplicitList" << EmittedLists[DefList] << ", ";
535a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
5360e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner  // Emit the operand info.
537a0cca4ae267bc28143e8f4737e119349d95e4825Chris Lattner  std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
538d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner  if (OperandInfo.empty())
539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "nullptr";
5400e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner  else
541ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    OS << "OperandInfo" << OpInfo.find(OperandInfo)->second;
542a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
543715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly  CodeGenTarget &Target = CDP.getTargetInfo();
544715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly  if (Inst.HasComplexDeprecationPredicate)
545715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly    // Emit a function pointer to the complex predicate method.
546715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly    OS << ",0"
547715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly       << ",&get" << Inst.DeprecatedReason << "DeprecationInfo";
548715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly  else if (!Inst.DeprecatedReason.empty())
549715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly    // Emit the Subtarget feature.
550715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly    OS << "," << Target.getInstNamespace() << "::" << Inst.DeprecatedReason
551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       << ",nullptr";
552715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly  else
553715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly    // Instruction isn't deprecated.
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << ",0,nullptr";
555715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly
556fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
557a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner}
55822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
55922fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng// emitEnums - Print out enum values for all of the instructions.
56022fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Chengvoid InstrInfoEmitter::emitEnums(raw_ostream &OS) {
56122fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
56222fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "\n#ifdef GET_INSTRINFO_ENUM\n";
56322fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "#undef GET_INSTRINFO_ENUM\n";
56422fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
56522fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "namespace llvm {\n\n";
56622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
56722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  CodeGenTarget Target(Records);
56822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
56922fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  // We must emit the PHI opcode first...
57022fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  std::string Namespace = Target.getInstNamespace();
571bf1aab15075884933e94a3aa950d88a7f16b5989Jim Grosbach
57222fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  if (Namespace.empty()) {
57322fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng    fprintf(stderr, "No instructions defined!\n");
57422fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng    exit(1);
57522fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  }
57622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
57722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
57822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng    Target.getInstructionsByEnumValue();
57922fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
58022fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "namespace " << Namespace << " {\n";
58122fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "  enum {\n";
582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Num = 0;
583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const CodeGenInstruction *Inst : NumberedInstructions)
584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "    " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n";
58522fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "    INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n";
586d8f2eb301c05b2d664a284df7604b82dad7ecab8Vincent Lejeune  OS << "  };\n";
587d8f2eb301c05b2d664a284df7604b82dad7ecab8Vincent Lejeune  OS << "namespace Sched {\n";
588d8f2eb301c05b2d664a284df7604b82dad7ecab8Vincent Lejeune  OS << "  enum {\n";
589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Num = 0;
590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const auto &Class : SchedModels.explicit_classes())
591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "    " << Class.Name << "\t= " << Num++ << ",\n";
592d8f2eb301c05b2d664a284df7604b82dad7ecab8Vincent Lejeune  OS << "    SCHED_LIST_END = " << SchedModels.numInstrSchedClasses() << "\n";
593d8f2eb301c05b2d664a284df7604b82dad7ecab8Vincent Lejeune  OS << "  };\n}\n}\n";
59422fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "} // End llvm namespace \n";
59522fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
59622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "#endif // GET_INSTRINFO_ENUM\n\n";
59722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng}
5986f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
5996f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm {
6006f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
6016f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
6026f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  InstrInfoEmitter(RK).run(OS);
603becdf4d7cd0d5a3079339b6e177066b143d2f84cSebastian Pop  EmitMapTable(RK, OS);
6046f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}
6056f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
6066f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace
607