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