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"
2023132b188ba651ba172380cd082cc286df73d440Chris Lattner#include "llvm/ADT/StringExtras.h"
216f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/Record.h"
226f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h"
23cb366d980a389e5b9c3fc2b9aae373c0ba2903c6Jeff Cohen#include <algorithm>
24901b85888c2de6bf982c47ab69b7e83908b6a216Benjamin Kramer#include <cstdio>
256f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <map>
266f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <vector>
272082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnerusing namespace llvm;
28d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
296f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace {
306f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass InstrInfoEmitter {
316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  RecordKeeper &Records;
326f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  CodeGenDAGPatterns CDP;
332661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  const CodeGenSchedModels &SchedModels;
346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
356f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic:
362661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  InstrInfoEmitter(RecordKeeper &R):
372661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick    Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}
386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  // run - Output the instruction set description.
406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void run(raw_ostream &OS);
416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenprivate:
436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void emitEnums(raw_ostream &OS);
446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
456f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
466f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
476f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                  Record *InstrInfo,
486f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                  std::map<std::vector<Record*>, unsigned> &EL,
496f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                  const OperandInfoMapTy &OpInfo,
506f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                  raw_ostream &OS);
516f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
526f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  // Operand information.
536f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
546f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
556f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen};
566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace
576f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
585fbe27530415dcacd7afd591c4ba1d6df4374873Chris Lattnerstatic void PrintDefList(const std::vector<Record*> &Uses,
591a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar                         unsigned Num, raw_ostream &OS) {
60fac259814923d091942b230e7bd002a8d1130bc3Craig Topper  OS << "static const uint16_t ImplicitList" << Num << "[] = { ";
61a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner  for (unsigned i = 0, e = Uses.size(); i != e; ++i)
62a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner    OS << getQualifiedName(Uses[i]) << ", ";
63a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner  OS << "0 };\n";
64a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner}
65a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
66ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner//===----------------------------------------------------------------------===//
67ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner// Operand Info Emission.
68ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner//===----------------------------------------------------------------------===//
69ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner
70a0cca4ae267bc28143e8f4737e119349d95e4825Chris Lattnerstd::vector<std::string>
71a0cca4ae267bc28143e8f4737e119349d95e4825Chris LattnerInstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
72a0cca4ae267bc28143e8f4737e119349d95e4825Chris Lattner  std::vector<std::string> Result;
73bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
74c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner  for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) {
75f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // Handle aggregate operands and normal operands the same way by expanding
76f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // either case into a list of operands for this op.
77c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    std::vector<CGIOperandList::OperandInfo> OperandList;
78f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner
79f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // This might be a multiple operand thing.  Targets like X86 have
80f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // registers in their multi-operand operands.  It may also be an anonymous
81f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // operand, which has a single operand, but no declared class for the
82f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    // operand.
8305bce0beee87512e52428d4b80f5a8e79a949576David Greene    DagInit *MIOI = Inst.Operands[i].MIOperandInfo;
84bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
85f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    if (!MIOI || MIOI->getNumArgs() == 0) {
86f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // Single, anonymous, operand.
87c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner      OperandList.push_back(Inst.Operands[i]);
8865303d6bd777b76735ef179870678a1d14671c54Chris Lattner    } else {
89c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner      for (unsigned j = 0, e = Inst.Operands[i].MINumOperands; j != e; ++j) {
90c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner        OperandList.push_back(Inst.Operands[i]);
91a0cca4ae267bc28143e8f4737e119349d95e4825Chris Lattner
9205bce0beee87512e52428d4b80f5a8e79a949576David Greene        Record *OpR = dynamic_cast<DefInit*>(MIOI->getArg(j))->getDef();
93f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner        OperandList.back().Rec = OpR;
94f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      }
95f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    }
96d9a7f4db5f996cce8b3a7f95f8dbac3c996a6625Chris Lattner
97f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner    for (unsigned j = 0, e = OperandList.size(); j != e; ++j) {
98f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      Record *OpR = OperandList[j].Rec;
99f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      std::string Res;
100bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
101bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson      if (OpR->isSubClassOf("RegisterOperand"))
102bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson        OpR = OpR->getValueAsDef("RegClass");
103f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      if (OpR->isSubClassOf("RegisterClass"))
104f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner        Res += getQualifiedName(OpR) + "RegClassID, ";
105cb778a8634454c70d88955b3732f330a6cbe5b07Chris Lattner      else if (OpR->isSubClassOf("PointerLikeRegClass"))
106cb778a8634454c70d88955b3732f330a6cbe5b07Chris Lattner        Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", ";
107f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      else
108a606d955de3b0f777131d74162eb6f11b5f95d75Dan Gohman        // -1 means the operand does not have a fixed register class.
109a606d955de3b0f777131d74162eb6f11b5f95d75Dan Gohman        Res += "-1, ";
110bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
111f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // Fill in applicable flags.
112f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      Res += "0";
113bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
114f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // Ptr value whose register class is resolved via callback.
115a938ac6223c5fd315ab745086d843df5e0604e09Chris Lattner      if (OpR->isSubClassOf("PointerLikeRegClass"))
116e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng        Res += "|(1<<MCOI::LookupPtrRegClass)";
117f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner
118f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // Predicate operands.  Check to see if the original unexpanded operand
119f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // was of type PredicateOperand.
120c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner      if (Inst.Operands[i].Rec->isSubClassOf("PredicateOperand"))
121e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng        Res += "|(1<<MCOI::Predicate)";
122bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
12388cc092ca5bd79480205ee7b01aa39c13f3e35d7Evan Cheng      // Optional def operands.  Check to see if the original unexpanded operand
12488cc092ca5bd79480205ee7b01aa39c13f3e35d7Evan Cheng      // was of type OptionalDefOperand.
125c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner      if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand"))
126e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng        Res += "|(1<<MCOI::OptionalDef)";
12788cc092ca5bd79480205ee7b01aa39c13f3e35d7Evan Cheng
12839bdc5526f9bb4985c5ea7711e603bb44707ed42Craig Topper      // Fill in operand type.
12939bdc5526f9bb4985c5ea7711e603bb44707ed42Craig Topper      Res += ", MCOI::";
13039bdc5526f9bb4985c5ea7711e603bb44707ed42Craig Topper      assert(!Inst.Operands[i].OperandType.empty() && "Invalid operand type.");
13139bdc5526f9bb4985c5ea7711e603bb44707ed42Craig Topper      Res += Inst.Operands[i].OperandType;
13239bdc5526f9bb4985c5ea7711e603bb44707ed42Craig Topper
133f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      // Fill in constraint info.
134a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      Res += ", ";
135bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
136c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner      const CGIOperandList::ConstraintInfo &Constraint =
137c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner        Inst.Operands[i].Constraints[j];
138a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      if (Constraint.isNone())
139a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        Res += "0";
140a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      else if (Constraint.isEarlyClobber())
141e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng        Res += "(1 << MCOI::EARLY_CLOBBER)";
142a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      else {
143a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        assert(Constraint.isTied());
144a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        Res += "((" + utostr(Constraint.getTiedOperand()) +
145e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                    " << 16) | (1 << MCOI::TIED_TO))";
146a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      }
147bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
148f19683956275a85bc0cfa0ac08760fdcc790f510Chris Lattner      Result.push_back(Res);
149d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner    }
150d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner  }
151e2ba8975883874633a1035c245af3b948b940b25Evan Cheng
152d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner  return Result;
153d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner}
154d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner
155bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Andersonvoid InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
156ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner                                       OperandInfoMapTy &OperandInfoIDs) {
157ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  // ID #0 is for no operand info.
158ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  unsigned OperandListNum = 0;
159ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum;
160bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
161ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  OS << "\n";
162ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  const CodeGenTarget &Target = CDP.getTargetInfo();
163ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
164ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner       E = Target.inst_end(); II != E; ++II) {
1656a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner    std::vector<std::string> OperandInfo = GetOperandInfo(**II);
166ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    unsigned &N = OperandInfoIDs[OperandInfo];
167ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    if (N != 0) continue;
168bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
169ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    N = ++OperandListNum;
170e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    OS << "static const MCOperandInfo OperandInfo" << N << "[] = { ";
171ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i)
172ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner      OS << "{ " << OperandInfo[i] << " }, ";
173ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    OS << "};\n";
174ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  }
175ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner}
176ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner
177ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner//===----------------------------------------------------------------------===//
178ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner// Main Output.
179ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner//===----------------------------------------------------------------------===//
180a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
181a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner// run - Emit the main instruction description records for the target...
1821a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid InstrInfoEmitter::run(raw_ostream &OS) {
1836f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  emitSourceFileHeader("Target Instruction Enum Values", OS);
18422fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  emitEnums(OS);
18522fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
1866f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  emitSourceFileHeader("Target Instruction Descriptors", OS);
18722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
18822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n";
18922fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "#undef GET_INSTRINFO_MC_DESC\n";
19022fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
1912c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner  OS << "namespace llvm {\n\n";
1922c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner
193ee4fa1977dd3a495a8857eef924ee5961db765c6Dan Gohman  CodeGenTarget &Target = CDP.getTargetInfo();
1947884b750c33b750177b3f22af75c874c97f728d8Chris Lattner  const std::string &TargetName = Target.getName();
1957884b750c33b750177b3f22af75c874c97f728d8Chris Lattner  Record *InstrInfo = Target.getInstructionSet();
196a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
197a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner  // Keep track of all of the def lists we have emitted already.
198a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner  std::map<std::vector<Record*>, unsigned> EmittedLists;
199a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner  unsigned ListNumber = 0;
200bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
201a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner  // Emit all of the instruction's implicit uses and defs.
202ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
203ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner         E = Target.inst_end(); II != E; ++II) {
2046a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner    Record *Inst = (*II)->TheDef;
205366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
206366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    if (!Uses.empty()) {
207a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner      unsigned &IL = EmittedLists[Uses];
2085fbe27530415dcacd7afd591c4ba1d6df4374873Chris Lattner      if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS);
209a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner    }
210366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
211366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    if (!Defs.empty()) {
212366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner      unsigned &IL = EmittedLists[Defs];
2135fbe27530415dcacd7afd591c4ba1d6df4374873Chris Lattner      if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS);
214a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner    }
215a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner  }
216a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
217ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  OperandInfoMapTy OperandInfoIDs;
218bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
2190e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner  // Emit all of the operand info records.
220ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner  EmitOperandInfo(OS, OperandInfoIDs);
221bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
222e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  // Emit all of the MCInstrDesc records in their ENUM ordering.
2230e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner  //
2241a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n";
225f65027842e82027dd6e8020586a299aaa548e355Chris Lattner  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
226f65027842e82027dd6e8020586a299aaa548e355Chris Lattner    Target.getInstructionsByEnumValue();
227a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
228f52e2618f3992aa673c738aa1d2e6c046a0b6f5aChris Lattner  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i)
229f52e2618f3992aa673c738aa1d2e6c046a0b6f5aChris Lattner    emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists,
2304db3748fcf39ac0001b9d02eb6bf803e309a5c19Evan Cheng               OperandInfoIDs, OS);
23194b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng  OS << "};\n\n";
23294b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng
233413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  // Build an array of instruction names
234413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  SequenceToOffsetTable<std::string> InstrNames;
235c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
236c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer    const CodeGenInstruction *Instr = NumberedInstructions[i];
237413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper    InstrNames.add(Instr->TheDef->getName());
238413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  }
239413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper
240413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  InstrNames.layout();
241413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  OS << "extern const char " << TargetName << "InstrNameData[] = {\n";
242413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  InstrNames.emit(OS, printChar);
243413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  OS << "};\n\n";
244413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper
245413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {";
246413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
247c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer    if (i % 8 == 0)
248c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer      OS << "\n    ";
249413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper    const CodeGenInstruction *Instr = NumberedInstructions[i];
250413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper    OS << InstrNames.get(Instr->TheDef->getName()) << "U, ";
251c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer  }
252c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer
253c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer  OS << "\n};\n\n";
254c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer
25594b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng  // MCInstrInfo initialization routine.
25694b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng  OS << "static inline void Init" << TargetName
25794b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng     << "MCInstrInfo(MCInstrInfo *II) {\n";
25894b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng  OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, "
259c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer     << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
26094b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng     << NumberedInstructions.size() << ");\n}\n\n";
26194b01f688256fca49decb239a8c84b003f18cdbcEvan Cheng
2622c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner  OS << "} // End llvm namespace \n";
26322fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
26422fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
2654db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
2664db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  // Create a TargetInstrInfo subclass to hide the MC layer initialization.
2674db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "\n#ifdef GET_INSTRINFO_HEADER\n";
2684db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "#undef GET_INSTRINFO_HEADER\n";
2694db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
2704db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  std::string ClassName = TargetName + "GenInstrInfo";
27194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "namespace llvm {\n";
2724db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "struct " << ClassName << " : public TargetInstrInfoImpl {\n"
2734db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng     << "  explicit " << ClassName << "(int SO = -1, int DO = -1);\n"
2744db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng     << "};\n";
2754db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "} // End llvm namespace \n";
2764db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
2774db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "#endif // GET_INSTRINFO_HEADER\n\n";
2784db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
2794db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "\n#ifdef GET_INSTRINFO_CTOR\n";
2804db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "#undef GET_INSTRINFO_CTOR\n";
2814db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
28294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "namespace llvm {\n";
2831a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n";
284bcfa982c4866fee5f86dca8c4bfc7425a9629f0dJakob Stoklund Olesen  OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
285413b2e7539a1e41f8694abb809678ae48d1e6125Craig Topper  OS << "extern const char " << TargetName << "InstrNameData[];\n";
2864db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << ClassName << "::" << ClassName << "(int SO, int DO)\n"
2874db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng     << "  : TargetInstrInfoImpl(SO, DO) {\n"
2884db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng     << "  InitMCInstrInfo(" << TargetName << "Insts, "
289c667ba69ac342563c0886e20509e68705d78a0a5Benjamin Kramer     << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
2904db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng     << NumberedInstructions.size() << ");\n}\n";
2914db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "} // End llvm namespace \n";
2924db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
2934db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  OS << "#endif // GET_INSTRINFO_CTOR\n\n";
294a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner}
295a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
296ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattnervoid InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
297a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner                                  Record *InstrInfo,
298366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner                         std::map<std::vector<Record*>, unsigned> &EmittedLists,
299ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner                                  const OperandInfoMapTy &OpInfo,
3001a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar                                  raw_ostream &OS) {
301a529a37fbd602d748e3e1b345db059ebe3ccf5b1Chris Lattner  int MinOperands = 0;
302c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner  if (!Inst.Operands.size() == 0)
303d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner    // Each logical operand can be multiple MI operands.
304c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    MinOperands = Inst.Operands.back().MIOperandNo +
305c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner                  Inst.Operands.back().MINumOperands;
306d35121ad00667d93ea779a722dbee7d022410815Dan Gohman
3072661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  Record *ItinDef = Inst.TheDef->getValueAsDef("Itinerary");
308fb1aab0673a699c39281e3bdc1091c0ed8fd1d1cEvan Cheng  OS << "  { ";
309b5910820ce8608b75cb88e6c4efd2d1a5858159aEvan Cheng  OS << Num << ",\t" << MinOperands << ",\t"
31016884415db751c75f2133bd04921393c792b1158Owen Anderson     << Inst.Operands.NumDefs << ",\t"
3112661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick     << SchedModels.getItinClassIdx(ItinDef) << ",\t"
312133f9d989485376ce8ad0d6c61ba12e913fa6366Benjamin Kramer     << Inst.TheDef->getValueAsInt("Size") << ",\t0";
313a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
314a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner  // Emit all of the target indepedent flags...
315c291e2f5780c3a8470113a2a58c1fa680cd54b20Jakob Stoklund Olesen  if (Inst.isPseudo)           OS << "|(1<<MCID::Pseudo)";
316e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isReturn)           OS << "|(1<<MCID::Return)";
317e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isBranch)           OS << "|(1<<MCID::Branch)";
318e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isIndirectBranch)   OS << "|(1<<MCID::IndirectBranch)";
319e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isCompare)          OS << "|(1<<MCID::Compare)";
320e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isMoveImm)          OS << "|(1<<MCID::MoveImm)";
321e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isBitcast)          OS << "|(1<<MCID::Bitcast)";
322f2c64ef519b38a4328809b27b4a3a8e0c26e9709Jakob Stoklund Olesen  if (Inst.isSelect)           OS << "|(1<<MCID::Select)";
323e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isBarrier)          OS << "|(1<<MCID::Barrier)";
324e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.hasDelaySlot)       OS << "|(1<<MCID::DelaySlot)";
325e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isCall)             OS << "|(1<<MCID::Call)";
326e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.canFoldAsLoad)      OS << "|(1<<MCID::FoldableAsLoad)";
327e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.mayLoad)            OS << "|(1<<MCID::MayLoad)";
328e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.mayStore)           OS << "|(1<<MCID::MayStore)";
329e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isPredicable)       OS << "|(1<<MCID::Predicable)";
330e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)";
331e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isCommutable)       OS << "|(1<<MCID::Commutable)";
332e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isTerminator)       OS << "|(1<<MCID::Terminator)";
333e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)";
334e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isNotDuplicable)    OS << "|(1<<MCID::NotDuplicable)";
335e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)";
336e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)";
33783a8031336a1155e6b0c3e9a84164324e08d1c8bAndrew Trick  if (Inst.hasPostISelHook)    OS << "|(1<<MCID::HasPostISelHook)";
338e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)";
339e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.hasSideEffects)     OS << "|(1<<MCID::UnmodeledSideEffects)";
340e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.isAsCheapAsAMove)   OS << "|(1<<MCID::CheapAsAMove)";
341e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)";
342e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)";
343a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
344a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner  // Emit all of the target-specific flags...
34505bce0beee87512e52428d4b80f5a8e79a949576David Greene  BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
346fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  if (!TSF) throw "no TSFlags?";
347fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  uint64_t Value = 0;
348fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
34905bce0beee87512e52428d4b80f5a8e79a949576David Greene    if (BitInit *Bit = dynamic_cast<BitInit*>(TSF->getBit(i)))
350fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen      Value |= uint64_t(Bit->getValue()) << i;
351fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen    else
352fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen      throw "Invalid TSFlags bit in " + Inst.TheDef->getName();
353fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  }
354fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  OS << ", 0x";
355fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  OS.write_hex(Value);
356622dffde8691a33180e2368184b9f4efa6a86fbcEric Christopher  OS << "ULL, ";
357a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
358a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner  // Emit the implicit uses and defs lists...
359366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner  std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
360366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner  if (UseList.empty())
361cd4317efcf334be10d9a98008a1445d6e12a7712Jim Laskey    OS << "NULL, ";
3623da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman  else
363366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    OS << "ImplicitList" << EmittedLists[UseList] << ", ";
364a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
365366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner  std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
366366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner  if (DefList.empty())
367cd4317efcf334be10d9a98008a1445d6e12a7712Jim Laskey    OS << "NULL, ";
3683da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman  else
369366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner    OS << "ImplicitList" << EmittedLists[DefList] << ", ";
370a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
3710e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner  // Emit the operand info.
372a0cca4ae267bc28143e8f4737e119349d95e4825Chris Lattner  std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
373d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner  if (OperandInfo.empty())
374d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner    OS << "0";
3750e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner  else
376ef8339b11a0180c6df6ade4e9f4fd75a76ebc419Chris Lattner    OS << "OperandInfo" << OpInfo.find(OperandInfo)->second;
377a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner
378fddb7667ca4d8fe83f96b388295849281ddaa5b4Jakob Stoklund Olesen  OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
379a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner}
38022fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
38122fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng// emitEnums - Print out enum values for all of the instructions.
38222fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Chengvoid InstrInfoEmitter::emitEnums(raw_ostream &OS) {
38322fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
38422fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "\n#ifdef GET_INSTRINFO_ENUM\n";
38522fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "#undef GET_INSTRINFO_ENUM\n";
38622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
38722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "namespace llvm {\n\n";
38822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
38922fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  CodeGenTarget Target(Records);
39022fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
39122fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  // We must emit the PHI opcode first...
39222fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  std::string Namespace = Target.getInstNamespace();
393bf1aab15075884933e94a3aa950d88a7f16b5989Jim Grosbach
39422fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  if (Namespace.empty()) {
39522fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng    fprintf(stderr, "No instructions defined!\n");
39622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng    exit(1);
39722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  }
39822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
39922fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
40022fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng    Target.getInstructionsByEnumValue();
40122fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
40222fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "namespace " << Namespace << " {\n";
40322fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "  enum {\n";
40422fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
40522fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng    OS << "    " << NumberedInstructions[i]->TheDef->getName()
40622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng       << "\t= " << i << ",\n";
40722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  }
40822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "    INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n";
40922fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "  };\n}\n";
41022fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "} // End llvm namespace \n";
41122fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
41222fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng  OS << "#endif // GET_INSTRINFO_ENUM\n\n";
41322fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng}
4146f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
4156f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm {
4166f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
4176f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
4186f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  InstrInfoEmitter(RK).run(OS);
4196f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}
4206f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
4216f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace
422