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