1 //===--- Triple.cpp - Target triple helper class --------------------------===// 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 #include "llvm/ADT/Triple.h" 11 #include "llvm/ADT/SmallString.h" 12 #include "llvm/ADT/StringSwitch.h" 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/Support/ErrorHandling.h" 15 #include <cstring> 16 using namespace llvm; 17 18 const char *Triple::getArchTypeName(ArchType Kind) { 19 switch (Kind) { 20 case UnknownArch: return "unknown"; 21 22 case arm: return "arm"; 23 case cellspu: return "cellspu"; 24 case hexagon: return "hexagon"; 25 case mips: return "mips"; 26 case mipsel: return "mipsel"; 27 case mips64: return "mips64"; 28 case mips64el:return "mips64el"; 29 case msp430: return "msp430"; 30 case ppc64: return "powerpc64"; 31 case ppc: return "powerpc"; 32 case r600: return "r600"; 33 case sparc: return "sparc"; 34 case sparcv9: return "sparcv9"; 35 case tce: return "tce"; 36 case thumb: return "thumb"; 37 case x86: return "i386"; 38 case x86_64: return "x86_64"; 39 case xcore: return "xcore"; 40 case mblaze: return "mblaze"; 41 case nvptx: return "nvptx"; 42 case nvptx64: return "nvptx64"; 43 case le32: return "le32"; 44 case amdil: return "amdil"; 45 case spir: return "spir"; 46 } 47 48 llvm_unreachable("Invalid ArchType!"); 49 } 50 51 const char *Triple::getArchTypePrefix(ArchType Kind) { 52 switch (Kind) { 53 default: 54 return 0; 55 56 case arm: 57 case thumb: return "arm"; 58 59 case cellspu: return "spu"; 60 61 case ppc64: 62 case ppc: return "ppc"; 63 64 case mblaze: return "mblaze"; 65 66 case mips: 67 case mipsel: 68 case mips64: 69 case mips64el:return "mips"; 70 71 case hexagon: return "hexagon"; 72 73 case r600: return "r600"; 74 75 case sparcv9: 76 case sparc: return "sparc"; 77 78 case x86: 79 case x86_64: return "x86"; 80 81 case xcore: return "xcore"; 82 83 case nvptx: return "nvptx"; 84 case nvptx64: return "nvptx"; 85 case le32: return "le32"; 86 case amdil: return "amdil"; 87 case spir: return "spir"; 88 } 89 } 90 91 const char *Triple::getVendorTypeName(VendorType Kind) { 92 switch (Kind) { 93 case UnknownVendor: return "unknown"; 94 95 case Apple: return "apple"; 96 case PC: return "pc"; 97 case SCEI: return "scei"; 98 case BGP: return "bgp"; 99 case BGQ: return "bgq"; 100 case Freescale: return "fsl"; 101 case IBM: return "ibm"; 102 } 103 104 llvm_unreachable("Invalid VendorType!"); 105 } 106 107 const char *Triple::getOSTypeName(OSType Kind) { 108 switch (Kind) { 109 case UnknownOS: return "unknown"; 110 111 case AuroraUX: return "auroraux"; 112 case Cygwin: return "cygwin"; 113 case Darwin: return "darwin"; 114 case DragonFly: return "dragonfly"; 115 case FreeBSD: return "freebsd"; 116 case IOS: return "ios"; 117 case KFreeBSD: return "kfreebsd"; 118 case Linux: return "linux"; 119 case Lv2: return "lv2"; 120 case MacOSX: return "macosx"; 121 case MinGW32: return "mingw32"; 122 case NetBSD: return "netbsd"; 123 case OpenBSD: return "openbsd"; 124 case Solaris: return "solaris"; 125 case Win32: return "win32"; 126 case Haiku: return "haiku"; 127 case Minix: return "minix"; 128 case RTEMS: return "rtems"; 129 case NativeClient: return "nacl"; 130 case CNK: return "cnk"; 131 case Bitrig: return "bitrig"; 132 case AIX: return "aix"; 133 } 134 135 llvm_unreachable("Invalid OSType"); 136 } 137 138 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { 139 switch (Kind) { 140 case UnknownEnvironment: return "unknown"; 141 case GNU: return "gnu"; 142 case GNUEABIHF: return "gnueabihf"; 143 case GNUEABI: return "gnueabi"; 144 case EABI: return "eabi"; 145 case MachO: return "macho"; 146 case Android: return "android"; 147 case ELF: return "elf"; 148 } 149 150 llvm_unreachable("Invalid EnvironmentType!"); 151 } 152 153 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 154 return StringSwitch<Triple::ArchType>(Name) 155 .Case("arm", arm) 156 .Case("cellspu", cellspu) 157 .Case("mips", mips) 158 .Case("mipsel", mipsel) 159 .Case("mips64", mips64) 160 .Case("mips64el", mips64el) 161 .Case("msp430", msp430) 162 .Case("ppc64", ppc64) 163 .Case("ppc32", ppc) 164 .Case("ppc", ppc) 165 .Case("mblaze", mblaze) 166 .Case("r600", r600) 167 .Case("hexagon", hexagon) 168 .Case("sparc", sparc) 169 .Case("sparcv9", sparcv9) 170 .Case("tce", tce) 171 .Case("thumb", thumb) 172 .Case("x86", x86) 173 .Case("x86-64", x86_64) 174 .Case("xcore", xcore) 175 .Case("nvptx", nvptx) 176 .Case("nvptx64", nvptx64) 177 .Case("le32", le32) 178 .Case("amdil", amdil) 179 .Case("spir", spir) 180 .Default(UnknownArch); 181 } 182 183 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) { 184 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for 185 // archs which Darwin doesn't use. 186 187 // The matching this routine does is fairly pointless, since it is neither the 188 // complete architecture list, nor a reasonable subset. The problem is that 189 // historically the driver driver accepts this and also ties its -march= 190 // handling to the architecture name, so we need to be careful before removing 191 // support for it. 192 193 // This code must be kept in sync with Clang's Darwin specific argument 194 // translation. 195 196 return StringSwitch<ArchType>(Str) 197 .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", Triple::ppc) 198 .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", Triple::ppc) 199 .Case("ppc64", Triple::ppc64) 200 .Cases("i386", "i486", "i486SX", "i586", "i686", Triple::x86) 201 .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4", 202 Triple::x86) 203 .Case("x86_64", Triple::x86_64) 204 // This is derived from the driver driver. 205 .Cases("arm", "armv4t", "armv5", "armv6", Triple::arm) 206 .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", Triple::arm) 207 .Case("r600", Triple::r600) 208 .Case("nvptx", Triple::nvptx) 209 .Case("nvptx64", Triple::nvptx64) 210 .Case("amdil", Triple::amdil) 211 .Case("spir", Triple::spir) 212 .Default(Triple::UnknownArch); 213 } 214 215 // Returns architecture name that is understood by the target assembler. 216 const char *Triple::getArchNameForAssembler() { 217 if (!isOSDarwin() && getVendor() != Triple::Apple) 218 return NULL; 219 220 return StringSwitch<const char*>(getArchName()) 221 .Case("i386", "i386") 222 .Case("x86_64", "x86_64") 223 .Case("powerpc", "ppc") 224 .Case("powerpc64", "ppc64") 225 .Cases("mblaze", "microblaze", "mblaze") 226 .Case("arm", "arm") 227 .Cases("armv4t", "thumbv4t", "armv4t") 228 .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5") 229 .Cases("armv6", "thumbv6", "armv6") 230 .Cases("armv7", "thumbv7", "armv7") 231 .Case("r600", "r600") 232 .Case("nvptx", "nvptx") 233 .Case("nvptx64", "nvptx64") 234 .Case("le32", "le32") 235 .Case("amdil", "amdil") 236 .Case("spir", "spir") 237 .Default(NULL); 238 } 239 240 static Triple::ArchType parseArch(StringRef ArchName) { 241 return StringSwitch<Triple::ArchType>(ArchName) 242 .Cases("i386", "i486", "i586", "i686", Triple::x86) 243 // FIXME: Do we need to support these? 244 .Cases("i786", "i886", "i986", Triple::x86) 245 .Cases("amd64", "x86_64", Triple::x86_64) 246 .Case("powerpc", Triple::ppc) 247 .Cases("powerpc64", "ppu", Triple::ppc64) 248 .Case("mblaze", Triple::mblaze) 249 .Cases("arm", "xscale", Triple::arm) 250 // FIXME: It would be good to replace these with explicit names for all the 251 // various suffixes supported. 252 .StartsWith("armv", Triple::arm) 253 .Case("thumb", Triple::thumb) 254 .StartsWith("thumbv", Triple::thumb) 255 .Cases("spu", "cellspu", Triple::cellspu) 256 .Case("msp430", Triple::msp430) 257 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) 258 .Cases("mipsel", "mipsallegrexel", Triple::mipsel) 259 .Cases("mips64", "mips64eb", Triple::mips64) 260 .Case("mips64el", Triple::mips64el) 261 .Case("r600", Triple::r600) 262 .Case("hexagon", Triple::hexagon) 263 .Case("sparc", Triple::sparc) 264 .Case("sparcv9", Triple::sparcv9) 265 .Case("tce", Triple::tce) 266 .Case("xcore", Triple::xcore) 267 .Case("nvptx", Triple::nvptx) 268 .Case("nvptx64", Triple::nvptx64) 269 .Case("le32", Triple::le32) 270 .Case("amdil", Triple::amdil) 271 .Case("spir", Triple::spir) 272 .Default(Triple::UnknownArch); 273 } 274 275 static Triple::VendorType parseVendor(StringRef VendorName) { 276 return StringSwitch<Triple::VendorType>(VendorName) 277 .Case("apple", Triple::Apple) 278 .Case("pc", Triple::PC) 279 .Case("scei", Triple::SCEI) 280 .Case("bgp", Triple::BGP) 281 .Case("bgq", Triple::BGQ) 282 .Case("fsl", Triple::Freescale) 283 .Case("ibm", Triple::IBM) 284 .Default(Triple::UnknownVendor); 285 } 286 287 static Triple::OSType parseOS(StringRef OSName) { 288 return StringSwitch<Triple::OSType>(OSName) 289 .StartsWith("auroraux", Triple::AuroraUX) 290 .StartsWith("cygwin", Triple::Cygwin) 291 .StartsWith("darwin", Triple::Darwin) 292 .StartsWith("dragonfly", Triple::DragonFly) 293 .StartsWith("freebsd", Triple::FreeBSD) 294 .StartsWith("ios", Triple::IOS) 295 .StartsWith("kfreebsd", Triple::KFreeBSD) 296 .StartsWith("linux", Triple::Linux) 297 .StartsWith("lv2", Triple::Lv2) 298 .StartsWith("macosx", Triple::MacOSX) 299 .StartsWith("mingw32", Triple::MinGW32) 300 .StartsWith("netbsd", Triple::NetBSD) 301 .StartsWith("openbsd", Triple::OpenBSD) 302 .StartsWith("solaris", Triple::Solaris) 303 .StartsWith("win32", Triple::Win32) 304 .StartsWith("haiku", Triple::Haiku) 305 .StartsWith("minix", Triple::Minix) 306 .StartsWith("rtems", Triple::RTEMS) 307 .StartsWith("nacl", Triple::NativeClient) 308 .StartsWith("cnk", Triple::CNK) 309 .StartsWith("bitrig", Triple::Bitrig) 310 .StartsWith("aix", Triple::AIX) 311 .Default(Triple::UnknownOS); 312 } 313 314 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { 315 return StringSwitch<Triple::EnvironmentType>(EnvironmentName) 316 .StartsWith("eabi", Triple::EABI) 317 .StartsWith("gnueabihf", Triple::GNUEABIHF) 318 .StartsWith("gnueabi", Triple::GNUEABI) 319 .StartsWith("gnu", Triple::GNU) 320 .StartsWith("macho", Triple::MachO) 321 .StartsWith("android", Triple::Android) 322 .StartsWith("elf", Triple::ELF) 323 .Default(Triple::UnknownEnvironment); 324 } 325 326 /// \brief Construct a triple from the string representation provided. 327 /// 328 /// This stores the string representation and parses the various pieces into 329 /// enum members. 330 Triple::Triple(const Twine &Str) 331 : Data(Str.str()), 332 Arch(parseArch(getArchName())), 333 Vendor(parseVendor(getVendorName())), 334 OS(parseOS(getOSName())), 335 Environment(parseEnvironment(getEnvironmentName())) { 336 } 337 338 /// \brief Construct a triple from string representations of the architecture, 339 /// vendor, and OS. 340 /// 341 /// This joins each argument into a canonical string representation and parses 342 /// them into enum members. It leaves the environment unknown and omits it from 343 /// the string representation. 344 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr) 345 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()), 346 Arch(parseArch(ArchStr.str())), 347 Vendor(parseVendor(VendorStr.str())), 348 OS(parseOS(OSStr.str())), 349 Environment() { 350 } 351 352 /// \brief Construct a triple from string representations of the architecture, 353 /// vendor, OS, and environment. 354 /// 355 /// This joins each argument into a canonical string representation and parses 356 /// them into enum members. 357 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, 358 const Twine &EnvironmentStr) 359 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') + 360 EnvironmentStr).str()), 361 Arch(parseArch(ArchStr.str())), 362 Vendor(parseVendor(VendorStr.str())), 363 OS(parseOS(OSStr.str())), 364 Environment(parseEnvironment(EnvironmentStr.str())) { 365 } 366 367 std::string Triple::normalize(StringRef Str) { 368 // Parse into components. 369 SmallVector<StringRef, 4> Components; 370 Str.split(Components, "-"); 371 372 // If the first component corresponds to a known architecture, preferentially 373 // use it for the architecture. If the second component corresponds to a 374 // known vendor, preferentially use it for the vendor, etc. This avoids silly 375 // component movement when a component parses as (eg) both a valid arch and a 376 // valid os. 377 ArchType Arch = UnknownArch; 378 if (Components.size() > 0) 379 Arch = parseArch(Components[0]); 380 VendorType Vendor = UnknownVendor; 381 if (Components.size() > 1) 382 Vendor = parseVendor(Components[1]); 383 OSType OS = UnknownOS; 384 if (Components.size() > 2) 385 OS = parseOS(Components[2]); 386 EnvironmentType Environment = UnknownEnvironment; 387 if (Components.size() > 3) 388 Environment = parseEnvironment(Components[3]); 389 390 // Note which components are already in their final position. These will not 391 // be moved. 392 bool Found[4]; 393 Found[0] = Arch != UnknownArch; 394 Found[1] = Vendor != UnknownVendor; 395 Found[2] = OS != UnknownOS; 396 Found[3] = Environment != UnknownEnvironment; 397 398 // If they are not there already, permute the components into their canonical 399 // positions by seeing if they parse as a valid architecture, and if so moving 400 // the component to the architecture position etc. 401 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) { 402 if (Found[Pos]) 403 continue; // Already in the canonical position. 404 405 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) { 406 // Do not reparse any components that already matched. 407 if (Idx < array_lengthof(Found) && Found[Idx]) 408 continue; 409 410 // Does this component parse as valid for the target position? 411 bool Valid = false; 412 StringRef Comp = Components[Idx]; 413 switch (Pos) { 414 default: llvm_unreachable("unexpected component type!"); 415 case 0: 416 Arch = parseArch(Comp); 417 Valid = Arch != UnknownArch; 418 break; 419 case 1: 420 Vendor = parseVendor(Comp); 421 Valid = Vendor != UnknownVendor; 422 break; 423 case 2: 424 OS = parseOS(Comp); 425 Valid = OS != UnknownOS; 426 break; 427 case 3: 428 Environment = parseEnvironment(Comp); 429 Valid = Environment != UnknownEnvironment; 430 break; 431 } 432 if (!Valid) 433 continue; // Nope, try the next component. 434 435 // Move the component to the target position, pushing any non-fixed 436 // components that are in the way to the right. This tends to give 437 // good results in the common cases of a forgotten vendor component 438 // or a wrongly positioned environment. 439 if (Pos < Idx) { 440 // Insert left, pushing the existing components to the right. For 441 // example, a-b-i386 -> i386-a-b when moving i386 to the front. 442 StringRef CurrentComponent(""); // The empty component. 443 // Replace the component we are moving with an empty component. 444 std::swap(CurrentComponent, Components[Idx]); 445 // Insert the component being moved at Pos, displacing any existing 446 // components to the right. 447 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) { 448 // Skip over any fixed components. 449 while (i < array_lengthof(Found) && Found[i]) 450 ++i; 451 // Place the component at the new position, getting the component 452 // that was at this position - it will be moved right. 453 std::swap(CurrentComponent, Components[i]); 454 } 455 } else if (Pos > Idx) { 456 // Push right by inserting empty components until the component at Idx 457 // reaches the target position Pos. For example, pc-a -> -pc-a when 458 // moving pc to the second position. 459 do { 460 // Insert one empty component at Idx. 461 StringRef CurrentComponent(""); // The empty component. 462 for (unsigned i = Idx; i < Components.size();) { 463 // Place the component at the new position, getting the component 464 // that was at this position - it will be moved right. 465 std::swap(CurrentComponent, Components[i]); 466 // If it was placed on top of an empty component then we are done. 467 if (CurrentComponent.empty()) 468 break; 469 // Advance to the next component, skipping any fixed components. 470 while (++i < array_lengthof(Found) && Found[i]) 471 ; 472 } 473 // The last component was pushed off the end - append it. 474 if (!CurrentComponent.empty()) 475 Components.push_back(CurrentComponent); 476 477 // Advance Idx to the component's new position. 478 while (++Idx < array_lengthof(Found) && Found[Idx]) 479 ; 480 } while (Idx < Pos); // Add more until the final position is reached. 481 } 482 assert(Pos < Components.size() && Components[Pos] == Comp && 483 "Component moved wrong!"); 484 Found[Pos] = true; 485 break; 486 } 487 } 488 489 // Special case logic goes here. At this point Arch, Vendor and OS have the 490 // correct values for the computed components. 491 492 // Stick the corrected components back together to form the normalized string. 493 std::string Normalized; 494 for (unsigned i = 0, e = Components.size(); i != e; ++i) { 495 if (i) Normalized += '-'; 496 Normalized += Components[i]; 497 } 498 return Normalized; 499 } 500 501 StringRef Triple::getArchName() const { 502 return StringRef(Data).split('-').first; // Isolate first component 503 } 504 505 StringRef Triple::getVendorName() const { 506 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 507 return Tmp.split('-').first; // Isolate second component 508 } 509 510 StringRef Triple::getOSName() const { 511 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 512 Tmp = Tmp.split('-').second; // Strip second component 513 return Tmp.split('-').first; // Isolate third component 514 } 515 516 StringRef Triple::getEnvironmentName() const { 517 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 518 Tmp = Tmp.split('-').second; // Strip second component 519 return Tmp.split('-').second; // Strip third component 520 } 521 522 StringRef Triple::getOSAndEnvironmentName() const { 523 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 524 return Tmp.split('-').second; // Strip second component 525 } 526 527 static unsigned EatNumber(StringRef &Str) { 528 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 529 unsigned Result = 0; 530 531 do { 532 // Consume the leading digit. 533 Result = Result*10 + (Str[0] - '0'); 534 535 // Eat the digit. 536 Str = Str.substr(1); 537 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9'); 538 539 return Result; 540 } 541 542 void Triple::getOSVersion(unsigned &Major, unsigned &Minor, 543 unsigned &Micro) const { 544 StringRef OSName = getOSName(); 545 546 // Assume that the OS portion of the triple starts with the canonical name. 547 StringRef OSTypeName = getOSTypeName(getOS()); 548 if (OSName.startswith(OSTypeName)) 549 OSName = OSName.substr(OSTypeName.size()); 550 551 // Any unset version defaults to 0. 552 Major = Minor = Micro = 0; 553 554 // Parse up to three components. 555 unsigned *Components[3] = { &Major, &Minor, &Micro }; 556 for (unsigned i = 0; i != 3; ++i) { 557 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 558 break; 559 560 // Consume the leading number. 561 *Components[i] = EatNumber(OSName); 562 563 // Consume the separator, if present. 564 if (OSName.startswith(".")) 565 OSName = OSName.substr(1); 566 } 567 } 568 569 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor, 570 unsigned &Micro) const { 571 getOSVersion(Major, Minor, Micro); 572 573 switch (getOS()) { 574 default: llvm_unreachable("unexpected OS for Darwin triple"); 575 case Darwin: 576 // Default to darwin8, i.e., MacOSX 10.4. 577 if (Major == 0) 578 Major = 8; 579 // Darwin version numbers are skewed from OS X versions. 580 if (Major < 4) 581 return false; 582 Micro = 0; 583 Minor = Major - 4; 584 Major = 10; 585 break; 586 case MacOSX: 587 // Default to 10.4. 588 if (Major == 0) { 589 Major = 10; 590 Minor = 4; 591 } 592 if (Major != 10) 593 return false; 594 break; 595 case IOS: 596 // Ignore the version from the triple. This is only handled because the 597 // the clang driver combines OS X and IOS support into a common Darwin 598 // toolchain that wants to know the OS X version number even when targeting 599 // IOS. 600 Major = 10; 601 Minor = 4; 602 Micro = 0; 603 break; 604 } 605 return true; 606 } 607 608 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor, 609 unsigned &Micro) const { 610 switch (getOS()) { 611 default: llvm_unreachable("unexpected OS for Darwin triple"); 612 case Darwin: 613 case MacOSX: 614 // Ignore the version from the triple. This is only handled because the 615 // the clang driver combines OS X and IOS support into a common Darwin 616 // toolchain that wants to know the iOS version number even when targeting 617 // OS X. 618 Major = 3; 619 Minor = 0; 620 Micro = 0; 621 break; 622 case IOS: 623 getOSVersion(Major, Minor, Micro); 624 // Default to 3.0. 625 if (Major == 0) 626 Major = 3; 627 break; 628 } 629 } 630 631 void Triple::setTriple(const Twine &Str) { 632 *this = Triple(Str); 633 } 634 635 void Triple::setArch(ArchType Kind) { 636 setArchName(getArchTypeName(Kind)); 637 } 638 639 void Triple::setVendor(VendorType Kind) { 640 setVendorName(getVendorTypeName(Kind)); 641 } 642 643 void Triple::setOS(OSType Kind) { 644 setOSName(getOSTypeName(Kind)); 645 } 646 647 void Triple::setEnvironment(EnvironmentType Kind) { 648 setEnvironmentName(getEnvironmentTypeName(Kind)); 649 } 650 651 void Triple::setArchName(StringRef Str) { 652 // Work around a miscompilation bug for Twines in gcc 4.0.3. 653 SmallString<64> Triple; 654 Triple += Str; 655 Triple += "-"; 656 Triple += getVendorName(); 657 Triple += "-"; 658 Triple += getOSAndEnvironmentName(); 659 setTriple(Triple.str()); 660 } 661 662 void Triple::setVendorName(StringRef Str) { 663 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 664 } 665 666 void Triple::setOSName(StringRef Str) { 667 if (hasEnvironment()) 668 setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 669 "-" + getEnvironmentName()); 670 else 671 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 672 } 673 674 void Triple::setEnvironmentName(StringRef Str) { 675 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 676 "-" + Str); 677 } 678 679 void Triple::setOSAndEnvironmentName(StringRef Str) { 680 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 681 } 682 683 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { 684 switch (Arch) { 685 case llvm::Triple::spir: 686 case llvm::Triple::UnknownArch: 687 return 0; 688 689 case llvm::Triple::msp430: 690 return 16; 691 692 case llvm::Triple::amdil: 693 case llvm::Triple::arm: 694 case llvm::Triple::cellspu: 695 case llvm::Triple::hexagon: 696 case llvm::Triple::le32: 697 case llvm::Triple::mblaze: 698 case llvm::Triple::mips: 699 case llvm::Triple::mipsel: 700 case llvm::Triple::nvptx: 701 case llvm::Triple::ppc: 702 case llvm::Triple::r600: 703 case llvm::Triple::sparc: 704 case llvm::Triple::tce: 705 case llvm::Triple::thumb: 706 case llvm::Triple::x86: 707 case llvm::Triple::xcore: 708 return 32; 709 710 case llvm::Triple::mips64: 711 case llvm::Triple::mips64el: 712 case llvm::Triple::nvptx64: 713 case llvm::Triple::ppc64: 714 case llvm::Triple::sparcv9: 715 case llvm::Triple::x86_64: 716 return 64; 717 } 718 llvm_unreachable("Invalid architecture value"); 719 } 720 721 bool Triple::isArch64Bit() const { 722 return getArchPointerBitWidth(getArch()) == 64; 723 } 724 725 bool Triple::isArch32Bit() const { 726 return getArchPointerBitWidth(getArch()) == 32; 727 } 728 729 bool Triple::isArch16Bit() const { 730 return getArchPointerBitWidth(getArch()) == 16; 731 } 732 733 Triple Triple::get32BitArchVariant() const { 734 Triple T(*this); 735 switch (getArch()) { 736 case Triple::UnknownArch: 737 case Triple::msp430: 738 T.setArch(UnknownArch); 739 break; 740 741 case Triple::amdil: 742 case Triple::spir: 743 case Triple::arm: 744 case Triple::cellspu: 745 case Triple::hexagon: 746 case Triple::le32: 747 case Triple::mblaze: 748 case Triple::mips: 749 case Triple::mipsel: 750 case Triple::nvptx: 751 case Triple::ppc: 752 case Triple::r600: 753 case Triple::sparc: 754 case Triple::tce: 755 case Triple::thumb: 756 case Triple::x86: 757 case Triple::xcore: 758 // Already 32-bit. 759 break; 760 761 case Triple::mips64: T.setArch(Triple::mips); break; 762 case Triple::mips64el: T.setArch(Triple::mipsel); break; 763 case Triple::nvptx64: T.setArch(Triple::nvptx); break; 764 case Triple::ppc64: T.setArch(Triple::ppc); break; 765 case Triple::sparcv9: T.setArch(Triple::sparc); break; 766 case Triple::x86_64: T.setArch(Triple::x86); break; 767 } 768 return T; 769 } 770 771 Triple Triple::get64BitArchVariant() const { 772 Triple T(*this); 773 switch (getArch()) { 774 case Triple::UnknownArch: 775 case Triple::amdil: 776 case Triple::arm: 777 case Triple::cellspu: 778 case Triple::hexagon: 779 case Triple::le32: 780 case Triple::mblaze: 781 case Triple::msp430: 782 case Triple::r600: 783 case Triple::tce: 784 case Triple::thumb: 785 case Triple::xcore: 786 T.setArch(UnknownArch); 787 break; 788 789 case Triple::spir: 790 case Triple::mips64: 791 case Triple::mips64el: 792 case Triple::nvptx64: 793 case Triple::ppc64: 794 case Triple::sparcv9: 795 case Triple::x86_64: 796 // Already 64-bit. 797 break; 798 799 case Triple::mips: T.setArch(Triple::mips64); break; 800 case Triple::mipsel: T.setArch(Triple::mips64el); break; 801 case Triple::nvptx: T.setArch(Triple::nvptx64); break; 802 case Triple::ppc: T.setArch(Triple::ppc64); break; 803 case Triple::sparc: T.setArch(Triple::sparcv9); break; 804 case Triple::x86: T.setArch(Triple::x86_64); break; 805 } 806 return T; 807 } 808