CodeGenTarget.cpp revision 243830
167761Smsmith//===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===// 278915Smsmith// 367761Smsmith// The LLVM Compiler Infrastructure 467761Smsmith// 567761Smsmith// This file is distributed under the University of Illinois Open Source 667761Smsmith// License. See LICENSE.TXT for details. 767761Smsmith// 867761Smsmith//===----------------------------------------------------------------------===// 967761Smsmith// 1067761Smsmith// This class wraps target description classes used by the various code 1167761Smsmith// generation TableGen backends. This makes it easier to access the data and 1267761Smsmith// provides a single place that needs to check it for validity. All of these 1367761Smsmith// classes abort on error conditions. 1467761Smsmith// 1567761Smsmith//===----------------------------------------------------------------------===// 1667761Smsmith 1767761Smsmith#include "CodeGenTarget.h" 1867761Smsmith#include "CodeGenIntrinsics.h" 1967761Smsmith#include "CodeGenSchedule.h" 2067761Smsmith#include "llvm/TableGen/Error.h" 2167761Smsmith#include "llvm/TableGen/Record.h" 2267761Smsmith#include "llvm/ADT/StringExtras.h" 2367761Smsmith#include "llvm/ADT/STLExtras.h" 2467761Smsmith#include "llvm/Support/CommandLine.h" 2567761Smsmith#include <algorithm> 2667761Smsmithusing namespace llvm; 2767761Smsmith 28119418Sobrienstatic cl::opt<unsigned> 29119418SobrienAsmParserNum("asmparsernum", cl::init(0), 30119418Sobrien cl::desc("Make -gen-asm-parser emit assembly parser #N")); 3167761Smsmith 3267761Smsmithstatic cl::opt<unsigned> 3367761SmsmithAsmWriterNum("asmwriternum", cl::init(0), 3491126Smsmith cl::desc("Make -gen-asm-writer emit assembly writer #N")); 3567761Smsmith 3691126Smsmith/// getValueType - Return the MVT::SimpleValueType that the specified TableGen 3778915Smsmith/// record corresponds to. 3879283SmsmithMVT::SimpleValueType llvm::getValueType(Record *Rec) { 3991126Smsmith return (MVT::SimpleValueType)Rec->getValueAsInt("Value"); 4091640Siwasaki} 4167761Smsmith 4267761Smsmithstd::string llvm::getName(MVT::SimpleValueType T) { 4367761Smsmith switch (T) { 4467761Smsmith case MVT::Other: return "UNKNOWN"; 45119529Snjl case MVT::iPTR: return "TLI.getPointerTy()"; 4678999Smsmith case MVT::iPTRAny: return "TLI.getPointerTy()"; 4791126Smsmith default: return getEnumName(T); 4869744Smsmith } 4971874Smsmith} 5071874Smsmith 5167761Smsmithstd::string llvm::getEnumName(MVT::SimpleValueType T) { 5278915Smsmith switch (T) { 5378915Smsmith case MVT::Other: return "MVT::Other"; 5478915Smsmith case MVT::i1: return "MVT::i1"; 5578915Smsmith case MVT::i8: return "MVT::i8"; 56119529Snjl case MVT::i16: return "MVT::i16"; 57119529Snjl case MVT::i32: return "MVT::i32"; 5878915Smsmith case MVT::i64: return "MVT::i64"; 59119529Snjl case MVT::i128: return "MVT::i128"; 60119529Snjl case MVT::iAny: return "MVT::iAny"; 6179375Smsmith case MVT::fAny: return "MVT::fAny"; 6278915Smsmith case MVT::vAny: return "MVT::vAny"; 6378915Smsmith case MVT::f16: return "MVT::f16"; 6478915Smsmith case MVT::f32: return "MVT::f32"; 6578915Smsmith case MVT::f64: return "MVT::f64"; 6678915Smsmith case MVT::f80: return "MVT::f80"; 6778915Smsmith case MVT::f128: return "MVT::f128"; 6878915Smsmith case MVT::ppcf128: return "MVT::ppcf128"; 6978915Smsmith case MVT::x86mmx: return "MVT::x86mmx"; 7078915Smsmith case MVT::Glue: return "MVT::Glue"; 7178915Smsmith case MVT::isVoid: return "MVT::isVoid"; 7278915Smsmith case MVT::v2i1: return "MVT::v2i1"; 7378915Smsmith case MVT::v4i1: return "MVT::v4i1"; 7478915Smsmith case MVT::v8i1: return "MVT::v8i1"; 7567761Smsmith case MVT::v16i1: return "MVT::v16i1"; 76119529Snjl case MVT::v2i8: return "MVT::v2i8"; 77119529Snjl case MVT::v4i8: return "MVT::v4i8"; 78119529Snjl case MVT::v8i8: return "MVT::v8i8"; 79119529Snjl case MVT::v16i8: return "MVT::v16i8"; 8079375Smsmith case MVT::v32i8: return "MVT::v32i8"; 81119529Snjl case MVT::v1i16: return "MVT::v1i16"; 82119529Snjl case MVT::v2i16: return "MVT::v2i16"; 8379375Smsmith case MVT::v4i16: return "MVT::v4i16"; 8479375Smsmith case MVT::v8i16: return "MVT::v8i16"; 8579375Smsmith case MVT::v16i16: return "MVT::v16i16"; 8679375Smsmith case MVT::v1i32: return "MVT::v1i32"; 8779283Smsmith case MVT::v2i32: return "MVT::v2i32"; 88119529Snjl case MVT::v4i32: return "MVT::v4i32"; 89119529Snjl case MVT::v8i32: return "MVT::v8i32"; 90119529Snjl case MVT::v16i32: return "MVT::v16i32"; 91119529Snjl case MVT::v1i64: return "MVT::v1i64"; 9279283Smsmith case MVT::v2i64: return "MVT::v2i64"; 93119529Snjl case MVT::v4i64: return "MVT::v4i64"; 9479283Smsmith case MVT::v8i64: return "MVT::v8i64"; 9578915Smsmith case MVT::v16i64: return "MVT::v16i64"; 96119529Snjl case MVT::v2f16: return "MVT::v2f16"; 9788420Siwasaki case MVT::v2f32: return "MVT::v2f32"; 9867761Smsmith case MVT::v4f32: return "MVT::v4f32"; 9967761Smsmith case MVT::v8f32: return "MVT::v8f32"; 10067761Smsmith case MVT::v2f64: return "MVT::v2f64"; 10167761Smsmith case MVT::v4f64: return "MVT::v4f64"; 10278915Smsmith case MVT::Metadata: return "MVT::Metadata"; 103119529Snjl case MVT::iPTR: return "MVT::iPTR"; 10478915Smsmith case MVT::iPTRAny: return "MVT::iPTRAny"; 10578915Smsmith case MVT::Untyped: return "MVT::Untyped"; 10678915Smsmith default: llvm_unreachable("ILLEGAL VALUE TYPE!"); 107119529Snjl } 108119529Snjl} 10979283Smsmith 11079375Smsmith/// getQualifiedName - Return the name of the specified record, with a 111119529Snjl/// namespace qualifier if the record contains one. 112119529Snjl/// 11391126Smsmithstd::string llvm::getQualifiedName(const Record *R) { 11491640Siwasaki std::string Namespace; 11591126Smsmith if (R->getValue("Namespace")) 11691126Smsmith Namespace = R->getValueAsString("Namespace"); 11767761Smsmith if (Namespace.empty()) return R->getName(); 11867761Smsmith return Namespace + "::" + R->getName(); 11967761Smsmith} 12067761Smsmith 12167761Smsmith 12267761Smsmith/// getTarget - Return the current instance of the Target class. 12367761Smsmith/// 12467761SmsmithCodeGenTarget::CodeGenTarget(RecordKeeper &records) 12567761Smsmith : Records(records), RegBank(0), SchedModels(0) { 12667761Smsmith std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target"); 12767761Smsmith if (Targets.size() == 0) 12867761Smsmith PrintFatalError("ERROR: No 'Target' subclasses defined!"); 12967761Smsmith if (Targets.size() != 1) 13067761Smsmith PrintFatalError("ERROR: Multiple subclasses of Target defined!"); 13189054Smsmith TargetRec = Targets[0]; 13267761Smsmith} 13367761Smsmith 13479283SmsmithCodeGenTarget::~CodeGenTarget() { 13579283Smsmith delete RegBank; 13679283Smsmith delete SchedModels; 137119529Snjl} 138119529Snjl 13988420Siwasakiconst std::string &CodeGenTarget::getName() const { 14085699Siwasaki return TargetRec->getName(); 141119529Snjl} 142119529Snjl 143119529Snjlstd::string CodeGenTarget::getInstNamespace() const { 14478915Smsmith for (inst_iterator i = inst_begin(), e = inst_end(); i != e; ++i) { 14578915Smsmith // Make sure not to pick up "TargetOpcode" by accidentally getting 14678915Smsmith // the namespace off the PHI instruction or something. 14767761Smsmith if ((*i)->Namespace != "TargetOpcode") 14867761Smsmith return (*i)->Namespace; 14967761Smsmith } 15078999Smsmith 151105282Sjhb return ""; 15278999Smsmith} 15378999Smsmith 15478999SmsmithRecord *CodeGenTarget::getInstructionSet() const { 155119529Snjl return TargetRec->getValueAsDef("InstructionSet"); 15669744Smsmith} 157119529Snjl 158120453Snjl 15978999Smsmith/// getAsmParser - Return the AssemblyParser definition for this target. 16078999Smsmith/// 16178999SmsmithRecord *CodeGenTarget::getAsmParser() const { 16267761Smsmith std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers"); 16378999Smsmith if (AsmParserNum >= LI.size()) 164119529Snjl PrintFatalError("Target does not have an AsmParser #" + utostr(AsmParserNum) + "!"); 16567761Smsmith return LI[AsmParserNum]; 16667761Smsmith} 16778915Smsmith 16878915Smsmith/// getAsmParserVariant - Return the AssmblyParserVariant definition for 16978915Smsmith/// this target. 17067761Smsmith/// 17167761SmsmithRecord *CodeGenTarget::getAsmParserVariant(unsigned i) const { 17267761Smsmith std::vector<Record*> LI = 17367761Smsmith TargetRec->getValueAsListOfDefs("AssemblyParserVariants"); 17479283Smsmith if (i >= LI.size()) 17578915Smsmith PrintFatalError("Target does not have an AsmParserVariant #" + utostr(i) + "!"); 17679283Smsmith return LI[i]; 177105282Sjhb} 17867761Smsmith 17996926Speter/// getAsmParserVariantCount - Return the AssmblyParserVariant definition 18069744Smsmith/// available for this target. 18178999Smsmith/// 18278999Smsmithunsigned CodeGenTarget::getAsmParserVariantCount() const { 18367761Smsmith std::vector<Record*> LI = 18467761Smsmith TargetRec->getValueAsListOfDefs("AssemblyParserVariants"); 18567761Smsmith return LI.size(); 18679375Smsmith} 18788420Siwasaki 18867761Smsmith/// getAsmWriter - Return the AssemblyWriter definition for this target. 18978915Smsmith/// 19078915SmsmithRecord *CodeGenTarget::getAsmWriter() const { 19178915Smsmith std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters"); 19278915Smsmith if (AsmWriterNum >= LI.size()) 19378915Smsmith PrintFatalError("Target does not have an AsmWriter #" + utostr(AsmWriterNum) + "!"); 19478999Smsmith return LI[AsmWriterNum]; 19578915Smsmith} 19678915Smsmith 19778915SmsmithCodeGenRegBank &CodeGenTarget::getRegBank() const { 19878915Smsmith if (!RegBank) 19971874Smsmith RegBank = new CodeGenRegBank(Records); 20078999Smsmith return *RegBank; 20170271Stakawata} 20271874Smsmith 20379283Smsmithvoid CodeGenTarget::ReadRegAltNameIndices() const { 20479283Smsmith RegAltNameIndices = Records.getAllDerivedDefinitions("RegAltNameIndex"); 20579283Smsmith std::sort(RegAltNameIndices.begin(), RegAltNameIndices.end(), LessRecord()); 20679283Smsmith} 20779283Smsmith 20879283Smsmith/// getRegisterByName - If there is a register with the specific AsmName, 20979283Smsmith/// return it. 21079283Smsmithconst CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const { 211119529Snjl const StringMap<CodeGenRegister*> &Regs = getRegBank().getRegistersByName(); 212119529Snjl StringMap<CodeGenRegister*>::const_iterator I = Regs.find(Name); 21385699Siwasaki if (I == Regs.end()) 21485699Siwasaki return 0; 21585699Siwasaki return I->second; 216119529Snjl} 217119529Snjl 21888420Siwasakistd::vector<MVT::SimpleValueType> CodeGenTarget:: 21988420SiwasakigetRegisterVTs(Record *R) const { 22088420Siwasaki const CodeGenRegister *Reg = getRegBank().getReg(R); 22188420Siwasaki std::vector<MVT::SimpleValueType> Result; 22279283Smsmith ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses(); 22379283Smsmith for (unsigned i = 0, e = RCs.size(); i != e; ++i) { 22479283Smsmith const CodeGenRegisterClass &RC = *RCs[i]; 22579283Smsmith if (RC.contains(Reg)) { 226119529Snjl const std::vector<MVT::SimpleValueType> &InVTs = RC.getValueTypes(); 227119529Snjl Result.insert(Result.end(), InVTs.begin(), InVTs.end()); 22879283Smsmith } 22979283Smsmith } 23079283Smsmith 23179375Smsmith // Remove duplicates. 23279375Smsmith array_pod_sort(Result.begin(), Result.end()); 23379375Smsmith Result.erase(std::unique(Result.begin(), Result.end()), Result.end()); 23479375Smsmith return Result; 23579283Smsmith} 23679375Smsmith 23779375Smsmith 23879283Smsmithvoid CodeGenTarget::ReadLegalValueTypes() const { 23979283Smsmith ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses(); 24079375Smsmith for (unsigned i = 0, e = RCs.size(); i != e; ++i) 24179283Smsmith for (unsigned ri = 0, re = RCs[i]->VTs.size(); ri != re; ++ri) 24279283Smsmith LegalValueTypes.push_back(RCs[i]->VTs[ri]); 24379375Smsmith 24479283Smsmith // Remove duplicates. 24579283Smsmith std::sort(LegalValueTypes.begin(), LegalValueTypes.end()); 24679375Smsmith LegalValueTypes.erase(std::unique(LegalValueTypes.begin(), 24786399Siwasaki LegalValueTypes.end()), 24886399Siwasaki LegalValueTypes.end()); 24986399Siwasaki} 25079283Smsmith 25179283SmsmithCodeGenSchedModels &CodeGenTarget::getSchedModels() const { 25279375Smsmith if (!SchedModels) 25379375Smsmith SchedModels = new CodeGenSchedModels(Records, *this); 25479375Smsmith return *SchedModels; 25579375Smsmith} 25691640Siwasaki 25779375Smsmithvoid CodeGenTarget::ReadInstructions() const { 25879375Smsmith std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 25979375Smsmith if (Insts.size() <= 2) 26071874Smsmith PrintFatalError("No 'Instruction' subclasses defined!"); 26171874Smsmith 26271874Smsmith // Parse the instructions defined in the .td file. 26378999Smsmith for (unsigned i = 0, e = Insts.size(); i != e; ++i) 26491126Smsmith Instructions[Insts[i]] = new CodeGenInstruction(Insts[i]); 26591126Smsmith} 26691126Smsmith 26791126Smsmithstatic const CodeGenInstruction * 26891126SmsmithGetInstByName(const char *Name, 26991126Smsmith const DenseMap<const Record*, CodeGenInstruction*> &Insts, 270104354Sscottl RecordKeeper &Records) { 27191126Smsmith const Record *Rec = Records.getDef(Name); 272119529Snjl 273119529Snjl DenseMap<const Record*, CodeGenInstruction*>::const_iterator 27491126Smsmith I = Insts.find(Rec); 27591126Smsmith if (Rec == 0 || I == Insts.end()) 27691126Smsmith PrintFatalError(std::string("Could not find '") + Name + "' instruction!"); 27791126Smsmith return I->second; 27878999Smsmith} 27978999Smsmith 28079375Smsmithnamespace { 281119529Snjl/// SortInstByName - Sorting predicate to sort instructions by name. 28267761Smsmith/// 28370271Stakawatastruct SortInstByName { 28478915Smsmith bool operator()(const CodeGenInstruction *Rec1, 28578915Smsmith const CodeGenInstruction *Rec2) const { 28678915Smsmith return Rec1->TheDef->getName() < Rec2->TheDef->getName(); 28778915Smsmith } 28878915Smsmith}; 28978915Smsmith} 29078915Smsmith 29178915Smsmith/// getInstructionsByEnumValue - Return all of the instructions defined by the 29278915Smsmith/// target, ordered by their enum value. 29378915Smsmithvoid CodeGenTarget::ComputeInstrsByEnum() const { 29478915Smsmith // The ordering here must match the ordering in TargetOpcodes.h. 29578915Smsmith const char *const FixedInstrs[] = { 29696926Speter "PHI", 29778915Smsmith "INLINEASM", 29878999Smsmith "PROLOG_LABEL", 29978999Smsmith "EH_LABEL", 300119529Snjl "GC_LABEL", 30178915Smsmith "KILL", 30278915Smsmith "EXTRACT_SUBREG", 30379375Smsmith "INSERT_SUBREG", 30479375Smsmith "IMPLICIT_DEF", 30579375Smsmith "SUBREG_TO_REG", 30679375Smsmith "COPY_TO_REGCLASS", 30779375Smsmith "DBG_VALUE", 30878915Smsmith "REG_SEQUENCE", 309119529Snjl "COPY", 31078915Smsmith "BUNDLE", 31178915Smsmith "LIFETIME_START", 31279375Smsmith "LIFETIME_END", 31378915Smsmith 0 31491126Smsmith }; 31591126Smsmith const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions(); 31691126Smsmith for (const char *const *p = FixedInstrs; *p; ++p) { 31779375Smsmith const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records); 31878915Smsmith assert(Instr && "Missing target independent instruction"); 319119529Snjl assert(Instr->Namespace == "TargetOpcode" && "Bad namespace"); 32078915Smsmith InstrsByEnum.push_back(Instr); 321119529Snjl } 32278915Smsmith unsigned EndOfPredefines = InstrsByEnum.size(); 323119529Snjl 32478915Smsmith for (DenseMap<const Record*, CodeGenInstruction*>::const_iterator 32578915Smsmith I = Insts.begin(), E = Insts.end(); I != E; ++I) { 32678915Smsmith const CodeGenInstruction *CGI = I->second; 32779375Smsmith if (CGI->Namespace != "TargetOpcode") 32879375Smsmith InstrsByEnum.push_back(CGI); 32991126Smsmith } 33091126Smsmith 33191126Smsmith assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr"); 33279375Smsmith 33379375Smsmith // All of the instructions are now in random order based on the map iteration. 33479375Smsmith // Sort them by name. 33579375Smsmith std::sort(InstrsByEnum.begin()+EndOfPredefines, InstrsByEnum.end(), 33679375Smsmith SortInstByName()); 33778915Smsmith} 33878915Smsmith 33979283Smsmith 34079283Smsmith/// isLittleEndianEncoding - Return whether this target encodes its instruction 34179283Smsmith/// in little-endian format, i.e. bits laid out in the order [0..n] 34279283Smsmith/// 34379283Smsmithbool CodeGenTarget::isLittleEndianEncoding() const { 34479375Smsmith return getInstructionSet()->getValueAsBit("isLittleEndianEncoding"); 34579375Smsmith} 34679375Smsmith 34779283Smsmith/// guessInstructionProperties - Return true if it's OK to guess instruction 34879375Smsmith/// properties instead of raising an error. 34979283Smsmith/// 35079283Smsmith/// This is configurable as a temporary migration aid. It will eventually be 35178915Smsmith/// permanently false. 35278915Smsmithbool CodeGenTarget::guessInstructionProperties() const { 35378915Smsmith return getInstructionSet()->getValueAsBit("guessInstructionProperties"); 35478915Smsmith} 355119529Snjl 35678915Smsmith//===----------------------------------------------------------------------===// 35778915Smsmith// ComplexPattern implementation 35885699Siwasaki// 35985699SiwasakiComplexPattern::ComplexPattern(Record *R) { 36085699Siwasaki Ty = ::getValueType(R->getValueAsDef("Ty")); 36185699Siwasaki NumOperands = R->getValueAsInt("NumOperands"); 36285699Siwasaki SelectFunc = R->getValueAsString("SelectFunc"); 36385699Siwasaki RootNodes = R->getValueAsListOfDefs("RootNodes"); 36485699Siwasaki 365119529Snjl // Parse the properties. 36685699Siwasaki Properties = 0; 36785699Siwasaki std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties"); 36885699Siwasaki for (unsigned i = 0, e = PropList.size(); i != e; ++i) 36985699Siwasaki if (PropList[i]->getName() == "SDNPHasChain") { 37085699Siwasaki Properties |= 1 << SDNPHasChain; 37178915Smsmith } else if (PropList[i]->getName() == "SDNPOptInGlue") { 37278915Smsmith Properties |= 1 << SDNPOptInGlue; 37378915Smsmith } else if (PropList[i]->getName() == "SDNPMayStore") { 37471874Smsmith Properties |= 1 << SDNPMayStore; 375119529Snjl } else if (PropList[i]->getName() == "SDNPMayLoad") { 37671874Smsmith Properties |= 1 << SDNPMayLoad; 377119529Snjl } else if (PropList[i]->getName() == "SDNPSideEffect") { 378119529Snjl Properties |= 1 << SDNPSideEffect; 37979283Smsmith } else if (PropList[i]->getName() == "SDNPMemOperand") { 38078915Smsmith Properties |= 1 << SDNPMemOperand; 38179283Smsmith } else if (PropList[i]->getName() == "SDNPVariadic") { 38286399Siwasaki Properties |= 1 << SDNPVariadic; 38370271Stakawata } else if (PropList[i]->getName() == "SDNPWantRoot") { 38496926Speter Properties |= 1 << SDNPWantRoot; 38570271Stakawata } else if (PropList[i]->getName() == "SDNPWantParent") { 38678999Smsmith Properties |= 1 << SDNPWantParent; 38778999Smsmith } else { 388119529Snjl errs() << "Unsupported SD Node property '" << PropList[i]->getName() 389119529Snjl << "' on ComplexPattern '" << R->getName() << "'!\n"; 39088420Siwasaki exit(1); 39188420Siwasaki } 39288420Siwasaki} 393119529Snjl 394119529Snjl//===----------------------------------------------------------------------===// 395119529Snjl// CodeGenIntrinsic Implementation 39686552Siwasaki//===----------------------------------------------------------------------===// 39786552Siwasaki 39886552Siwasakistd::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC, 39978915Smsmith bool TargetOnly) { 40088420Siwasaki std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic"); 40171874Smsmith 40288420Siwasaki std::vector<CodeGenIntrinsic> Result; 40382372Smsmith 40479283Smsmith for (unsigned i = 0, e = I.size(); i != e; ++i) { 40578915Smsmith bool isTarget = I[i]->getValueAsBit("isTarget"); 40678915Smsmith if (isTarget == TargetOnly) 40778915Smsmith Result.push_back(CodeGenIntrinsic(I[i])); 40879283Smsmith } 40979283Smsmith return Result; 41078915Smsmith} 41179283Smsmith 41279375SmsmithCodeGenIntrinsic::CodeGenIntrinsic(Record *R) { 41379375Smsmith TheDef = R; 41479283Smsmith std::string DefName = R->getName(); 41582967Siwasaki ModRef = ReadWriteMem; 416119529Snjl isOverloaded = false; 417119529Snjl isCommutative = false; 418119529Snjl canThrow = false; 419119529Snjl isNoReturn = false; 42085699Siwasaki 42182967Siwasaki if (DefName.size() <= 4 || 42279375Smsmith std::string(DefName.begin(), DefName.begin() + 4) != "int_") 42379375Smsmith PrintFatalError("Intrinsic '" + DefName + "' does not start with 'int_'!"); 42479283Smsmith 42585699Siwasaki EnumName = std::string(DefName.begin()+4, DefName.end()); 42685699Siwasaki 42785699Siwasaki if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field. 42885699Siwasaki GCCBuiltinName = R->getValueAsString("GCCBuiltinName"); 42985699Siwasaki 43085699Siwasaki TargetPrefix = R->getValueAsString("TargetPrefix"); 431119529Snjl Name = R->getValueAsString("LLVMName"); 43285699Siwasaki 43385699Siwasaki if (Name == "") { 434119529Snjl // If an explicit name isn't specified, derive one from the DefName. 43585699Siwasaki Name = "llvm."; 43685699Siwasaki 43785699Siwasaki for (unsigned i = 0, e = EnumName.size(); i != e; ++i) 438119529Snjl Name += (EnumName[i] == '_') ? '.' : EnumName[i]; 43979375Smsmith } else { 44079375Smsmith // Verify it starts with "llvm.". 44178915Smsmith if (Name.size() <= 5 || 44279375Smsmith std::string(Name.begin(), Name.begin() + 5) != "llvm.") 44379375Smsmith PrintFatalError("Intrinsic '" + DefName + "'s name does not start with 'llvm.'!"); 44479375Smsmith } 44579375Smsmith 44679375Smsmith // If TargetPrefix is specified, make sure that Name starts with 44779375Smsmith // "llvm.<targetprefix>.". 44879375Smsmith if (!TargetPrefix.empty()) { 44979375Smsmith if (Name.size() < 6+TargetPrefix.size() || 45079375Smsmith std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size()) 451119529Snjl != (TargetPrefix + ".")) 45279283Smsmith PrintFatalError("Intrinsic '" + DefName + "' does not start with 'llvm." + 453119529Snjl TargetPrefix + ".'!"); 45479283Smsmith } 455119529Snjl 456119529Snjl // Parse the list of return types. 457119529Snjl std::vector<MVT::SimpleValueType> OverloadedVTs; 45878915Smsmith ListInit *TypeList = R->getValueAsListInit("RetTypes"); 459119529Snjl for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) { 460119529Snjl Record *TyEl = TypeList->getElementAsRecord(i); 461119529Snjl assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!"); 462119529Snjl MVT::SimpleValueType VT; 463119529Snjl if (TyEl->isSubClassOf("LLVMMatchType")) { 464119529Snjl unsigned MatchTy = TyEl->getValueAsInt("Number"); 46586552Siwasaki assert(MatchTy < OverloadedVTs.size() && 466119529Snjl "Invalid matching number!"); 467119529Snjl VT = OverloadedVTs[MatchTy]; 468119529Snjl // It only makes sense to use the extended and truncated vector element 46979283Smsmith // variants with iAny types; otherwise, if the intrinsic is not 47079283Smsmith // overloaded, all the types can be specified directly. 47178915Smsmith assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") && 472119529Snjl !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) || 47378915Smsmith VT == MVT::iAny || VT == MVT::vAny) && 47478915Smsmith "Expected iAny or vAny type"); 47579283Smsmith } else { 47679283Smsmith VT = getValueType(TyEl->getValueAsDef("VT")); 47779283Smsmith } 47879283Smsmith if (EVT(VT).isOverloaded()) { 47978915Smsmith OverloadedVTs.push_back(VT); 480119529Snjl isOverloaded = true; 481119529Snjl } 482119529Snjl 483119529Snjl // Reject invalid types. 484119529Snjl if (VT == MVT::isVoid) 48597274Sbde PrintFatalError("Intrinsic '" + DefName + " has void in result type list!"); 48679283Smsmith 48778915Smsmith IS.RetVTs.push_back(VT); 48879375Smsmith IS.RetTypeDefs.push_back(TyEl); 48978915Smsmith } 49088420Siwasaki 49188420Siwasaki // Parse the list of parameter types. 49271874Smsmith TypeList = R->getValueAsListInit("ParamTypes"); 49371874Smsmith for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) { 49470271Stakawata Record *TyEl = TypeList->getElementAsRecord(i); 49578915Smsmith assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!"); 49678915Smsmith MVT::SimpleValueType VT; 49778915Smsmith if (TyEl->isSubClassOf("LLVMMatchType")) { 49871874Smsmith unsigned MatchTy = TyEl->getValueAsInt("Number"); 49978915Smsmith assert(MatchTy < OverloadedVTs.size() && 50078915Smsmith "Invalid matching number!"); 50178915Smsmith VT = OverloadedVTs[MatchTy]; 50278915Smsmith // It only makes sense to use the extended and truncated vector element 50396926Speter // variants with iAny types; otherwise, if the intrinsic is not 50478999Smsmith // overloaded, all the types can be specified directly. 50578999Smsmith assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") && 50678915Smsmith !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) || 507119529Snjl VT == MVT::iAny || VT == MVT::vAny) && 50878915Smsmith "Expected iAny or vAny type"); 50979375Smsmith } else 51078915Smsmith VT = getValueType(TyEl->getValueAsDef("VT")); 51179375Smsmith 51278915Smsmith if (EVT(VT).isOverloaded()) { 51378915Smsmith OverloadedVTs.push_back(VT); 51478915Smsmith isOverloaded = true; 51578915Smsmith } 51678915Smsmith 51778915Smsmith // Reject invalid types. 51878915Smsmith if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/) 51979283Smsmith PrintFatalError("Intrinsic '" + DefName + " has void in result type list!"); 52079375Smsmith 521119529Snjl IS.ParamVTs.push_back(VT); 52278915Smsmith IS.ParamTypeDefs.push_back(TyEl); 52378915Smsmith } 52478915Smsmith 52578915Smsmith // Parse the intrinsic properties. 52678915Smsmith ListInit *PropList = R->getValueAsListInit("Properties"); 52778915Smsmith for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) { 52878915Smsmith Record *Property = PropList->getElementAsRecord(i); 52978915Smsmith assert(Property->isSubClassOf("IntrinsicProperty") && 53078915Smsmith "Expected a property!"); 53178915Smsmith 53279375Smsmith if (Property->getName() == "IntrNoMem") 53378915Smsmith ModRef = NoMem; 53496926Speter else if (Property->getName() == "IntrReadArgMem") 53578915Smsmith ModRef = ReadArgMem; 53678999Smsmith else if (Property->getName() == "IntrReadMem") 53778999Smsmith ModRef = ReadMem; 53878915Smsmith else if (Property->getName() == "IntrReadWriteArgMem") 539102470Siwasaki ModRef = ReadWriteArgMem; 540119529Snjl else if (Property->getName() == "Commutative") 541119529Snjl isCommutative = true; 542102470Siwasaki else if (Property->getName() == "Throws") 543102470Siwasaki canThrow = true; 544102470Siwasaki else if (Property->getName() == "IntrNoReturn") 54578915Smsmith isNoReturn = true; 546119529Snjl else if (Property->isSubClassOf("NoCapture")) { 547119529Snjl unsigned ArgNo = Property->getValueAsInt("ArgNo"); 54878915Smsmith ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture)); 54978915Smsmith } else 55078915Smsmith llvm_unreachable("Unknown property!"); 55178915Smsmith } 55278915Smsmith 55378915Smsmith // Sort the argument attributes for later benefit. 55478915Smsmith std::sort(ArgumentAttributes.begin(), ArgumentAttributes.end()); 55578915Smsmith} 55691126Smsmith