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