xref: /minix3/external/bsd/llvm/dist/llvm/utils/TableGen/CodeGenTarget.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc //===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===//
2*f4a2713aSLionel Sambuc //
3*f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*f4a2713aSLionel Sambuc //
5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7*f4a2713aSLionel Sambuc //
8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9*f4a2713aSLionel Sambuc //
10*f4a2713aSLionel Sambuc // This class wraps target description classes used by the various code
11*f4a2713aSLionel Sambuc // generation TableGen backends.  This makes it easier to access the data and
12*f4a2713aSLionel Sambuc // provides a single place that needs to check it for validity.  All of these
13*f4a2713aSLionel Sambuc // classes abort on error conditions.
14*f4a2713aSLionel Sambuc //
15*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
16*f4a2713aSLionel Sambuc 
17*f4a2713aSLionel Sambuc #include "CodeGenTarget.h"
18*f4a2713aSLionel Sambuc #include "CodeGenIntrinsics.h"
19*f4a2713aSLionel Sambuc #include "CodeGenSchedule.h"
20*f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
21*f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
22*f4a2713aSLionel Sambuc #include "llvm/Support/CommandLine.h"
23*f4a2713aSLionel Sambuc #include "llvm/TableGen/Error.h"
24*f4a2713aSLionel Sambuc #include "llvm/TableGen/Record.h"
25*f4a2713aSLionel Sambuc #include <algorithm>
26*f4a2713aSLionel Sambuc using namespace llvm;
27*f4a2713aSLionel Sambuc 
28*f4a2713aSLionel Sambuc static cl::opt<unsigned>
29*f4a2713aSLionel Sambuc AsmParserNum("asmparsernum", cl::init(0),
30*f4a2713aSLionel Sambuc              cl::desc("Make -gen-asm-parser emit assembly parser #N"));
31*f4a2713aSLionel Sambuc 
32*f4a2713aSLionel Sambuc static cl::opt<unsigned>
33*f4a2713aSLionel Sambuc AsmWriterNum("asmwriternum", cl::init(0),
34*f4a2713aSLionel Sambuc              cl::desc("Make -gen-asm-writer emit assembly writer #N"));
35*f4a2713aSLionel Sambuc 
36*f4a2713aSLionel Sambuc /// getValueType - Return the MVT::SimpleValueType that the specified TableGen
37*f4a2713aSLionel Sambuc /// record corresponds to.
38*f4a2713aSLionel Sambuc MVT::SimpleValueType llvm::getValueType(Record *Rec) {
39*f4a2713aSLionel Sambuc   return (MVT::SimpleValueType)Rec->getValueAsInt("Value");
40*f4a2713aSLionel Sambuc }
41*f4a2713aSLionel Sambuc 
42*f4a2713aSLionel Sambuc std::string llvm::getName(MVT::SimpleValueType T) {
43*f4a2713aSLionel Sambuc   switch (T) {
44*f4a2713aSLionel Sambuc   case MVT::Other:   return "UNKNOWN";
45*f4a2713aSLionel Sambuc   case MVT::iPTR:    return "TLI.getPointerTy()";
46*f4a2713aSLionel Sambuc   case MVT::iPTRAny: return "TLI.getPointerTy()";
47*f4a2713aSLionel Sambuc   default: return getEnumName(T);
48*f4a2713aSLionel Sambuc   }
49*f4a2713aSLionel Sambuc }
50*f4a2713aSLionel Sambuc 
51*f4a2713aSLionel Sambuc std::string llvm::getEnumName(MVT::SimpleValueType T) {
52*f4a2713aSLionel Sambuc   switch (T) {
53*f4a2713aSLionel Sambuc   case MVT::Other:    return "MVT::Other";
54*f4a2713aSLionel Sambuc   case MVT::i1:       return "MVT::i1";
55*f4a2713aSLionel Sambuc   case MVT::i8:       return "MVT::i8";
56*f4a2713aSLionel Sambuc   case MVT::i16:      return "MVT::i16";
57*f4a2713aSLionel Sambuc   case MVT::i32:      return "MVT::i32";
58*f4a2713aSLionel Sambuc   case MVT::i64:      return "MVT::i64";
59*f4a2713aSLionel Sambuc   case MVT::i128:     return "MVT::i128";
60*f4a2713aSLionel Sambuc   case MVT::iAny:     return "MVT::iAny";
61*f4a2713aSLionel Sambuc   case MVT::fAny:     return "MVT::fAny";
62*f4a2713aSLionel Sambuc   case MVT::vAny:     return "MVT::vAny";
63*f4a2713aSLionel Sambuc   case MVT::f16:      return "MVT::f16";
64*f4a2713aSLionel Sambuc   case MVT::f32:      return "MVT::f32";
65*f4a2713aSLionel Sambuc   case MVT::f64:      return "MVT::f64";
66*f4a2713aSLionel Sambuc   case MVT::f80:      return "MVT::f80";
67*f4a2713aSLionel Sambuc   case MVT::f128:     return "MVT::f128";
68*f4a2713aSLionel Sambuc   case MVT::ppcf128:  return "MVT::ppcf128";
69*f4a2713aSLionel Sambuc   case MVT::x86mmx:   return "MVT::x86mmx";
70*f4a2713aSLionel Sambuc   case MVT::Glue:     return "MVT::Glue";
71*f4a2713aSLionel Sambuc   case MVT::isVoid:   return "MVT::isVoid";
72*f4a2713aSLionel Sambuc   case MVT::v2i1:     return "MVT::v2i1";
73*f4a2713aSLionel Sambuc   case MVT::v4i1:     return "MVT::v4i1";
74*f4a2713aSLionel Sambuc   case MVT::v8i1:     return "MVT::v8i1";
75*f4a2713aSLionel Sambuc   case MVT::v16i1:    return "MVT::v16i1";
76*f4a2713aSLionel Sambuc   case MVT::v32i1:    return "MVT::v32i1";
77*f4a2713aSLionel Sambuc   case MVT::v64i1:    return "MVT::v64i1";
78*f4a2713aSLionel Sambuc   case MVT::v1i8:     return "MVT::v1i8";
79*f4a2713aSLionel Sambuc   case MVT::v2i8:     return "MVT::v2i8";
80*f4a2713aSLionel Sambuc   case MVT::v4i8:     return "MVT::v4i8";
81*f4a2713aSLionel Sambuc   case MVT::v8i8:     return "MVT::v8i8";
82*f4a2713aSLionel Sambuc   case MVT::v16i8:    return "MVT::v16i8";
83*f4a2713aSLionel Sambuc   case MVT::v32i8:    return "MVT::v32i8";
84*f4a2713aSLionel Sambuc   case MVT::v64i8:    return "MVT::v64i8";
85*f4a2713aSLionel Sambuc   case MVT::v1i16:    return "MVT::v1i16";
86*f4a2713aSLionel Sambuc   case MVT::v2i16:    return "MVT::v2i16";
87*f4a2713aSLionel Sambuc   case MVT::v4i16:    return "MVT::v4i16";
88*f4a2713aSLionel Sambuc   case MVT::v8i16:    return "MVT::v8i16";
89*f4a2713aSLionel Sambuc   case MVT::v16i16:   return "MVT::v16i16";
90*f4a2713aSLionel Sambuc   case MVT::v32i16:   return "MVT::v32i16";
91*f4a2713aSLionel Sambuc   case MVT::v1i32:    return "MVT::v1i32";
92*f4a2713aSLionel Sambuc   case MVT::v2i32:    return "MVT::v2i32";
93*f4a2713aSLionel Sambuc   case MVT::v4i32:    return "MVT::v4i32";
94*f4a2713aSLionel Sambuc   case MVT::v8i32:    return "MVT::v8i32";
95*f4a2713aSLionel Sambuc   case MVT::v16i32:   return "MVT::v16i32";
96*f4a2713aSLionel Sambuc   case MVT::v1i64:    return "MVT::v1i64";
97*f4a2713aSLionel Sambuc   case MVT::v2i64:    return "MVT::v2i64";
98*f4a2713aSLionel Sambuc   case MVT::v4i64:    return "MVT::v4i64";
99*f4a2713aSLionel Sambuc   case MVT::v8i64:    return "MVT::v8i64";
100*f4a2713aSLionel Sambuc   case MVT::v16i64:   return "MVT::v16i64";
101*f4a2713aSLionel Sambuc   case MVT::v2f16:    return "MVT::v2f16";
102*f4a2713aSLionel Sambuc   case MVT::v4f16:    return "MVT::v4f16";
103*f4a2713aSLionel Sambuc   case MVT::v8f16:    return "MVT::v8f16";
104*f4a2713aSLionel Sambuc   case MVT::v1f32:    return "MVT::v1f32";
105*f4a2713aSLionel Sambuc   case MVT::v2f32:    return "MVT::v2f32";
106*f4a2713aSLionel Sambuc   case MVT::v4f32:    return "MVT::v4f32";
107*f4a2713aSLionel Sambuc   case MVT::v8f32:    return "MVT::v8f32";
108*f4a2713aSLionel Sambuc   case MVT::v16f32:   return "MVT::v16f32";
109*f4a2713aSLionel Sambuc   case MVT::v1f64:    return "MVT::v1f64";
110*f4a2713aSLionel Sambuc   case MVT::v2f64:    return "MVT::v2f64";
111*f4a2713aSLionel Sambuc   case MVT::v4f64:    return "MVT::v4f64";
112*f4a2713aSLionel Sambuc   case MVT::v8f64:    return "MVT::v8f64";
113*f4a2713aSLionel Sambuc   case MVT::Metadata: return "MVT::Metadata";
114*f4a2713aSLionel Sambuc   case MVT::iPTR:     return "MVT::iPTR";
115*f4a2713aSLionel Sambuc   case MVT::iPTRAny:  return "MVT::iPTRAny";
116*f4a2713aSLionel Sambuc   case MVT::Untyped:  return "MVT::Untyped";
117*f4a2713aSLionel Sambuc   default: llvm_unreachable("ILLEGAL VALUE TYPE!");
118*f4a2713aSLionel Sambuc   }
119*f4a2713aSLionel Sambuc }
120*f4a2713aSLionel Sambuc 
121*f4a2713aSLionel Sambuc /// getQualifiedName - Return the name of the specified record, with a
122*f4a2713aSLionel Sambuc /// namespace qualifier if the record contains one.
123*f4a2713aSLionel Sambuc ///
124*f4a2713aSLionel Sambuc std::string llvm::getQualifiedName(const Record *R) {
125*f4a2713aSLionel Sambuc   std::string Namespace;
126*f4a2713aSLionel Sambuc   if (R->getValue("Namespace"))
127*f4a2713aSLionel Sambuc      Namespace = R->getValueAsString("Namespace");
128*f4a2713aSLionel Sambuc   if (Namespace.empty()) return R->getName();
129*f4a2713aSLionel Sambuc   return Namespace + "::" + R->getName();
130*f4a2713aSLionel Sambuc }
131*f4a2713aSLionel Sambuc 
132*f4a2713aSLionel Sambuc 
133*f4a2713aSLionel Sambuc /// getTarget - Return the current instance of the Target class.
134*f4a2713aSLionel Sambuc ///
135*f4a2713aSLionel Sambuc CodeGenTarget::CodeGenTarget(RecordKeeper &records)
136*f4a2713aSLionel Sambuc   : Records(records), RegBank(0), SchedModels(0) {
137*f4a2713aSLionel Sambuc   std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
138*f4a2713aSLionel Sambuc   if (Targets.size() == 0)
139*f4a2713aSLionel Sambuc     PrintFatalError("ERROR: No 'Target' subclasses defined!");
140*f4a2713aSLionel Sambuc   if (Targets.size() != 1)
141*f4a2713aSLionel Sambuc     PrintFatalError("ERROR: Multiple subclasses of Target defined!");
142*f4a2713aSLionel Sambuc   TargetRec = Targets[0];
143*f4a2713aSLionel Sambuc }
144*f4a2713aSLionel Sambuc 
145*f4a2713aSLionel Sambuc CodeGenTarget::~CodeGenTarget() {
146*f4a2713aSLionel Sambuc   delete RegBank;
147*f4a2713aSLionel Sambuc   delete SchedModels;
148*f4a2713aSLionel Sambuc }
149*f4a2713aSLionel Sambuc 
150*f4a2713aSLionel Sambuc const std::string &CodeGenTarget::getName() const {
151*f4a2713aSLionel Sambuc   return TargetRec->getName();
152*f4a2713aSLionel Sambuc }
153*f4a2713aSLionel Sambuc 
154*f4a2713aSLionel Sambuc std::string CodeGenTarget::getInstNamespace() const {
155*f4a2713aSLionel Sambuc   for (inst_iterator i = inst_begin(), e = inst_end(); i != e; ++i) {
156*f4a2713aSLionel Sambuc     // Make sure not to pick up "TargetOpcode" by accidentally getting
157*f4a2713aSLionel Sambuc     // the namespace off the PHI instruction or something.
158*f4a2713aSLionel Sambuc     if ((*i)->Namespace != "TargetOpcode")
159*f4a2713aSLionel Sambuc       return (*i)->Namespace;
160*f4a2713aSLionel Sambuc   }
161*f4a2713aSLionel Sambuc 
162*f4a2713aSLionel Sambuc   return "";
163*f4a2713aSLionel Sambuc }
164*f4a2713aSLionel Sambuc 
165*f4a2713aSLionel Sambuc Record *CodeGenTarget::getInstructionSet() const {
166*f4a2713aSLionel Sambuc   return TargetRec->getValueAsDef("InstructionSet");
167*f4a2713aSLionel Sambuc }
168*f4a2713aSLionel Sambuc 
169*f4a2713aSLionel Sambuc 
170*f4a2713aSLionel Sambuc /// getAsmParser - Return the AssemblyParser definition for this target.
171*f4a2713aSLionel Sambuc ///
172*f4a2713aSLionel Sambuc Record *CodeGenTarget::getAsmParser() const {
173*f4a2713aSLionel Sambuc   std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers");
174*f4a2713aSLionel Sambuc   if (AsmParserNum >= LI.size())
175*f4a2713aSLionel Sambuc     PrintFatalError("Target does not have an AsmParser #" + utostr(AsmParserNum) + "!");
176*f4a2713aSLionel Sambuc   return LI[AsmParserNum];
177*f4a2713aSLionel Sambuc }
178*f4a2713aSLionel Sambuc 
179*f4a2713aSLionel Sambuc /// getAsmParserVariant - Return the AssmblyParserVariant definition for
180*f4a2713aSLionel Sambuc /// this target.
181*f4a2713aSLionel Sambuc ///
182*f4a2713aSLionel Sambuc Record *CodeGenTarget::getAsmParserVariant(unsigned i) const {
183*f4a2713aSLionel Sambuc   std::vector<Record*> LI =
184*f4a2713aSLionel Sambuc     TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
185*f4a2713aSLionel Sambuc   if (i >= LI.size())
186*f4a2713aSLionel Sambuc     PrintFatalError("Target does not have an AsmParserVariant #" + utostr(i) + "!");
187*f4a2713aSLionel Sambuc   return LI[i];
188*f4a2713aSLionel Sambuc }
189*f4a2713aSLionel Sambuc 
190*f4a2713aSLionel Sambuc /// getAsmParserVariantCount - Return the AssmblyParserVariant definition
191*f4a2713aSLionel Sambuc /// available for this target.
192*f4a2713aSLionel Sambuc ///
193*f4a2713aSLionel Sambuc unsigned CodeGenTarget::getAsmParserVariantCount() const {
194*f4a2713aSLionel Sambuc   std::vector<Record*> LI =
195*f4a2713aSLionel Sambuc     TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
196*f4a2713aSLionel Sambuc   return LI.size();
197*f4a2713aSLionel Sambuc }
198*f4a2713aSLionel Sambuc 
199*f4a2713aSLionel Sambuc /// getAsmWriter - Return the AssemblyWriter definition for this target.
200*f4a2713aSLionel Sambuc ///
201*f4a2713aSLionel Sambuc Record *CodeGenTarget::getAsmWriter() const {
202*f4a2713aSLionel Sambuc   std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
203*f4a2713aSLionel Sambuc   if (AsmWriterNum >= LI.size())
204*f4a2713aSLionel Sambuc     PrintFatalError("Target does not have an AsmWriter #" + utostr(AsmWriterNum) + "!");
205*f4a2713aSLionel Sambuc   return LI[AsmWriterNum];
206*f4a2713aSLionel Sambuc }
207*f4a2713aSLionel Sambuc 
208*f4a2713aSLionel Sambuc CodeGenRegBank &CodeGenTarget::getRegBank() const {
209*f4a2713aSLionel Sambuc   if (!RegBank)
210*f4a2713aSLionel Sambuc     RegBank = new CodeGenRegBank(Records);
211*f4a2713aSLionel Sambuc   return *RegBank;
212*f4a2713aSLionel Sambuc }
213*f4a2713aSLionel Sambuc 
214*f4a2713aSLionel Sambuc void CodeGenTarget::ReadRegAltNameIndices() const {
215*f4a2713aSLionel Sambuc   RegAltNameIndices = Records.getAllDerivedDefinitions("RegAltNameIndex");
216*f4a2713aSLionel Sambuc   std::sort(RegAltNameIndices.begin(), RegAltNameIndices.end(), LessRecord());
217*f4a2713aSLionel Sambuc }
218*f4a2713aSLionel Sambuc 
219*f4a2713aSLionel Sambuc /// getRegisterByName - If there is a register with the specific AsmName,
220*f4a2713aSLionel Sambuc /// return it.
221*f4a2713aSLionel Sambuc const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const {
222*f4a2713aSLionel Sambuc   const StringMap<CodeGenRegister*> &Regs = getRegBank().getRegistersByName();
223*f4a2713aSLionel Sambuc   StringMap<CodeGenRegister*>::const_iterator I = Regs.find(Name);
224*f4a2713aSLionel Sambuc   if (I == Regs.end())
225*f4a2713aSLionel Sambuc     return 0;
226*f4a2713aSLionel Sambuc   return I->second;
227*f4a2713aSLionel Sambuc }
228*f4a2713aSLionel Sambuc 
229*f4a2713aSLionel Sambuc std::vector<MVT::SimpleValueType> CodeGenTarget::
230*f4a2713aSLionel Sambuc getRegisterVTs(Record *R) const {
231*f4a2713aSLionel Sambuc   const CodeGenRegister *Reg = getRegBank().getReg(R);
232*f4a2713aSLionel Sambuc   std::vector<MVT::SimpleValueType> Result;
233*f4a2713aSLionel Sambuc   ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses();
234*f4a2713aSLionel Sambuc   for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
235*f4a2713aSLionel Sambuc     const CodeGenRegisterClass &RC = *RCs[i];
236*f4a2713aSLionel Sambuc     if (RC.contains(Reg)) {
237*f4a2713aSLionel Sambuc       ArrayRef<MVT::SimpleValueType> InVTs = RC.getValueTypes();
238*f4a2713aSLionel Sambuc       Result.insert(Result.end(), InVTs.begin(), InVTs.end());
239*f4a2713aSLionel Sambuc     }
240*f4a2713aSLionel Sambuc   }
241*f4a2713aSLionel Sambuc 
242*f4a2713aSLionel Sambuc   // Remove duplicates.
243*f4a2713aSLionel Sambuc   array_pod_sort(Result.begin(), Result.end());
244*f4a2713aSLionel Sambuc   Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
245*f4a2713aSLionel Sambuc   return Result;
246*f4a2713aSLionel Sambuc }
247*f4a2713aSLionel Sambuc 
248*f4a2713aSLionel Sambuc 
249*f4a2713aSLionel Sambuc void CodeGenTarget::ReadLegalValueTypes() const {
250*f4a2713aSLionel Sambuc   ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses();
251*f4a2713aSLionel Sambuc   for (unsigned i = 0, e = RCs.size(); i != e; ++i)
252*f4a2713aSLionel Sambuc     for (unsigned ri = 0, re = RCs[i]->VTs.size(); ri != re; ++ri)
253*f4a2713aSLionel Sambuc       LegalValueTypes.push_back(RCs[i]->VTs[ri]);
254*f4a2713aSLionel Sambuc 
255*f4a2713aSLionel Sambuc   // Remove duplicates.
256*f4a2713aSLionel Sambuc   std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
257*f4a2713aSLionel Sambuc   LegalValueTypes.erase(std::unique(LegalValueTypes.begin(),
258*f4a2713aSLionel Sambuc                                     LegalValueTypes.end()),
259*f4a2713aSLionel Sambuc                         LegalValueTypes.end());
260*f4a2713aSLionel Sambuc }
261*f4a2713aSLionel Sambuc 
262*f4a2713aSLionel Sambuc CodeGenSchedModels &CodeGenTarget::getSchedModels() const {
263*f4a2713aSLionel Sambuc   if (!SchedModels)
264*f4a2713aSLionel Sambuc     SchedModels = new CodeGenSchedModels(Records, *this);
265*f4a2713aSLionel Sambuc   return *SchedModels;
266*f4a2713aSLionel Sambuc }
267*f4a2713aSLionel Sambuc 
268*f4a2713aSLionel Sambuc void CodeGenTarget::ReadInstructions() const {
269*f4a2713aSLionel Sambuc   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
270*f4a2713aSLionel Sambuc   if (Insts.size() <= 2)
271*f4a2713aSLionel Sambuc     PrintFatalError("No 'Instruction' subclasses defined!");
272*f4a2713aSLionel Sambuc 
273*f4a2713aSLionel Sambuc   // Parse the instructions defined in the .td file.
274*f4a2713aSLionel Sambuc   for (unsigned i = 0, e = Insts.size(); i != e; ++i)
275*f4a2713aSLionel Sambuc     Instructions[Insts[i]] = new CodeGenInstruction(Insts[i]);
276*f4a2713aSLionel Sambuc }
277*f4a2713aSLionel Sambuc 
278*f4a2713aSLionel Sambuc static const CodeGenInstruction *
279*f4a2713aSLionel Sambuc GetInstByName(const char *Name,
280*f4a2713aSLionel Sambuc               const DenseMap<const Record*, CodeGenInstruction*> &Insts,
281*f4a2713aSLionel Sambuc               RecordKeeper &Records) {
282*f4a2713aSLionel Sambuc   const Record *Rec = Records.getDef(Name);
283*f4a2713aSLionel Sambuc 
284*f4a2713aSLionel Sambuc   DenseMap<const Record*, CodeGenInstruction*>::const_iterator
285*f4a2713aSLionel Sambuc     I = Insts.find(Rec);
286*f4a2713aSLionel Sambuc   if (Rec == 0 || I == Insts.end())
287*f4a2713aSLionel Sambuc     PrintFatalError(std::string("Could not find '") + Name + "' instruction!");
288*f4a2713aSLionel Sambuc   return I->second;
289*f4a2713aSLionel Sambuc }
290*f4a2713aSLionel Sambuc 
291*f4a2713aSLionel Sambuc namespace {
292*f4a2713aSLionel Sambuc /// SortInstByName - Sorting predicate to sort instructions by name.
293*f4a2713aSLionel Sambuc ///
294*f4a2713aSLionel Sambuc struct SortInstByName {
295*f4a2713aSLionel Sambuc   bool operator()(const CodeGenInstruction *Rec1,
296*f4a2713aSLionel Sambuc                   const CodeGenInstruction *Rec2) const {
297*f4a2713aSLionel Sambuc     return Rec1->TheDef->getName() < Rec2->TheDef->getName();
298*f4a2713aSLionel Sambuc   }
299*f4a2713aSLionel Sambuc };
300*f4a2713aSLionel Sambuc }
301*f4a2713aSLionel Sambuc 
302*f4a2713aSLionel Sambuc /// getInstructionsByEnumValue - Return all of the instructions defined by the
303*f4a2713aSLionel Sambuc /// target, ordered by their enum value.
304*f4a2713aSLionel Sambuc void CodeGenTarget::ComputeInstrsByEnum() const {
305*f4a2713aSLionel Sambuc   // The ordering here must match the ordering in TargetOpcodes.h.
306*f4a2713aSLionel Sambuc   static const char *const FixedInstrs[] = {
307*f4a2713aSLionel Sambuc     "PHI",
308*f4a2713aSLionel Sambuc     "INLINEASM",
309*f4a2713aSLionel Sambuc     "PROLOG_LABEL",
310*f4a2713aSLionel Sambuc     "EH_LABEL",
311*f4a2713aSLionel Sambuc     "GC_LABEL",
312*f4a2713aSLionel Sambuc     "KILL",
313*f4a2713aSLionel Sambuc     "EXTRACT_SUBREG",
314*f4a2713aSLionel Sambuc     "INSERT_SUBREG",
315*f4a2713aSLionel Sambuc     "IMPLICIT_DEF",
316*f4a2713aSLionel Sambuc     "SUBREG_TO_REG",
317*f4a2713aSLionel Sambuc     "COPY_TO_REGCLASS",
318*f4a2713aSLionel Sambuc     "DBG_VALUE",
319*f4a2713aSLionel Sambuc     "REG_SEQUENCE",
320*f4a2713aSLionel Sambuc     "COPY",
321*f4a2713aSLionel Sambuc     "BUNDLE",
322*f4a2713aSLionel Sambuc     "LIFETIME_START",
323*f4a2713aSLionel Sambuc     "LIFETIME_END",
324*f4a2713aSLionel Sambuc     "STACKMAP",
325*f4a2713aSLionel Sambuc     "PATCHPOINT",
326*f4a2713aSLionel Sambuc     0
327*f4a2713aSLionel Sambuc   };
328*f4a2713aSLionel Sambuc   const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions();
329*f4a2713aSLionel Sambuc   for (const char *const *p = FixedInstrs; *p; ++p) {
330*f4a2713aSLionel Sambuc     const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records);
331*f4a2713aSLionel Sambuc     assert(Instr && "Missing target independent instruction");
332*f4a2713aSLionel Sambuc     assert(Instr->Namespace == "TargetOpcode" && "Bad namespace");
333*f4a2713aSLionel Sambuc     InstrsByEnum.push_back(Instr);
334*f4a2713aSLionel Sambuc   }
335*f4a2713aSLionel Sambuc   unsigned EndOfPredefines = InstrsByEnum.size();
336*f4a2713aSLionel Sambuc 
337*f4a2713aSLionel Sambuc   for (DenseMap<const Record*, CodeGenInstruction*>::const_iterator
338*f4a2713aSLionel Sambuc        I = Insts.begin(), E = Insts.end(); I != E; ++I) {
339*f4a2713aSLionel Sambuc     const CodeGenInstruction *CGI = I->second;
340*f4a2713aSLionel Sambuc     if (CGI->Namespace != "TargetOpcode")
341*f4a2713aSLionel Sambuc       InstrsByEnum.push_back(CGI);
342*f4a2713aSLionel Sambuc   }
343*f4a2713aSLionel Sambuc 
344*f4a2713aSLionel Sambuc   assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr");
345*f4a2713aSLionel Sambuc 
346*f4a2713aSLionel Sambuc   // All of the instructions are now in random order based on the map iteration.
347*f4a2713aSLionel Sambuc   // Sort them by name.
348*f4a2713aSLionel Sambuc   std::sort(InstrsByEnum.begin()+EndOfPredefines, InstrsByEnum.end(),
349*f4a2713aSLionel Sambuc             SortInstByName());
350*f4a2713aSLionel Sambuc }
351*f4a2713aSLionel Sambuc 
352*f4a2713aSLionel Sambuc 
353*f4a2713aSLionel Sambuc /// isLittleEndianEncoding - Return whether this target encodes its instruction
354*f4a2713aSLionel Sambuc /// in little-endian format, i.e. bits laid out in the order [0..n]
355*f4a2713aSLionel Sambuc ///
356*f4a2713aSLionel Sambuc bool CodeGenTarget::isLittleEndianEncoding() const {
357*f4a2713aSLionel Sambuc   return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
358*f4a2713aSLionel Sambuc }
359*f4a2713aSLionel Sambuc 
360*f4a2713aSLionel Sambuc /// guessInstructionProperties - Return true if it's OK to guess instruction
361*f4a2713aSLionel Sambuc /// properties instead of raising an error.
362*f4a2713aSLionel Sambuc ///
363*f4a2713aSLionel Sambuc /// This is configurable as a temporary migration aid. It will eventually be
364*f4a2713aSLionel Sambuc /// permanently false.
365*f4a2713aSLionel Sambuc bool CodeGenTarget::guessInstructionProperties() const {
366*f4a2713aSLionel Sambuc   return getInstructionSet()->getValueAsBit("guessInstructionProperties");
367*f4a2713aSLionel Sambuc }
368*f4a2713aSLionel Sambuc 
369*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
370*f4a2713aSLionel Sambuc // ComplexPattern implementation
371*f4a2713aSLionel Sambuc //
372*f4a2713aSLionel Sambuc ComplexPattern::ComplexPattern(Record *R) {
373*f4a2713aSLionel Sambuc   Ty          = ::getValueType(R->getValueAsDef("Ty"));
374*f4a2713aSLionel Sambuc   NumOperands = R->getValueAsInt("NumOperands");
375*f4a2713aSLionel Sambuc   SelectFunc  = R->getValueAsString("SelectFunc");
376*f4a2713aSLionel Sambuc   RootNodes   = R->getValueAsListOfDefs("RootNodes");
377*f4a2713aSLionel Sambuc 
378*f4a2713aSLionel Sambuc   // Parse the properties.
379*f4a2713aSLionel Sambuc   Properties = 0;
380*f4a2713aSLionel Sambuc   std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
381*f4a2713aSLionel Sambuc   for (unsigned i = 0, e = PropList.size(); i != e; ++i)
382*f4a2713aSLionel Sambuc     if (PropList[i]->getName() == "SDNPHasChain") {
383*f4a2713aSLionel Sambuc       Properties |= 1 << SDNPHasChain;
384*f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPOptInGlue") {
385*f4a2713aSLionel Sambuc       Properties |= 1 << SDNPOptInGlue;
386*f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPMayStore") {
387*f4a2713aSLionel Sambuc       Properties |= 1 << SDNPMayStore;
388*f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPMayLoad") {
389*f4a2713aSLionel Sambuc       Properties |= 1 << SDNPMayLoad;
390*f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPSideEffect") {
391*f4a2713aSLionel Sambuc       Properties |= 1 << SDNPSideEffect;
392*f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPMemOperand") {
393*f4a2713aSLionel Sambuc       Properties |= 1 << SDNPMemOperand;
394*f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPVariadic") {
395*f4a2713aSLionel Sambuc       Properties |= 1 << SDNPVariadic;
396*f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPWantRoot") {
397*f4a2713aSLionel Sambuc       Properties |= 1 << SDNPWantRoot;
398*f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPWantParent") {
399*f4a2713aSLionel Sambuc       Properties |= 1 << SDNPWantParent;
400*f4a2713aSLionel Sambuc     } else {
401*f4a2713aSLionel Sambuc       errs() << "Unsupported SD Node property '" << PropList[i]->getName()
402*f4a2713aSLionel Sambuc              << "' on ComplexPattern '" << R->getName() << "'!\n";
403*f4a2713aSLionel Sambuc       exit(1);
404*f4a2713aSLionel Sambuc     }
405*f4a2713aSLionel Sambuc }
406*f4a2713aSLionel Sambuc 
407*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
408*f4a2713aSLionel Sambuc // CodeGenIntrinsic Implementation
409*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
410*f4a2713aSLionel Sambuc 
411*f4a2713aSLionel Sambuc std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC,
412*f4a2713aSLionel Sambuc                                                    bool TargetOnly) {
413*f4a2713aSLionel Sambuc   std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
414*f4a2713aSLionel Sambuc 
415*f4a2713aSLionel Sambuc   std::vector<CodeGenIntrinsic> Result;
416*f4a2713aSLionel Sambuc 
417*f4a2713aSLionel Sambuc   for (unsigned i = 0, e = I.size(); i != e; ++i) {
418*f4a2713aSLionel Sambuc     bool isTarget = I[i]->getValueAsBit("isTarget");
419*f4a2713aSLionel Sambuc     if (isTarget == TargetOnly)
420*f4a2713aSLionel Sambuc       Result.push_back(CodeGenIntrinsic(I[i]));
421*f4a2713aSLionel Sambuc   }
422*f4a2713aSLionel Sambuc   return Result;
423*f4a2713aSLionel Sambuc }
424*f4a2713aSLionel Sambuc 
425*f4a2713aSLionel Sambuc CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
426*f4a2713aSLionel Sambuc   TheDef = R;
427*f4a2713aSLionel Sambuc   std::string DefName = R->getName();
428*f4a2713aSLionel Sambuc   ModRef = ReadWriteMem;
429*f4a2713aSLionel Sambuc   isOverloaded = false;
430*f4a2713aSLionel Sambuc   isCommutative = false;
431*f4a2713aSLionel Sambuc   canThrow = false;
432*f4a2713aSLionel Sambuc   isNoReturn = false;
433*f4a2713aSLionel Sambuc 
434*f4a2713aSLionel Sambuc   if (DefName.size() <= 4 ||
435*f4a2713aSLionel Sambuc       std::string(DefName.begin(), DefName.begin() + 4) != "int_")
436*f4a2713aSLionel Sambuc     PrintFatalError("Intrinsic '" + DefName + "' does not start with 'int_'!");
437*f4a2713aSLionel Sambuc 
438*f4a2713aSLionel Sambuc   EnumName = std::string(DefName.begin()+4, DefName.end());
439*f4a2713aSLionel Sambuc 
440*f4a2713aSLionel Sambuc   if (R->getValue("GCCBuiltinName"))  // Ignore a missing GCCBuiltinName field.
441*f4a2713aSLionel Sambuc     GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
442*f4a2713aSLionel Sambuc 
443*f4a2713aSLionel Sambuc   TargetPrefix = R->getValueAsString("TargetPrefix");
444*f4a2713aSLionel Sambuc   Name = R->getValueAsString("LLVMName");
445*f4a2713aSLionel Sambuc 
446*f4a2713aSLionel Sambuc   if (Name == "") {
447*f4a2713aSLionel Sambuc     // If an explicit name isn't specified, derive one from the DefName.
448*f4a2713aSLionel Sambuc     Name = "llvm.";
449*f4a2713aSLionel Sambuc 
450*f4a2713aSLionel Sambuc     for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
451*f4a2713aSLionel Sambuc       Name += (EnumName[i] == '_') ? '.' : EnumName[i];
452*f4a2713aSLionel Sambuc   } else {
453*f4a2713aSLionel Sambuc     // Verify it starts with "llvm.".
454*f4a2713aSLionel Sambuc     if (Name.size() <= 5 ||
455*f4a2713aSLionel Sambuc         std::string(Name.begin(), Name.begin() + 5) != "llvm.")
456*f4a2713aSLionel Sambuc       PrintFatalError("Intrinsic '" + DefName + "'s name does not start with 'llvm.'!");
457*f4a2713aSLionel Sambuc   }
458*f4a2713aSLionel Sambuc 
459*f4a2713aSLionel Sambuc   // If TargetPrefix is specified, make sure that Name starts with
460*f4a2713aSLionel Sambuc   // "llvm.<targetprefix>.".
461*f4a2713aSLionel Sambuc   if (!TargetPrefix.empty()) {
462*f4a2713aSLionel Sambuc     if (Name.size() < 6+TargetPrefix.size() ||
463*f4a2713aSLionel Sambuc         std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size())
464*f4a2713aSLionel Sambuc         != (TargetPrefix + "."))
465*f4a2713aSLionel Sambuc       PrintFatalError("Intrinsic '" + DefName + "' does not start with 'llvm." +
466*f4a2713aSLionel Sambuc         TargetPrefix + ".'!");
467*f4a2713aSLionel Sambuc   }
468*f4a2713aSLionel Sambuc 
469*f4a2713aSLionel Sambuc   // Parse the list of return types.
470*f4a2713aSLionel Sambuc   std::vector<MVT::SimpleValueType> OverloadedVTs;
471*f4a2713aSLionel Sambuc   ListInit *TypeList = R->getValueAsListInit("RetTypes");
472*f4a2713aSLionel Sambuc   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
473*f4a2713aSLionel Sambuc     Record *TyEl = TypeList->getElementAsRecord(i);
474*f4a2713aSLionel Sambuc     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
475*f4a2713aSLionel Sambuc     MVT::SimpleValueType VT;
476*f4a2713aSLionel Sambuc     if (TyEl->isSubClassOf("LLVMMatchType")) {
477*f4a2713aSLionel Sambuc       unsigned MatchTy = TyEl->getValueAsInt("Number");
478*f4a2713aSLionel Sambuc       assert(MatchTy < OverloadedVTs.size() &&
479*f4a2713aSLionel Sambuc              "Invalid matching number!");
480*f4a2713aSLionel Sambuc       VT = OverloadedVTs[MatchTy];
481*f4a2713aSLionel Sambuc       // It only makes sense to use the extended and truncated vector element
482*f4a2713aSLionel Sambuc       // variants with iAny types; otherwise, if the intrinsic is not
483*f4a2713aSLionel Sambuc       // overloaded, all the types can be specified directly.
484*f4a2713aSLionel Sambuc       assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
485*f4a2713aSLionel Sambuc                !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
486*f4a2713aSLionel Sambuc               VT == MVT::iAny || VT == MVT::vAny) &&
487*f4a2713aSLionel Sambuc              "Expected iAny or vAny type");
488*f4a2713aSLionel Sambuc     } else {
489*f4a2713aSLionel Sambuc       VT = getValueType(TyEl->getValueAsDef("VT"));
490*f4a2713aSLionel Sambuc     }
491*f4a2713aSLionel Sambuc     if (EVT(VT).isOverloaded()) {
492*f4a2713aSLionel Sambuc       OverloadedVTs.push_back(VT);
493*f4a2713aSLionel Sambuc       isOverloaded = true;
494*f4a2713aSLionel Sambuc     }
495*f4a2713aSLionel Sambuc 
496*f4a2713aSLionel Sambuc     // Reject invalid types.
497*f4a2713aSLionel Sambuc     if (VT == MVT::isVoid)
498*f4a2713aSLionel Sambuc       PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
499*f4a2713aSLionel Sambuc 
500*f4a2713aSLionel Sambuc     IS.RetVTs.push_back(VT);
501*f4a2713aSLionel Sambuc     IS.RetTypeDefs.push_back(TyEl);
502*f4a2713aSLionel Sambuc   }
503*f4a2713aSLionel Sambuc 
504*f4a2713aSLionel Sambuc   // Parse the list of parameter types.
505*f4a2713aSLionel Sambuc   TypeList = R->getValueAsListInit("ParamTypes");
506*f4a2713aSLionel Sambuc   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
507*f4a2713aSLionel Sambuc     Record *TyEl = TypeList->getElementAsRecord(i);
508*f4a2713aSLionel Sambuc     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
509*f4a2713aSLionel Sambuc     MVT::SimpleValueType VT;
510*f4a2713aSLionel Sambuc     if (TyEl->isSubClassOf("LLVMMatchType")) {
511*f4a2713aSLionel Sambuc       unsigned MatchTy = TyEl->getValueAsInt("Number");
512*f4a2713aSLionel Sambuc       assert(MatchTy < OverloadedVTs.size() &&
513*f4a2713aSLionel Sambuc              "Invalid matching number!");
514*f4a2713aSLionel Sambuc       VT = OverloadedVTs[MatchTy];
515*f4a2713aSLionel Sambuc       // It only makes sense to use the extended and truncated vector element
516*f4a2713aSLionel Sambuc       // variants with iAny types; otherwise, if the intrinsic is not
517*f4a2713aSLionel Sambuc       // overloaded, all the types can be specified directly.
518*f4a2713aSLionel Sambuc       assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
519*f4a2713aSLionel Sambuc                !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
520*f4a2713aSLionel Sambuc               VT == MVT::iAny || VT == MVT::vAny) &&
521*f4a2713aSLionel Sambuc              "Expected iAny or vAny type");
522*f4a2713aSLionel Sambuc     } else
523*f4a2713aSLionel Sambuc       VT = getValueType(TyEl->getValueAsDef("VT"));
524*f4a2713aSLionel Sambuc 
525*f4a2713aSLionel Sambuc     if (EVT(VT).isOverloaded()) {
526*f4a2713aSLionel Sambuc       OverloadedVTs.push_back(VT);
527*f4a2713aSLionel Sambuc       isOverloaded = true;
528*f4a2713aSLionel Sambuc     }
529*f4a2713aSLionel Sambuc 
530*f4a2713aSLionel Sambuc     // Reject invalid types.
531*f4a2713aSLionel Sambuc     if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
532*f4a2713aSLionel Sambuc       PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
533*f4a2713aSLionel Sambuc 
534*f4a2713aSLionel Sambuc     IS.ParamVTs.push_back(VT);
535*f4a2713aSLionel Sambuc     IS.ParamTypeDefs.push_back(TyEl);
536*f4a2713aSLionel Sambuc   }
537*f4a2713aSLionel Sambuc 
538*f4a2713aSLionel Sambuc   // Parse the intrinsic properties.
539*f4a2713aSLionel Sambuc   ListInit *PropList = R->getValueAsListInit("Properties");
540*f4a2713aSLionel Sambuc   for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) {
541*f4a2713aSLionel Sambuc     Record *Property = PropList->getElementAsRecord(i);
542*f4a2713aSLionel Sambuc     assert(Property->isSubClassOf("IntrinsicProperty") &&
543*f4a2713aSLionel Sambuc            "Expected a property!");
544*f4a2713aSLionel Sambuc 
545*f4a2713aSLionel Sambuc     if (Property->getName() == "IntrNoMem")
546*f4a2713aSLionel Sambuc       ModRef = NoMem;
547*f4a2713aSLionel Sambuc     else if (Property->getName() == "IntrReadArgMem")
548*f4a2713aSLionel Sambuc       ModRef = ReadArgMem;
549*f4a2713aSLionel Sambuc     else if (Property->getName() == "IntrReadMem")
550*f4a2713aSLionel Sambuc       ModRef = ReadMem;
551*f4a2713aSLionel Sambuc     else if (Property->getName() == "IntrReadWriteArgMem")
552*f4a2713aSLionel Sambuc       ModRef = ReadWriteArgMem;
553*f4a2713aSLionel Sambuc     else if (Property->getName() == "Commutative")
554*f4a2713aSLionel Sambuc       isCommutative = true;
555*f4a2713aSLionel Sambuc     else if (Property->getName() == "Throws")
556*f4a2713aSLionel Sambuc       canThrow = true;
557*f4a2713aSLionel Sambuc     else if (Property->getName() == "IntrNoReturn")
558*f4a2713aSLionel Sambuc       isNoReturn = true;
559*f4a2713aSLionel Sambuc     else if (Property->isSubClassOf("NoCapture")) {
560*f4a2713aSLionel Sambuc       unsigned ArgNo = Property->getValueAsInt("ArgNo");
561*f4a2713aSLionel Sambuc       ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
562*f4a2713aSLionel Sambuc     } else if (Property->isSubClassOf("ReadOnly")) {
563*f4a2713aSLionel Sambuc       unsigned ArgNo = Property->getValueAsInt("ArgNo");
564*f4a2713aSLionel Sambuc       ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly));
565*f4a2713aSLionel Sambuc     } else if (Property->isSubClassOf("ReadNone")) {
566*f4a2713aSLionel Sambuc       unsigned ArgNo = Property->getValueAsInt("ArgNo");
567*f4a2713aSLionel Sambuc       ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone));
568*f4a2713aSLionel Sambuc     } else
569*f4a2713aSLionel Sambuc       llvm_unreachable("Unknown property!");
570*f4a2713aSLionel Sambuc   }
571*f4a2713aSLionel Sambuc 
572*f4a2713aSLionel Sambuc   // Sort the argument attributes for later benefit.
573*f4a2713aSLionel Sambuc   std::sort(ArgumentAttributes.begin(), ArgumentAttributes.end());
574*f4a2713aSLionel Sambuc }
575