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