1f22ef01cSRoman Divacky //===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This class wraps target description classes used by the various code
11f22ef01cSRoman Divacky // generation TableGen backends.  This makes it easier to access the data and
12f22ef01cSRoman Divacky // provides a single place that needs to check it for validity.  All of these
133861d79fSDimitry Andric // classes abort on error conditions.
14f22ef01cSRoman Divacky //
15f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
16f22ef01cSRoman Divacky 
17f22ef01cSRoman Divacky #include "CodeGenTarget.h"
18f22ef01cSRoman Divacky #include "CodeGenIntrinsics.h"
197ae0e2c9SDimitry Andric #include "CodeGenSchedule.h"
20139f7f9bSDimitry Andric #include "llvm/ADT/STLExtras.h"
21139f7f9bSDimitry Andric #include "llvm/ADT/StringExtras.h"
22139f7f9bSDimitry Andric #include "llvm/Support/CommandLine.h"
233861d79fSDimitry Andric #include "llvm/TableGen/Error.h"
246122f3e6SDimitry Andric #include "llvm/TableGen/Record.h"
25f22ef01cSRoman Divacky #include <algorithm>
26f22ef01cSRoman Divacky using namespace llvm;
27f22ef01cSRoman Divacky 
28f22ef01cSRoman Divacky static cl::opt<unsigned>
29f22ef01cSRoman Divacky AsmParserNum("asmparsernum", cl::init(0),
30f22ef01cSRoman Divacky              cl::desc("Make -gen-asm-parser emit assembly parser #N"));
31f22ef01cSRoman Divacky 
32f22ef01cSRoman Divacky static cl::opt<unsigned>
33f22ef01cSRoman Divacky AsmWriterNum("asmwriternum", cl::init(0),
34f22ef01cSRoman Divacky              cl::desc("Make -gen-asm-writer emit assembly writer #N"));
35f22ef01cSRoman Divacky 
36f22ef01cSRoman Divacky /// getValueType - Return the MVT::SimpleValueType that the specified TableGen
37f22ef01cSRoman Divacky /// record corresponds to.
38f22ef01cSRoman Divacky MVT::SimpleValueType llvm::getValueType(Record *Rec) {
39f22ef01cSRoman Divacky   return (MVT::SimpleValueType)Rec->getValueAsInt("Value");
40f22ef01cSRoman Divacky }
41f22ef01cSRoman Divacky 
42f22ef01cSRoman Divacky std::string llvm::getName(MVT::SimpleValueType T) {
43f22ef01cSRoman Divacky   switch (T) {
44f22ef01cSRoman Divacky   case MVT::Other:   return "UNKNOWN";
45f22ef01cSRoman Divacky   case MVT::iPTR:    return "TLI.getPointerTy()";
46f22ef01cSRoman Divacky   case MVT::iPTRAny: return "TLI.getPointerTy()";
47f22ef01cSRoman Divacky   default: return getEnumName(T);
48f22ef01cSRoman Divacky   }
49f22ef01cSRoman Divacky }
50f22ef01cSRoman Divacky 
51f22ef01cSRoman Divacky std::string llvm::getEnumName(MVT::SimpleValueType T) {
52f22ef01cSRoman Divacky   switch (T) {
53f22ef01cSRoman Divacky   case MVT::Other:    return "MVT::Other";
54f22ef01cSRoman Divacky   case MVT::i1:       return "MVT::i1";
55f22ef01cSRoman Divacky   case MVT::i8:       return "MVT::i8";
56f22ef01cSRoman Divacky   case MVT::i16:      return "MVT::i16";
57f22ef01cSRoman Divacky   case MVT::i32:      return "MVT::i32";
58f22ef01cSRoman Divacky   case MVT::i64:      return "MVT::i64";
59f22ef01cSRoman Divacky   case MVT::i128:     return "MVT::i128";
60f22ef01cSRoman Divacky   case MVT::iAny:     return "MVT::iAny";
61f22ef01cSRoman Divacky   case MVT::fAny:     return "MVT::fAny";
62f22ef01cSRoman Divacky   case MVT::vAny:     return "MVT::vAny";
63dff0c46cSDimitry Andric   case MVT::f16:      return "MVT::f16";
64f22ef01cSRoman Divacky   case MVT::f32:      return "MVT::f32";
65f22ef01cSRoman Divacky   case MVT::f64:      return "MVT::f64";
66f22ef01cSRoman Divacky   case MVT::f80:      return "MVT::f80";
67f22ef01cSRoman Divacky   case MVT::f128:     return "MVT::f128";
68f22ef01cSRoman Divacky   case MVT::ppcf128:  return "MVT::ppcf128";
692754fe60SDimitry Andric   case MVT::x86mmx:   return "MVT::x86mmx";
702754fe60SDimitry Andric   case MVT::Glue:     return "MVT::Glue";
71f22ef01cSRoman Divacky   case MVT::isVoid:   return "MVT::isVoid";
723861d79fSDimitry Andric   case MVT::v2i1:     return "MVT::v2i1";
733861d79fSDimitry Andric   case MVT::v4i1:     return "MVT::v4i1";
743861d79fSDimitry Andric   case MVT::v8i1:     return "MVT::v8i1";
753861d79fSDimitry Andric   case MVT::v16i1:    return "MVT::v16i1";
76139f7f9bSDimitry Andric   case MVT::v32i1:    return "MVT::v32i1";
77139f7f9bSDimitry Andric   case MVT::v64i1:    return "MVT::v64i1";
78f785676fSDimitry Andric   case MVT::v1i8:     return "MVT::v1i8";
79f22ef01cSRoman Divacky   case MVT::v2i8:     return "MVT::v2i8";
80f22ef01cSRoman Divacky   case MVT::v4i8:     return "MVT::v4i8";
81f22ef01cSRoman Divacky   case MVT::v8i8:     return "MVT::v8i8";
82f22ef01cSRoman Divacky   case MVT::v16i8:    return "MVT::v16i8";
83f22ef01cSRoman Divacky   case MVT::v32i8:    return "MVT::v32i8";
84139f7f9bSDimitry Andric   case MVT::v64i8:    return "MVT::v64i8";
853861d79fSDimitry Andric   case MVT::v1i16:    return "MVT::v1i16";
86f22ef01cSRoman Divacky   case MVT::v2i16:    return "MVT::v2i16";
87f22ef01cSRoman Divacky   case MVT::v4i16:    return "MVT::v4i16";
88f22ef01cSRoman Divacky   case MVT::v8i16:    return "MVT::v8i16";
89f22ef01cSRoman Divacky   case MVT::v16i16:   return "MVT::v16i16";
90139f7f9bSDimitry Andric   case MVT::v32i16:   return "MVT::v32i16";
913861d79fSDimitry Andric   case MVT::v1i32:    return "MVT::v1i32";
92f22ef01cSRoman Divacky   case MVT::v2i32:    return "MVT::v2i32";
93f22ef01cSRoman Divacky   case MVT::v4i32:    return "MVT::v4i32";
94f22ef01cSRoman Divacky   case MVT::v8i32:    return "MVT::v8i32";
953861d79fSDimitry Andric   case MVT::v16i32:   return "MVT::v16i32";
96f22ef01cSRoman Divacky   case MVT::v1i64:    return "MVT::v1i64";
97f22ef01cSRoman Divacky   case MVT::v2i64:    return "MVT::v2i64";
98f22ef01cSRoman Divacky   case MVT::v4i64:    return "MVT::v4i64";
99f22ef01cSRoman Divacky   case MVT::v8i64:    return "MVT::v8i64";
1003861d79fSDimitry Andric   case MVT::v16i64:   return "MVT::v16i64";
101dff0c46cSDimitry Andric   case MVT::v2f16:    return "MVT::v2f16";
102f785676fSDimitry Andric   case MVT::v4f16:    return "MVT::v4f16";
103f785676fSDimitry Andric   case MVT::v8f16:    return "MVT::v8f16";
104f785676fSDimitry Andric   case MVT::v1f32:    return "MVT::v1f32";
105f22ef01cSRoman Divacky   case MVT::v2f32:    return "MVT::v2f32";
106f22ef01cSRoman Divacky   case MVT::v4f32:    return "MVT::v4f32";
107f22ef01cSRoman Divacky   case MVT::v8f32:    return "MVT::v8f32";
108139f7f9bSDimitry Andric   case MVT::v16f32:   return "MVT::v16f32";
109f785676fSDimitry Andric   case MVT::v1f64:    return "MVT::v1f64";
110f22ef01cSRoman Divacky   case MVT::v2f64:    return "MVT::v2f64";
111f22ef01cSRoman Divacky   case MVT::v4f64:    return "MVT::v4f64";
112139f7f9bSDimitry Andric   case MVT::v8f64:    return "MVT::v8f64";
113f22ef01cSRoman Divacky   case MVT::Metadata: return "MVT::Metadata";
114f22ef01cSRoman Divacky   case MVT::iPTR:     return "MVT::iPTR";
115f22ef01cSRoman Divacky   case MVT::iPTRAny:  return "MVT::iPTRAny";
116dff0c46cSDimitry Andric   case MVT::Untyped:  return "MVT::Untyped";
117dff0c46cSDimitry Andric   default: llvm_unreachable("ILLEGAL VALUE TYPE!");
118f22ef01cSRoman Divacky   }
119f22ef01cSRoman Divacky }
120f22ef01cSRoman Divacky 
121f22ef01cSRoman Divacky /// getQualifiedName - Return the name of the specified record, with a
122f22ef01cSRoman Divacky /// namespace qualifier if the record contains one.
123f22ef01cSRoman Divacky ///
124f22ef01cSRoman Divacky std::string llvm::getQualifiedName(const Record *R) {
125bd5abe19SDimitry Andric   std::string Namespace;
126bd5abe19SDimitry Andric   if (R->getValue("Namespace"))
127bd5abe19SDimitry Andric      Namespace = R->getValueAsString("Namespace");
128f22ef01cSRoman Divacky   if (Namespace.empty()) return R->getName();
129f22ef01cSRoman Divacky   return Namespace + "::" + R->getName();
130f22ef01cSRoman Divacky }
131f22ef01cSRoman Divacky 
132f22ef01cSRoman Divacky 
133f22ef01cSRoman Divacky /// getTarget - Return the current instance of the Target class.
134f22ef01cSRoman Divacky ///
135bd5abe19SDimitry Andric CodeGenTarget::CodeGenTarget(RecordKeeper &records)
13691bc56edSDimitry Andric   : Records(records), RegBank(nullptr), SchedModels(nullptr) {
137f22ef01cSRoman Divacky   std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
138f22ef01cSRoman Divacky   if (Targets.size() == 0)
1393861d79fSDimitry Andric     PrintFatalError("ERROR: No 'Target' subclasses defined!");
140f22ef01cSRoman Divacky   if (Targets.size() != 1)
1413861d79fSDimitry Andric     PrintFatalError("ERROR: Multiple subclasses of Target defined!");
142f22ef01cSRoman Divacky   TargetRec = Targets[0];
143f22ef01cSRoman Divacky }
144f22ef01cSRoman Divacky 
1457ae0e2c9SDimitry Andric CodeGenTarget::~CodeGenTarget() {
14691bc56edSDimitry Andric   DeleteContainerSeconds(Instructions);
1477ae0e2c9SDimitry Andric   delete RegBank;
1487ae0e2c9SDimitry Andric   delete SchedModels;
1497ae0e2c9SDimitry Andric }
150f22ef01cSRoman Divacky 
151f22ef01cSRoman Divacky const std::string &CodeGenTarget::getName() const {
152f22ef01cSRoman Divacky   return TargetRec->getName();
153f22ef01cSRoman Divacky }
154f22ef01cSRoman Divacky 
155f22ef01cSRoman Divacky std::string CodeGenTarget::getInstNamespace() const {
156f22ef01cSRoman Divacky   for (inst_iterator i = inst_begin(), e = inst_end(); i != e; ++i) {
157f22ef01cSRoman Divacky     // Make sure not to pick up "TargetOpcode" by accidentally getting
158f22ef01cSRoman Divacky     // the namespace off the PHI instruction or something.
159f22ef01cSRoman Divacky     if ((*i)->Namespace != "TargetOpcode")
160f22ef01cSRoman Divacky       return (*i)->Namespace;
161f22ef01cSRoman Divacky   }
162f22ef01cSRoman Divacky 
163f22ef01cSRoman Divacky   return "";
164f22ef01cSRoman Divacky }
165f22ef01cSRoman Divacky 
166f22ef01cSRoman Divacky Record *CodeGenTarget::getInstructionSet() const {
167f22ef01cSRoman Divacky   return TargetRec->getValueAsDef("InstructionSet");
168f22ef01cSRoman Divacky }
169f22ef01cSRoman Divacky 
170f22ef01cSRoman Divacky 
171f22ef01cSRoman Divacky /// getAsmParser - Return the AssemblyParser definition for this target.
172f22ef01cSRoman Divacky ///
173f22ef01cSRoman Divacky Record *CodeGenTarget::getAsmParser() const {
174f22ef01cSRoman Divacky   std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers");
175f22ef01cSRoman Divacky   if (AsmParserNum >= LI.size())
17691bc56edSDimitry Andric     PrintFatalError("Target does not have an AsmParser #" +
17791bc56edSDimitry Andric                     Twine(AsmParserNum) + "!");
178f22ef01cSRoman Divacky   return LI[AsmParserNum];
179f22ef01cSRoman Divacky }
180f22ef01cSRoman Divacky 
181dff0c46cSDimitry Andric /// getAsmParserVariant - Return the AssmblyParserVariant definition for
182dff0c46cSDimitry Andric /// this target.
183dff0c46cSDimitry Andric ///
184dff0c46cSDimitry Andric Record *CodeGenTarget::getAsmParserVariant(unsigned i) const {
185dff0c46cSDimitry Andric   std::vector<Record*> LI =
186dff0c46cSDimitry Andric     TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
187dff0c46cSDimitry Andric   if (i >= LI.size())
18891bc56edSDimitry Andric     PrintFatalError("Target does not have an AsmParserVariant #" + Twine(i) +
18991bc56edSDimitry Andric                     "!");
190dff0c46cSDimitry Andric   return LI[i];
191dff0c46cSDimitry Andric }
192dff0c46cSDimitry Andric 
193dff0c46cSDimitry Andric /// getAsmParserVariantCount - Return the AssmblyParserVariant definition
194dff0c46cSDimitry Andric /// available for this target.
195dff0c46cSDimitry Andric ///
196dff0c46cSDimitry Andric unsigned CodeGenTarget::getAsmParserVariantCount() const {
197dff0c46cSDimitry Andric   std::vector<Record*> LI =
198dff0c46cSDimitry Andric     TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
199dff0c46cSDimitry Andric   return LI.size();
200dff0c46cSDimitry Andric }
201dff0c46cSDimitry Andric 
202f22ef01cSRoman Divacky /// getAsmWriter - Return the AssemblyWriter definition for this target.
203f22ef01cSRoman Divacky ///
204f22ef01cSRoman Divacky Record *CodeGenTarget::getAsmWriter() const {
205f22ef01cSRoman Divacky   std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
206f22ef01cSRoman Divacky   if (AsmWriterNum >= LI.size())
20791bc56edSDimitry Andric     PrintFatalError("Target does not have an AsmWriter #" +
20891bc56edSDimitry Andric                     Twine(AsmWriterNum) + "!");
209f22ef01cSRoman Divacky   return LI[AsmWriterNum];
210f22ef01cSRoman Divacky }
211f22ef01cSRoman Divacky 
212bd5abe19SDimitry Andric CodeGenRegBank &CodeGenTarget::getRegBank() const {
213bd5abe19SDimitry Andric   if (!RegBank)
214bd5abe19SDimitry Andric     RegBank = new CodeGenRegBank(Records);
215bd5abe19SDimitry Andric   return *RegBank;
216f22ef01cSRoman Divacky }
217f22ef01cSRoman Divacky 
21817a519f9SDimitry Andric void CodeGenTarget::ReadRegAltNameIndices() const {
21917a519f9SDimitry Andric   RegAltNameIndices = Records.getAllDerivedDefinitions("RegAltNameIndex");
22017a519f9SDimitry Andric   std::sort(RegAltNameIndices.begin(), RegAltNameIndices.end(), LessRecord());
221f22ef01cSRoman Divacky }
222f22ef01cSRoman Divacky 
2232754fe60SDimitry Andric /// getRegisterByName - If there is a register with the specific AsmName,
2242754fe60SDimitry Andric /// return it.
2252754fe60SDimitry Andric const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const {
2263861d79fSDimitry Andric   const StringMap<CodeGenRegister*> &Regs = getRegBank().getRegistersByName();
2273861d79fSDimitry Andric   StringMap<CodeGenRegister*>::const_iterator I = Regs.find(Name);
2283861d79fSDimitry Andric   if (I == Regs.end())
22991bc56edSDimitry Andric     return nullptr;
2303861d79fSDimitry Andric   return I->second;
2312754fe60SDimitry Andric }
2322754fe60SDimitry Andric 
233f22ef01cSRoman Divacky std::vector<MVT::SimpleValueType> CodeGenTarget::
234f22ef01cSRoman Divacky getRegisterVTs(Record *R) const {
23517a519f9SDimitry Andric   const CodeGenRegister *Reg = getRegBank().getReg(R);
236f22ef01cSRoman Divacky   std::vector<MVT::SimpleValueType> Result;
2376122f3e6SDimitry Andric   ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses();
238f22ef01cSRoman Divacky   for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
2396122f3e6SDimitry Andric     const CodeGenRegisterClass &RC = *RCs[i];
24017a519f9SDimitry Andric     if (RC.contains(Reg)) {
241139f7f9bSDimitry Andric       ArrayRef<MVT::SimpleValueType> InVTs = RC.getValueTypes();
242f22ef01cSRoman Divacky       Result.insert(Result.end(), InVTs.begin(), InVTs.end());
243f22ef01cSRoman Divacky     }
244f22ef01cSRoman Divacky   }
245f22ef01cSRoman Divacky 
246f22ef01cSRoman Divacky   // Remove duplicates.
247f22ef01cSRoman Divacky   array_pod_sort(Result.begin(), Result.end());
248f22ef01cSRoman Divacky   Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
249f22ef01cSRoman Divacky   return Result;
250f22ef01cSRoman Divacky }
251f22ef01cSRoman Divacky 
252f22ef01cSRoman Divacky 
253f22ef01cSRoman Divacky void CodeGenTarget::ReadLegalValueTypes() const {
2546122f3e6SDimitry Andric   ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses();
255f22ef01cSRoman Divacky   for (unsigned i = 0, e = RCs.size(); i != e; ++i)
2566122f3e6SDimitry Andric     for (unsigned ri = 0, re = RCs[i]->VTs.size(); ri != re; ++ri)
2576122f3e6SDimitry Andric       LegalValueTypes.push_back(RCs[i]->VTs[ri]);
258f22ef01cSRoman Divacky 
259f22ef01cSRoman Divacky   // Remove duplicates.
260f22ef01cSRoman Divacky   std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
261f22ef01cSRoman Divacky   LegalValueTypes.erase(std::unique(LegalValueTypes.begin(),
262f22ef01cSRoman Divacky                                     LegalValueTypes.end()),
263f22ef01cSRoman Divacky                         LegalValueTypes.end());
264f22ef01cSRoman Divacky }
265f22ef01cSRoman Divacky 
2667ae0e2c9SDimitry Andric CodeGenSchedModels &CodeGenTarget::getSchedModels() const {
2677ae0e2c9SDimitry Andric   if (!SchedModels)
2687ae0e2c9SDimitry Andric     SchedModels = new CodeGenSchedModels(Records, *this);
2697ae0e2c9SDimitry Andric   return *SchedModels;
2707ae0e2c9SDimitry Andric }
271f22ef01cSRoman Divacky 
272f22ef01cSRoman Divacky void CodeGenTarget::ReadInstructions() const {
273f22ef01cSRoman Divacky   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
274f22ef01cSRoman Divacky   if (Insts.size() <= 2)
2753861d79fSDimitry Andric     PrintFatalError("No 'Instruction' subclasses defined!");
276f22ef01cSRoman Divacky 
277f22ef01cSRoman Divacky   // Parse the instructions defined in the .td file.
2782754fe60SDimitry Andric   for (unsigned i = 0, e = Insts.size(); i != e; ++i)
2792754fe60SDimitry Andric     Instructions[Insts[i]] = new CodeGenInstruction(Insts[i]);
280f22ef01cSRoman Divacky }
281f22ef01cSRoman Divacky 
282f22ef01cSRoman Divacky static const CodeGenInstruction *
283f22ef01cSRoman Divacky GetInstByName(const char *Name,
2842754fe60SDimitry Andric               const DenseMap<const Record*, CodeGenInstruction*> &Insts,
2852754fe60SDimitry Andric               RecordKeeper &Records) {
286f22ef01cSRoman Divacky   const Record *Rec = Records.getDef(Name);
287f22ef01cSRoman Divacky 
288f22ef01cSRoman Divacky   DenseMap<const Record*, CodeGenInstruction*>::const_iterator
289f22ef01cSRoman Divacky     I = Insts.find(Rec);
29091bc56edSDimitry Andric   if (!Rec || I == Insts.end())
29191bc56edSDimitry Andric     PrintFatalError(Twine("Could not find '") + Name + "' instruction!");
292f22ef01cSRoman Divacky   return I->second;
293f22ef01cSRoman Divacky }
294f22ef01cSRoman Divacky 
29591bc56edSDimitry Andric /// \brief Return all of the instructions defined by the target, ordered by
29691bc56edSDimitry Andric /// their enum value.
297f22ef01cSRoman Divacky void CodeGenTarget::ComputeInstrsByEnum() const {
298ffd1746dSEd Schouten   // The ordering here must match the ordering in TargetOpcodes.h.
299f785676fSDimitry Andric   static const char *const FixedInstrs[] = {
30091bc56edSDimitry Andric       "PHI",          "INLINEASM",     "CFI_INSTRUCTION",  "EH_LABEL",
30191bc56edSDimitry Andric       "GC_LABEL",     "KILL",          "EXTRACT_SUBREG",   "INSERT_SUBREG",
30291bc56edSDimitry Andric       "IMPLICIT_DEF", "SUBREG_TO_REG", "COPY_TO_REGCLASS", "DBG_VALUE",
30391bc56edSDimitry Andric       "REG_SEQUENCE", "COPY",          "BUNDLE",           "LIFETIME_START",
30491bc56edSDimitry Andric       "LIFETIME_END", "STACKMAP",      "PATCHPOINT",       nullptr};
305f22ef01cSRoman Divacky   const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions();
306ffd1746dSEd Schouten   for (const char *const *p = FixedInstrs; *p; ++p) {
3072754fe60SDimitry Andric     const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records);
308ffd1746dSEd Schouten     assert(Instr && "Missing target independent instruction");
309ffd1746dSEd Schouten     assert(Instr->Namespace == "TargetOpcode" && "Bad namespace");
310ffd1746dSEd Schouten     InstrsByEnum.push_back(Instr);
311ffd1746dSEd Schouten   }
312f22ef01cSRoman Divacky   unsigned EndOfPredefines = InstrsByEnum.size();
313f22ef01cSRoman Divacky 
314f22ef01cSRoman Divacky   for (DenseMap<const Record*, CodeGenInstruction*>::const_iterator
315f22ef01cSRoman Divacky        I = Insts.begin(), E = Insts.end(); I != E; ++I) {
316f22ef01cSRoman Divacky     const CodeGenInstruction *CGI = I->second;
317ffd1746dSEd Schouten     if (CGI->Namespace != "TargetOpcode")
318f22ef01cSRoman Divacky       InstrsByEnum.push_back(CGI);
319f22ef01cSRoman Divacky   }
320f22ef01cSRoman Divacky 
321ffd1746dSEd Schouten   assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr");
322ffd1746dSEd Schouten 
323f22ef01cSRoman Divacky   // All of the instructions are now in random order based on the map iteration.
324f22ef01cSRoman Divacky   // Sort them by name.
325f22ef01cSRoman Divacky   std::sort(InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(),
32691bc56edSDimitry Andric             [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) {
32791bc56edSDimitry Andric     return Rec1->TheDef->getName() < Rec2->TheDef->getName();
32891bc56edSDimitry Andric   });
329f22ef01cSRoman Divacky }
330f22ef01cSRoman Divacky 
331f22ef01cSRoman Divacky 
332f22ef01cSRoman Divacky /// isLittleEndianEncoding - Return whether this target encodes its instruction
333f22ef01cSRoman Divacky /// in little-endian format, i.e. bits laid out in the order [0..n]
334f22ef01cSRoman Divacky ///
335f22ef01cSRoman Divacky bool CodeGenTarget::isLittleEndianEncoding() const {
336f22ef01cSRoman Divacky   return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
337f22ef01cSRoman Divacky }
338f22ef01cSRoman Divacky 
33991bc56edSDimitry Andric /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
34091bc56edSDimitry Andric /// encodings, reverse the bit order of all instructions.
34191bc56edSDimitry Andric void CodeGenTarget::reverseBitsForLittleEndianEncoding() {
34291bc56edSDimitry Andric   if (!isLittleEndianEncoding())
34391bc56edSDimitry Andric     return;
34491bc56edSDimitry Andric 
34591bc56edSDimitry Andric   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
34691bc56edSDimitry Andric   for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
34791bc56edSDimitry Andric        I != E; ++I) {
34891bc56edSDimitry Andric     Record *R = *I;
34991bc56edSDimitry Andric     if (R->getValueAsString("Namespace") == "TargetOpcode" ||
35091bc56edSDimitry Andric         R->getValueAsBit("isPseudo"))
35191bc56edSDimitry Andric       continue;
35291bc56edSDimitry Andric 
35391bc56edSDimitry Andric     BitsInit *BI = R->getValueAsBitsInit("Inst");
35491bc56edSDimitry Andric 
35591bc56edSDimitry Andric     unsigned numBits = BI->getNumBits();
35691bc56edSDimitry Andric 
35791bc56edSDimitry Andric     SmallVector<Init *, 16> NewBits(numBits);
35891bc56edSDimitry Andric 
35991bc56edSDimitry Andric     for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
36091bc56edSDimitry Andric       unsigned bitSwapIdx = numBits - bit - 1;
36191bc56edSDimitry Andric       Init *OrigBit = BI->getBit(bit);
36291bc56edSDimitry Andric       Init *BitSwap = BI->getBit(bitSwapIdx);
36391bc56edSDimitry Andric       NewBits[bit]        = BitSwap;
36491bc56edSDimitry Andric       NewBits[bitSwapIdx] = OrigBit;
36591bc56edSDimitry Andric     }
36691bc56edSDimitry Andric     if (numBits % 2) {
36791bc56edSDimitry Andric       unsigned middle = (numBits + 1) / 2;
36891bc56edSDimitry Andric       NewBits[middle] = BI->getBit(middle);
36991bc56edSDimitry Andric     }
37091bc56edSDimitry Andric 
37191bc56edSDimitry Andric     BitsInit *NewBI = BitsInit::get(NewBits);
37291bc56edSDimitry Andric 
37391bc56edSDimitry Andric     // Update the bits in reversed order so that emitInstrOpBits will get the
37491bc56edSDimitry Andric     // correct endianness.
37591bc56edSDimitry Andric     R->getValue("Inst")->setValue(NewBI);
37691bc56edSDimitry Andric   }
37791bc56edSDimitry Andric }
37891bc56edSDimitry Andric 
3793861d79fSDimitry Andric /// guessInstructionProperties - Return true if it's OK to guess instruction
3803861d79fSDimitry Andric /// properties instead of raising an error.
3813861d79fSDimitry Andric ///
3823861d79fSDimitry Andric /// This is configurable as a temporary migration aid. It will eventually be
3833861d79fSDimitry Andric /// permanently false.
3843861d79fSDimitry Andric bool CodeGenTarget::guessInstructionProperties() const {
3853861d79fSDimitry Andric   return getInstructionSet()->getValueAsBit("guessInstructionProperties");
3863861d79fSDimitry Andric }
3873861d79fSDimitry Andric 
388f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
389f22ef01cSRoman Divacky // ComplexPattern implementation
390f22ef01cSRoman Divacky //
391f22ef01cSRoman Divacky ComplexPattern::ComplexPattern(Record *R) {
392f22ef01cSRoman Divacky   Ty          = ::getValueType(R->getValueAsDef("Ty"));
393f22ef01cSRoman Divacky   NumOperands = R->getValueAsInt("NumOperands");
394f22ef01cSRoman Divacky   SelectFunc  = R->getValueAsString("SelectFunc");
395f22ef01cSRoman Divacky   RootNodes   = R->getValueAsListOfDefs("RootNodes");
396f22ef01cSRoman Divacky 
397f22ef01cSRoman Divacky   // Parse the properties.
398f22ef01cSRoman Divacky   Properties = 0;
399f22ef01cSRoman Divacky   std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
400f22ef01cSRoman Divacky   for (unsigned i = 0, e = PropList.size(); i != e; ++i)
401f22ef01cSRoman Divacky     if (PropList[i]->getName() == "SDNPHasChain") {
402f22ef01cSRoman Divacky       Properties |= 1 << SDNPHasChain;
4032754fe60SDimitry Andric     } else if (PropList[i]->getName() == "SDNPOptInGlue") {
4042754fe60SDimitry Andric       Properties |= 1 << SDNPOptInGlue;
405f22ef01cSRoman Divacky     } else if (PropList[i]->getName() == "SDNPMayStore") {
406f22ef01cSRoman Divacky       Properties |= 1 << SDNPMayStore;
407f22ef01cSRoman Divacky     } else if (PropList[i]->getName() == "SDNPMayLoad") {
408f22ef01cSRoman Divacky       Properties |= 1 << SDNPMayLoad;
409f22ef01cSRoman Divacky     } else if (PropList[i]->getName() == "SDNPSideEffect") {
410f22ef01cSRoman Divacky       Properties |= 1 << SDNPSideEffect;
411f22ef01cSRoman Divacky     } else if (PropList[i]->getName() == "SDNPMemOperand") {
412f22ef01cSRoman Divacky       Properties |= 1 << SDNPMemOperand;
413f22ef01cSRoman Divacky     } else if (PropList[i]->getName() == "SDNPVariadic") {
414f22ef01cSRoman Divacky       Properties |= 1 << SDNPVariadic;
4152754fe60SDimitry Andric     } else if (PropList[i]->getName() == "SDNPWantRoot") {
4162754fe60SDimitry Andric       Properties |= 1 << SDNPWantRoot;
4172754fe60SDimitry Andric     } else if (PropList[i]->getName() == "SDNPWantParent") {
4182754fe60SDimitry Andric       Properties |= 1 << SDNPWantParent;
419f22ef01cSRoman Divacky     } else {
420f22ef01cSRoman Divacky       errs() << "Unsupported SD Node property '" << PropList[i]->getName()
421f22ef01cSRoman Divacky              << "' on ComplexPattern '" << R->getName() << "'!\n";
422f22ef01cSRoman Divacky       exit(1);
423f22ef01cSRoman Divacky     }
424f22ef01cSRoman Divacky }
425f22ef01cSRoman Divacky 
426f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
427f22ef01cSRoman Divacky // CodeGenIntrinsic Implementation
428f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
429f22ef01cSRoman Divacky 
430f22ef01cSRoman Divacky std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC,
431f22ef01cSRoman Divacky                                                    bool TargetOnly) {
432f22ef01cSRoman Divacky   std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
433f22ef01cSRoman Divacky 
434f22ef01cSRoman Divacky   std::vector<CodeGenIntrinsic> Result;
435f22ef01cSRoman Divacky 
436f22ef01cSRoman Divacky   for (unsigned i = 0, e = I.size(); i != e; ++i) {
437f22ef01cSRoman Divacky     bool isTarget = I[i]->getValueAsBit("isTarget");
438f22ef01cSRoman Divacky     if (isTarget == TargetOnly)
439f22ef01cSRoman Divacky       Result.push_back(CodeGenIntrinsic(I[i]));
440f22ef01cSRoman Divacky   }
441f22ef01cSRoman Divacky   return Result;
442f22ef01cSRoman Divacky }
443f22ef01cSRoman Divacky 
444f22ef01cSRoman Divacky CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
445f22ef01cSRoman Divacky   TheDef = R;
446f22ef01cSRoman Divacky   std::string DefName = R->getName();
447e580952dSDimitry Andric   ModRef = ReadWriteMem;
448f22ef01cSRoman Divacky   isOverloaded = false;
449f22ef01cSRoman Divacky   isCommutative = false;
450bd5abe19SDimitry Andric   canThrow = false;
4517ae0e2c9SDimitry Andric   isNoReturn = false;
45291bc56edSDimitry Andric   isNoDuplicate = false;
453f22ef01cSRoman Divacky 
454f22ef01cSRoman Divacky   if (DefName.size() <= 4 ||
455f22ef01cSRoman Divacky       std::string(DefName.begin(), DefName.begin() + 4) != "int_")
4563861d79fSDimitry Andric     PrintFatalError("Intrinsic '" + DefName + "' does not start with 'int_'!");
457f22ef01cSRoman Divacky 
458f22ef01cSRoman Divacky   EnumName = std::string(DefName.begin()+4, DefName.end());
459f22ef01cSRoman Divacky 
460f22ef01cSRoman Divacky   if (R->getValue("GCCBuiltinName"))  // Ignore a missing GCCBuiltinName field.
461f22ef01cSRoman Divacky     GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
46291bc56edSDimitry Andric   if (R->getValue("MSBuiltinName"))   // Ignore a missing MSBuiltinName field.
46391bc56edSDimitry Andric     MSBuiltinName = R->getValueAsString("MSBuiltinName");
464f22ef01cSRoman Divacky 
465f22ef01cSRoman Divacky   TargetPrefix = R->getValueAsString("TargetPrefix");
466f22ef01cSRoman Divacky   Name = R->getValueAsString("LLVMName");
467f22ef01cSRoman Divacky 
468f22ef01cSRoman Divacky   if (Name == "") {
469f22ef01cSRoman Divacky     // If an explicit name isn't specified, derive one from the DefName.
470f22ef01cSRoman Divacky     Name = "llvm.";
471f22ef01cSRoman Divacky 
472f22ef01cSRoman Divacky     for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
473f22ef01cSRoman Divacky       Name += (EnumName[i] == '_') ? '.' : EnumName[i];
474f22ef01cSRoman Divacky   } else {
475f22ef01cSRoman Divacky     // Verify it starts with "llvm.".
476f22ef01cSRoman Divacky     if (Name.size() <= 5 ||
477f22ef01cSRoman Divacky         std::string(Name.begin(), Name.begin() + 5) != "llvm.")
4783861d79fSDimitry Andric       PrintFatalError("Intrinsic '" + DefName + "'s name does not start with 'llvm.'!");
479f22ef01cSRoman Divacky   }
480f22ef01cSRoman Divacky 
481f22ef01cSRoman Divacky   // If TargetPrefix is specified, make sure that Name starts with
482f22ef01cSRoman Divacky   // "llvm.<targetprefix>.".
483f22ef01cSRoman Divacky   if (!TargetPrefix.empty()) {
484f22ef01cSRoman Divacky     if (Name.size() < 6+TargetPrefix.size() ||
485f22ef01cSRoman Divacky         std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size())
486f22ef01cSRoman Divacky         != (TargetPrefix + "."))
4873861d79fSDimitry Andric       PrintFatalError("Intrinsic '" + DefName + "' does not start with 'llvm." +
4883861d79fSDimitry Andric         TargetPrefix + ".'!");
489f22ef01cSRoman Divacky   }
490f22ef01cSRoman Divacky 
491f22ef01cSRoman Divacky   // Parse the list of return types.
492f22ef01cSRoman Divacky   std::vector<MVT::SimpleValueType> OverloadedVTs;
493f22ef01cSRoman Divacky   ListInit *TypeList = R->getValueAsListInit("RetTypes");
494f22ef01cSRoman Divacky   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
495f22ef01cSRoman Divacky     Record *TyEl = TypeList->getElementAsRecord(i);
496f22ef01cSRoman Divacky     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
497f22ef01cSRoman Divacky     MVT::SimpleValueType VT;
498f22ef01cSRoman Divacky     if (TyEl->isSubClassOf("LLVMMatchType")) {
499f22ef01cSRoman Divacky       unsigned MatchTy = TyEl->getValueAsInt("Number");
500f22ef01cSRoman Divacky       assert(MatchTy < OverloadedVTs.size() &&
501f22ef01cSRoman Divacky              "Invalid matching number!");
502f22ef01cSRoman Divacky       VT = OverloadedVTs[MatchTy];
503f22ef01cSRoman Divacky       // It only makes sense to use the extended and truncated vector element
504f22ef01cSRoman Divacky       // variants with iAny types; otherwise, if the intrinsic is not
505f22ef01cSRoman Divacky       // overloaded, all the types can be specified directly.
50691bc56edSDimitry Andric       assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
50791bc56edSDimitry Andric                !TyEl->isSubClassOf("LLVMTruncatedType")) ||
508f22ef01cSRoman Divacky               VT == MVT::iAny || VT == MVT::vAny) &&
509f22ef01cSRoman Divacky              "Expected iAny or vAny type");
510f22ef01cSRoman Divacky     } else {
511f22ef01cSRoman Divacky       VT = getValueType(TyEl->getValueAsDef("VT"));
512f22ef01cSRoman Divacky     }
51391bc56edSDimitry Andric     if (MVT(VT).isOverloaded()) {
514f22ef01cSRoman Divacky       OverloadedVTs.push_back(VT);
515f22ef01cSRoman Divacky       isOverloaded = true;
516f22ef01cSRoman Divacky     }
517f22ef01cSRoman Divacky 
518f22ef01cSRoman Divacky     // Reject invalid types.
519f22ef01cSRoman Divacky     if (VT == MVT::isVoid)
5203861d79fSDimitry Andric       PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
521f22ef01cSRoman Divacky 
522f22ef01cSRoman Divacky     IS.RetVTs.push_back(VT);
523f22ef01cSRoman Divacky     IS.RetTypeDefs.push_back(TyEl);
524f22ef01cSRoman Divacky   }
525f22ef01cSRoman Divacky 
526f22ef01cSRoman Divacky   // Parse the list of parameter types.
527f22ef01cSRoman Divacky   TypeList = R->getValueAsListInit("ParamTypes");
528f22ef01cSRoman Divacky   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
529f22ef01cSRoman Divacky     Record *TyEl = TypeList->getElementAsRecord(i);
530f22ef01cSRoman Divacky     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
531f22ef01cSRoman Divacky     MVT::SimpleValueType VT;
532f22ef01cSRoman Divacky     if (TyEl->isSubClassOf("LLVMMatchType")) {
533f22ef01cSRoman Divacky       unsigned MatchTy = TyEl->getValueAsInt("Number");
534f22ef01cSRoman Divacky       assert(MatchTy < OverloadedVTs.size() &&
535f22ef01cSRoman Divacky              "Invalid matching number!");
536f22ef01cSRoman Divacky       VT = OverloadedVTs[MatchTy];
537f22ef01cSRoman Divacky       // It only makes sense to use the extended and truncated vector element
538f22ef01cSRoman Divacky       // variants with iAny types; otherwise, if the intrinsic is not
539f22ef01cSRoman Divacky       // overloaded, all the types can be specified directly.
54091bc56edSDimitry Andric       assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
54191bc56edSDimitry Andric                !TyEl->isSubClassOf("LLVMTruncatedType")) ||
542f22ef01cSRoman Divacky               VT == MVT::iAny || VT == MVT::vAny) &&
543f22ef01cSRoman Divacky              "Expected iAny or vAny type");
544f22ef01cSRoman Divacky     } else
545f22ef01cSRoman Divacky       VT = getValueType(TyEl->getValueAsDef("VT"));
546f22ef01cSRoman Divacky 
54791bc56edSDimitry Andric     if (MVT(VT).isOverloaded()) {
548f22ef01cSRoman Divacky       OverloadedVTs.push_back(VT);
549f22ef01cSRoman Divacky       isOverloaded = true;
550f22ef01cSRoman Divacky     }
551f22ef01cSRoman Divacky 
552f22ef01cSRoman Divacky     // Reject invalid types.
553f22ef01cSRoman Divacky     if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
5543861d79fSDimitry Andric       PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
555f22ef01cSRoman Divacky 
556f22ef01cSRoman Divacky     IS.ParamVTs.push_back(VT);
557f22ef01cSRoman Divacky     IS.ParamTypeDefs.push_back(TyEl);
558f22ef01cSRoman Divacky   }
559f22ef01cSRoman Divacky 
560f22ef01cSRoman Divacky   // Parse the intrinsic properties.
561f22ef01cSRoman Divacky   ListInit *PropList = R->getValueAsListInit("Properties");
562f22ef01cSRoman Divacky   for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) {
563f22ef01cSRoman Divacky     Record *Property = PropList->getElementAsRecord(i);
564f22ef01cSRoman Divacky     assert(Property->isSubClassOf("IntrinsicProperty") &&
565f22ef01cSRoman Divacky            "Expected a property!");
566f22ef01cSRoman Divacky 
567f22ef01cSRoman Divacky     if (Property->getName() == "IntrNoMem")
568f22ef01cSRoman Divacky       ModRef = NoMem;
569f22ef01cSRoman Divacky     else if (Property->getName() == "IntrReadArgMem")
570f22ef01cSRoman Divacky       ModRef = ReadArgMem;
571f22ef01cSRoman Divacky     else if (Property->getName() == "IntrReadMem")
572f22ef01cSRoman Divacky       ModRef = ReadMem;
573e580952dSDimitry Andric     else if (Property->getName() == "IntrReadWriteArgMem")
574e580952dSDimitry Andric       ModRef = ReadWriteArgMem;
575f22ef01cSRoman Divacky     else if (Property->getName() == "Commutative")
576f22ef01cSRoman Divacky       isCommutative = true;
577bd5abe19SDimitry Andric     else if (Property->getName() == "Throws")
578bd5abe19SDimitry Andric       canThrow = true;
57991bc56edSDimitry Andric     else if (Property->getName() == "IntrNoDuplicate")
58091bc56edSDimitry Andric       isNoDuplicate = true;
5817ae0e2c9SDimitry Andric     else if (Property->getName() == "IntrNoReturn")
5827ae0e2c9SDimitry Andric       isNoReturn = true;
583f22ef01cSRoman Divacky     else if (Property->isSubClassOf("NoCapture")) {
584f22ef01cSRoman Divacky       unsigned ArgNo = Property->getValueAsInt("ArgNo");
585f22ef01cSRoman Divacky       ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
586f785676fSDimitry Andric     } else if (Property->isSubClassOf("ReadOnly")) {
587f785676fSDimitry Andric       unsigned ArgNo = Property->getValueAsInt("ArgNo");
588f785676fSDimitry Andric       ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly));
589f785676fSDimitry Andric     } else if (Property->isSubClassOf("ReadNone")) {
590f785676fSDimitry Andric       unsigned ArgNo = Property->getValueAsInt("ArgNo");
591f785676fSDimitry Andric       ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone));
592f22ef01cSRoman Divacky     } else
593dff0c46cSDimitry Andric       llvm_unreachable("Unknown property!");
594f22ef01cSRoman Divacky   }
595bd5abe19SDimitry Andric 
596bd5abe19SDimitry Andric   // Sort the argument attributes for later benefit.
597bd5abe19SDimitry Andric   std::sort(ArgumentAttributes.begin(), ArgumentAttributes.end());
598f22ef01cSRoman Divacky }
599