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