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