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