1193323Sed//===--- Triple.cpp - Target triple helper class --------------------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed 10193323Sed#include "llvm/ADT/Triple.h" 11249423Sdim#include "llvm/ADT/STLExtras.h" 12198090Srdivacky#include "llvm/ADT/SmallString.h" 13234353Sdim#include "llvm/ADT/StringSwitch.h" 14234353Sdim#include "llvm/Support/ErrorHandling.h" 15193323Sed#include <cstring> 16193323Sedusing namespace llvm; 17193323Sed 18193323Sedconst char *Triple::getArchTypeName(ArchType Kind) { 19193323Sed switch (Kind) { 20193323Sed case UnknownArch: return "unknown"; 21218893Sdim 22249423Sdim case aarch64: return "aarch64"; 23198090Srdivacky case arm: return "arm"; 24234353Sdim case hexagon: return "hexagon"; 25198090Srdivacky case mips: return "mips"; 26198090Srdivacky case mipsel: return "mipsel"; 27226633Sdim case mips64: return "mips64"; 28226633Sdim case mips64el:return "mips64el"; 29198090Srdivacky case msp430: return "msp430"; 30198090Srdivacky case ppc64: return "powerpc64"; 31263508Sdim case ppc64le: return "powerpc64le"; 32198090Srdivacky case ppc: return "powerpc"; 33234353Sdim case r600: return "r600"; 34198090Srdivacky case sparc: return "sparc"; 35203954Srdivacky case sparcv9: return "sparcv9"; 36251662Sdim case systemz: return "s390x"; 37198090Srdivacky case tce: return "tce"; 38198090Srdivacky case thumb: return "thumb"; 39198090Srdivacky case x86: return "i386"; 40198090Srdivacky case x86_64: return "x86_64"; 41198090Srdivacky case xcore: return "xcore"; 42239462Sdim case nvptx: return "nvptx"; 43239462Sdim case nvptx64: return "nvptx64"; 44226633Sdim case le32: return "le32"; 45226633Sdim case amdil: return "amdil"; 46243830Sdim case spir: return "spir"; 47243830Sdim case spir64: return "spir64"; 48193323Sed } 49193323Sed 50234353Sdim llvm_unreachable("Invalid ArchType!"); 51193323Sed} 52193323Sed 53198090Srdivackyconst char *Triple::getArchTypePrefix(ArchType Kind) { 54198090Srdivacky switch (Kind) { 55198090Srdivacky default: 56198090Srdivacky return 0; 57198090Srdivacky 58249423Sdim case aarch64: return "aarch64"; 59249423Sdim 60198090Srdivacky case arm: 61198090Srdivacky case thumb: return "arm"; 62198090Srdivacky 63198090Srdivacky case ppc64: 64263508Sdim case ppc64le: 65198090Srdivacky case ppc: return "ppc"; 66198090Srdivacky 67239462Sdim case mips: 68239462Sdim case mipsel: 69239462Sdim case mips64: 70239462Sdim case mips64el:return "mips"; 71234353Sdim 72239462Sdim case hexagon: return "hexagon"; 73239462Sdim 74234353Sdim case r600: return "r600"; 75234353Sdim 76203954Srdivacky case sparcv9: 77198090Srdivacky case sparc: return "sparc"; 78198090Srdivacky 79251662Sdim case systemz: return "systemz"; 80251662Sdim 81198090Srdivacky case x86: 82198090Srdivacky case x86_64: return "x86"; 83218893Sdim 84198090Srdivacky case xcore: return "xcore"; 85218893Sdim 86239462Sdim case nvptx: return "nvptx"; 87239462Sdim case nvptx64: return "nvptx"; 88226633Sdim case le32: return "le32"; 89226633Sdim case amdil: return "amdil"; 90243830Sdim case spir: return "spir"; 91243830Sdim case spir64: return "spir"; 92198090Srdivacky } 93198090Srdivacky} 94198090Srdivacky 95193323Sedconst char *Triple::getVendorTypeName(VendorType Kind) { 96193323Sed switch (Kind) { 97193323Sed case UnknownVendor: return "unknown"; 98193323Sed 99193323Sed case Apple: return "apple"; 100198090Srdivacky case PC: return "pc"; 101221345Sdim case SCEI: return "scei"; 102234353Sdim case BGP: return "bgp"; 103234353Sdim case BGQ: return "bgq"; 104243830Sdim case Freescale: return "fsl"; 105243830Sdim case IBM: return "ibm"; 106263508Sdim case NVIDIA: return "nvidia"; 107193323Sed } 108193323Sed 109234353Sdim llvm_unreachable("Invalid VendorType!"); 110193323Sed} 111193323Sed 112193323Sedconst char *Triple::getOSTypeName(OSType Kind) { 113193323Sed switch (Kind) { 114193323Sed case UnknownOS: return "unknown"; 115193323Sed 116194612Sed case AuroraUX: return "auroraux"; 117198090Srdivacky case Cygwin: return "cygwin"; 118193323Sed case Darwin: return "darwin"; 119193323Sed case DragonFly: return "dragonfly"; 120193323Sed case FreeBSD: return "freebsd"; 121221345Sdim case IOS: return "ios"; 122226633Sdim case KFreeBSD: return "kfreebsd"; 123193323Sed case Linux: return "linux"; 124199989Srdivacky case Lv2: return "lv2"; 125221345Sdim case MacOSX: return "macosx"; 126198090Srdivacky case MinGW32: return "mingw32"; 127198090Srdivacky case NetBSD: return "netbsd"; 128195340Sed case OpenBSD: return "openbsd"; 129198090Srdivacky case Solaris: return "solaris"; 130198090Srdivacky case Win32: return "win32"; 131198396Srdivacky case Haiku: return "haiku"; 132210299Sed case Minix: return "minix"; 133224145Sdim case RTEMS: return "rtems"; 134249423Sdim case NaCl: return "nacl"; 135234353Sdim case CNK: return "cnk"; 136239462Sdim case Bitrig: return "bitrig"; 137243830Sdim case AIX: return "aix"; 138263508Sdim case CUDA: return "cuda"; 139263508Sdim case NVCL: return "nvcl"; 140193323Sed } 141193323Sed 142234353Sdim llvm_unreachable("Invalid OSType"); 143193323Sed} 144193323Sed 145218893Sdimconst char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { 146218893Sdim switch (Kind) { 147218893Sdim case UnknownEnvironment: return "unknown"; 148218893Sdim case GNU: return "gnu"; 149234353Sdim case GNUEABIHF: return "gnueabihf"; 150218893Sdim case GNUEABI: return "gnueabi"; 151249423Sdim case GNUX32: return "gnux32"; 152218893Sdim case EABI: return "eabi"; 153218893Sdim case MachO: return "macho"; 154243830Sdim case Android: return "android"; 155243830Sdim case ELF: return "elf"; 156218893Sdim } 157218893Sdim 158234353Sdim llvm_unreachable("Invalid EnvironmentType!"); 159218893Sdim} 160218893Sdim 161199481SrdivackyTriple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 162234353Sdim return StringSwitch<Triple::ArchType>(Name) 163249423Sdim .Case("aarch64", aarch64) 164234353Sdim .Case("arm", arm) 165234353Sdim .Case("mips", mips) 166234353Sdim .Case("mipsel", mipsel) 167234353Sdim .Case("mips64", mips64) 168234353Sdim .Case("mips64el", mips64el) 169234353Sdim .Case("msp430", msp430) 170234353Sdim .Case("ppc64", ppc64) 171234353Sdim .Case("ppc32", ppc) 172234353Sdim .Case("ppc", ppc) 173263508Sdim .Case("ppc64le", ppc64le) 174234353Sdim .Case("r600", r600) 175234353Sdim .Case("hexagon", hexagon) 176234353Sdim .Case("sparc", sparc) 177234353Sdim .Case("sparcv9", sparcv9) 178251662Sdim .Case("systemz", systemz) 179234353Sdim .Case("tce", tce) 180234353Sdim .Case("thumb", thumb) 181234353Sdim .Case("x86", x86) 182234353Sdim .Case("x86-64", x86_64) 183234353Sdim .Case("xcore", xcore) 184239462Sdim .Case("nvptx", nvptx) 185239462Sdim .Case("nvptx64", nvptx64) 186234353Sdim .Case("le32", le32) 187234353Sdim .Case("amdil", amdil) 188243830Sdim .Case("spir", spir) 189243830Sdim .Case("spir64", spir64) 190234353Sdim .Default(UnknownArch); 191198090Srdivacky} 192198090Srdivacky 193206083Srdivacky// Returns architecture name that is understood by the target assembler. 194199481Srdivackyconst char *Triple::getArchNameForAssembler() { 195221345Sdim if (!isOSDarwin() && getVendor() != Triple::Apple) 196199481Srdivacky return NULL; 197199481Srdivacky 198234353Sdim return StringSwitch<const char*>(getArchName()) 199234353Sdim .Case("i386", "i386") 200234353Sdim .Case("x86_64", "x86_64") 201234353Sdim .Case("powerpc", "ppc") 202234353Sdim .Case("powerpc64", "ppc64") 203263508Sdim .Case("powerpc64le", "ppc64le") 204234353Sdim .Case("arm", "arm") 205234353Sdim .Cases("armv4t", "thumbv4t", "armv4t") 206234353Sdim .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5") 207234353Sdim .Cases("armv6", "thumbv6", "armv6") 208234353Sdim .Cases("armv7", "thumbv7", "armv7") 209234353Sdim .Case("r600", "r600") 210239462Sdim .Case("nvptx", "nvptx") 211239462Sdim .Case("nvptx64", "nvptx64") 212234353Sdim .Case("le32", "le32") 213234353Sdim .Case("amdil", "amdil") 214243830Sdim .Case("spir", "spir") 215243830Sdim .Case("spir64", "spir64") 216234353Sdim .Default(NULL); 217199481Srdivacky} 218199481Srdivacky 219234353Sdimstatic Triple::ArchType parseArch(StringRef ArchName) { 220234353Sdim return StringSwitch<Triple::ArchType>(ArchName) 221234353Sdim .Cases("i386", "i486", "i586", "i686", Triple::x86) 222234353Sdim // FIXME: Do we need to support these? 223234353Sdim .Cases("i786", "i886", "i986", Triple::x86) 224263508Sdim .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64) 225234353Sdim .Case("powerpc", Triple::ppc) 226234353Sdim .Cases("powerpc64", "ppu", Triple::ppc64) 227263508Sdim .Case("powerpc64le", Triple::ppc64le) 228249423Sdim .Case("aarch64", Triple::aarch64) 229234353Sdim .Cases("arm", "xscale", Triple::arm) 230234353Sdim // FIXME: It would be good to replace these with explicit names for all the 231234353Sdim // various suffixes supported. 232234353Sdim .StartsWith("armv", Triple::arm) 233234353Sdim .Case("thumb", Triple::thumb) 234234353Sdim .StartsWith("thumbv", Triple::thumb) 235234353Sdim .Case("msp430", Triple::msp430) 236234353Sdim .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) 237234353Sdim .Cases("mipsel", "mipsallegrexel", Triple::mipsel) 238234353Sdim .Cases("mips64", "mips64eb", Triple::mips64) 239234353Sdim .Case("mips64el", Triple::mips64el) 240234353Sdim .Case("r600", Triple::r600) 241234353Sdim .Case("hexagon", Triple::hexagon) 242251662Sdim .Case("s390x", Triple::systemz) 243234353Sdim .Case("sparc", Triple::sparc) 244263508Sdim .Cases("sparcv9", "sparc64", Triple::sparcv9) 245234353Sdim .Case("tce", Triple::tce) 246234353Sdim .Case("xcore", Triple::xcore) 247239462Sdim .Case("nvptx", Triple::nvptx) 248239462Sdim .Case("nvptx64", Triple::nvptx64) 249234353Sdim .Case("le32", Triple::le32) 250234353Sdim .Case("amdil", Triple::amdil) 251243830Sdim .Case("spir", Triple::spir) 252243830Sdim .Case("spir64", Triple::spir64) 253234353Sdim .Default(Triple::UnknownArch); 254234353Sdim} 255193323Sed 256234353Sdimstatic Triple::VendorType parseVendor(StringRef VendorName) { 257234353Sdim return StringSwitch<Triple::VendorType>(VendorName) 258234353Sdim .Case("apple", Triple::Apple) 259234353Sdim .Case("pc", Triple::PC) 260234353Sdim .Case("scei", Triple::SCEI) 261234353Sdim .Case("bgp", Triple::BGP) 262234353Sdim .Case("bgq", Triple::BGQ) 263243830Sdim .Case("fsl", Triple::Freescale) 264243830Sdim .Case("ibm", Triple::IBM) 265263508Sdim .Case("nvidia", Triple::NVIDIA) 266234353Sdim .Default(Triple::UnknownVendor); 267212904Sdim} 268193323Sed 269234353Sdimstatic Triple::OSType parseOS(StringRef OSName) { 270234353Sdim return StringSwitch<Triple::OSType>(OSName) 271234353Sdim .StartsWith("auroraux", Triple::AuroraUX) 272234353Sdim .StartsWith("cygwin", Triple::Cygwin) 273234353Sdim .StartsWith("darwin", Triple::Darwin) 274234353Sdim .StartsWith("dragonfly", Triple::DragonFly) 275234353Sdim .StartsWith("freebsd", Triple::FreeBSD) 276234353Sdim .StartsWith("ios", Triple::IOS) 277234353Sdim .StartsWith("kfreebsd", Triple::KFreeBSD) 278234353Sdim .StartsWith("linux", Triple::Linux) 279234353Sdim .StartsWith("lv2", Triple::Lv2) 280234353Sdim .StartsWith("macosx", Triple::MacOSX) 281234353Sdim .StartsWith("mingw32", Triple::MinGW32) 282234353Sdim .StartsWith("netbsd", Triple::NetBSD) 283234353Sdim .StartsWith("openbsd", Triple::OpenBSD) 284234353Sdim .StartsWith("solaris", Triple::Solaris) 285234353Sdim .StartsWith("win32", Triple::Win32) 286234353Sdim .StartsWith("haiku", Triple::Haiku) 287234353Sdim .StartsWith("minix", Triple::Minix) 288234353Sdim .StartsWith("rtems", Triple::RTEMS) 289249423Sdim .StartsWith("nacl", Triple::NaCl) 290234353Sdim .StartsWith("cnk", Triple::CNK) 291239462Sdim .StartsWith("bitrig", Triple::Bitrig) 292243830Sdim .StartsWith("aix", Triple::AIX) 293263508Sdim .StartsWith("cuda", Triple::CUDA) 294263508Sdim .StartsWith("nvcl", Triple::NVCL) 295234353Sdim .Default(Triple::UnknownOS); 296212904Sdim} 297193323Sed 298234353Sdimstatic Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { 299234353Sdim return StringSwitch<Triple::EnvironmentType>(EnvironmentName) 300234353Sdim .StartsWith("eabi", Triple::EABI) 301234353Sdim .StartsWith("gnueabihf", Triple::GNUEABIHF) 302234353Sdim .StartsWith("gnueabi", Triple::GNUEABI) 303249423Sdim .StartsWith("gnux32", Triple::GNUX32) 304234353Sdim .StartsWith("gnu", Triple::GNU) 305234353Sdim .StartsWith("macho", Triple::MachO) 306243830Sdim .StartsWith("android", Triple::Android) 307243830Sdim .StartsWith("elf", Triple::ELF) 308234353Sdim .Default(Triple::UnknownEnvironment); 309212904Sdim} 310193323Sed 311234353Sdim/// \brief Construct a triple from the string representation provided. 312234353Sdim/// 313234353Sdim/// This stores the string representation and parses the various pieces into 314234353Sdim/// enum members. 315234353SdimTriple::Triple(const Twine &Str) 316234353Sdim : Data(Str.str()), 317234353Sdim Arch(parseArch(getArchName())), 318234353Sdim Vendor(parseVendor(getVendorName())), 319234353Sdim OS(parseOS(getOSName())), 320234353Sdim Environment(parseEnvironment(getEnvironmentName())) { 321218893Sdim} 322218893Sdim 323234353Sdim/// \brief Construct a triple from string representations of the architecture, 324234353Sdim/// vendor, and OS. 325234353Sdim/// 326234353Sdim/// This joins each argument into a canonical string representation and parses 327234353Sdim/// them into enum members. It leaves the environment unknown and omits it from 328234353Sdim/// the string representation. 329234353SdimTriple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr) 330234353Sdim : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()), 331234353Sdim Arch(parseArch(ArchStr.str())), 332234353Sdim Vendor(parseVendor(VendorStr.str())), 333234353Sdim OS(parseOS(OSStr.str())), 334234353Sdim Environment() { 335234353Sdim} 336212904Sdim 337234353Sdim/// \brief Construct a triple from string representations of the architecture, 338234353Sdim/// vendor, OS, and environment. 339234353Sdim/// 340234353Sdim/// This joins each argument into a canonical string representation and parses 341234353Sdim/// them into enum members. 342234353SdimTriple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, 343234353Sdim const Twine &EnvironmentStr) 344234353Sdim : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') + 345234353Sdim EnvironmentStr).str()), 346234353Sdim Arch(parseArch(ArchStr.str())), 347234353Sdim Vendor(parseVendor(VendorStr.str())), 348234353Sdim OS(parseOS(OSStr.str())), 349234353Sdim Environment(parseEnvironment(EnvironmentStr.str())) { 350193323Sed} 351193323Sed 352212904Sdimstd::string Triple::normalize(StringRef Str) { 353212904Sdim // Parse into components. 354212904Sdim SmallVector<StringRef, 4> Components; 355234353Sdim Str.split(Components, "-"); 356212904Sdim 357212904Sdim // If the first component corresponds to a known architecture, preferentially 358212904Sdim // use it for the architecture. If the second component corresponds to a 359212904Sdim // known vendor, preferentially use it for the vendor, etc. This avoids silly 360212904Sdim // component movement when a component parses as (eg) both a valid arch and a 361212904Sdim // valid os. 362212904Sdim ArchType Arch = UnknownArch; 363212904Sdim if (Components.size() > 0) 364234353Sdim Arch = parseArch(Components[0]); 365212904Sdim VendorType Vendor = UnknownVendor; 366212904Sdim if (Components.size() > 1) 367234353Sdim Vendor = parseVendor(Components[1]); 368212904Sdim OSType OS = UnknownOS; 369212904Sdim if (Components.size() > 2) 370234353Sdim OS = parseOS(Components[2]); 371218893Sdim EnvironmentType Environment = UnknownEnvironment; 372218893Sdim if (Components.size() > 3) 373234353Sdim Environment = parseEnvironment(Components[3]); 374212904Sdim 375212904Sdim // Note which components are already in their final position. These will not 376212904Sdim // be moved. 377218893Sdim bool Found[4]; 378212904Sdim Found[0] = Arch != UnknownArch; 379212904Sdim Found[1] = Vendor != UnknownVendor; 380212904Sdim Found[2] = OS != UnknownOS; 381218893Sdim Found[3] = Environment != UnknownEnvironment; 382212904Sdim 383212904Sdim // If they are not there already, permute the components into their canonical 384212904Sdim // positions by seeing if they parse as a valid architecture, and if so moving 385212904Sdim // the component to the architecture position etc. 386218893Sdim for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) { 387212904Sdim if (Found[Pos]) 388212904Sdim continue; // Already in the canonical position. 389212904Sdim 390212904Sdim for (unsigned Idx = 0; Idx != Components.size(); ++Idx) { 391212904Sdim // Do not reparse any components that already matched. 392218893Sdim if (Idx < array_lengthof(Found) && Found[Idx]) 393212904Sdim continue; 394212904Sdim 395212904Sdim // Does this component parse as valid for the target position? 396212904Sdim bool Valid = false; 397212904Sdim StringRef Comp = Components[Idx]; 398212904Sdim switch (Pos) { 399234353Sdim default: llvm_unreachable("unexpected component type!"); 400212904Sdim case 0: 401234353Sdim Arch = parseArch(Comp); 402212904Sdim Valid = Arch != UnknownArch; 403212904Sdim break; 404212904Sdim case 1: 405234353Sdim Vendor = parseVendor(Comp); 406212904Sdim Valid = Vendor != UnknownVendor; 407212904Sdim break; 408212904Sdim case 2: 409234353Sdim OS = parseOS(Comp); 410212904Sdim Valid = OS != UnknownOS; 411212904Sdim break; 412218893Sdim case 3: 413234353Sdim Environment = parseEnvironment(Comp); 414218893Sdim Valid = Environment != UnknownEnvironment; 415218893Sdim break; 416212904Sdim } 417212904Sdim if (!Valid) 418212904Sdim continue; // Nope, try the next component. 419212904Sdim 420212904Sdim // Move the component to the target position, pushing any non-fixed 421212904Sdim // components that are in the way to the right. This tends to give 422212904Sdim // good results in the common cases of a forgotten vendor component 423212904Sdim // or a wrongly positioned environment. 424212904Sdim if (Pos < Idx) { 425212904Sdim // Insert left, pushing the existing components to the right. For 426212904Sdim // example, a-b-i386 -> i386-a-b when moving i386 to the front. 427212904Sdim StringRef CurrentComponent(""); // The empty component. 428212904Sdim // Replace the component we are moving with an empty component. 429212904Sdim std::swap(CurrentComponent, Components[Idx]); 430212904Sdim // Insert the component being moved at Pos, displacing any existing 431212904Sdim // components to the right. 432212904Sdim for (unsigned i = Pos; !CurrentComponent.empty(); ++i) { 433212904Sdim // Skip over any fixed components. 434234353Sdim while (i < array_lengthof(Found) && Found[i]) 435234353Sdim ++i; 436212904Sdim // Place the component at the new position, getting the component 437212904Sdim // that was at this position - it will be moved right. 438212904Sdim std::swap(CurrentComponent, Components[i]); 439212904Sdim } 440212904Sdim } else if (Pos > Idx) { 441212904Sdim // Push right by inserting empty components until the component at Idx 442212904Sdim // reaches the target position Pos. For example, pc-a -> -pc-a when 443212904Sdim // moving pc to the second position. 444212904Sdim do { 445212904Sdim // Insert one empty component at Idx. 446212904Sdim StringRef CurrentComponent(""); // The empty component. 447218893Sdim for (unsigned i = Idx; i < Components.size();) { 448212904Sdim // Place the component at the new position, getting the component 449212904Sdim // that was at this position - it will be moved right. 450212904Sdim std::swap(CurrentComponent, Components[i]); 451212904Sdim // If it was placed on top of an empty component then we are done. 452212904Sdim if (CurrentComponent.empty()) 453212904Sdim break; 454218893Sdim // Advance to the next component, skipping any fixed components. 455218893Sdim while (++i < array_lengthof(Found) && Found[i]) 456218893Sdim ; 457212904Sdim } 458212904Sdim // The last component was pushed off the end - append it. 459212904Sdim if (!CurrentComponent.empty()) 460212904Sdim Components.push_back(CurrentComponent); 461212904Sdim 462212904Sdim // Advance Idx to the component's new position. 463234353Sdim while (++Idx < array_lengthof(Found) && Found[Idx]) 464234353Sdim ; 465212904Sdim } while (Idx < Pos); // Add more until the final position is reached. 466212904Sdim } 467212904Sdim assert(Pos < Components.size() && Components[Pos] == Comp && 468212904Sdim "Component moved wrong!"); 469212904Sdim Found[Pos] = true; 470212904Sdim break; 471212904Sdim } 472212904Sdim } 473212904Sdim 474212904Sdim // Special case logic goes here. At this point Arch, Vendor and OS have the 475212904Sdim // correct values for the computed components. 476212904Sdim 477212904Sdim // Stick the corrected components back together to form the normalized string. 478212904Sdim std::string Normalized; 479212904Sdim for (unsigned i = 0, e = Components.size(); i != e; ++i) { 480212904Sdim if (i) Normalized += '-'; 481212904Sdim Normalized += Components[i]; 482212904Sdim } 483212904Sdim return Normalized; 484212904Sdim} 485212904Sdim 486198090SrdivackyStringRef Triple::getArchName() const { 487198090Srdivacky return StringRef(Data).split('-').first; // Isolate first component 488193323Sed} 489193323Sed 490198090SrdivackyStringRef Triple::getVendorName() const { 491198090Srdivacky StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 492198090Srdivacky return Tmp.split('-').first; // Isolate second component 493193323Sed} 494193323Sed 495198090SrdivackyStringRef Triple::getOSName() const { 496198090Srdivacky StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 497198090Srdivacky Tmp = Tmp.split('-').second; // Strip second component 498198090Srdivacky return Tmp.split('-').first; // Isolate third component 499193323Sed} 500193323Sed 501198090SrdivackyStringRef Triple::getEnvironmentName() const { 502198090Srdivacky StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 503198090Srdivacky Tmp = Tmp.split('-').second; // Strip second component 504198090Srdivacky return Tmp.split('-').second; // Strip third component 505193323Sed} 506193323Sed 507198090SrdivackyStringRef Triple::getOSAndEnvironmentName() const { 508198090Srdivacky StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 509198090Srdivacky return Tmp.split('-').second; // Strip second component 510193323Sed} 511193323Sed 512198090Srdivackystatic unsigned EatNumber(StringRef &Str) { 513198090Srdivacky assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 514221345Sdim unsigned Result = 0; 515218893Sdim 516221345Sdim do { 517221345Sdim // Consume the leading digit. 518221345Sdim Result = Result*10 + (Str[0] - '0'); 519218893Sdim 520198090Srdivacky // Eat the digit. 521198090Srdivacky Str = Str.substr(1); 522221345Sdim } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9'); 523218893Sdim 524198090Srdivacky return Result; 525193323Sed} 526193323Sed 527221345Sdimvoid Triple::getOSVersion(unsigned &Major, unsigned &Minor, 528221345Sdim unsigned &Micro) const { 529198090Srdivacky StringRef OSName = getOSName(); 530218893Sdim 531221345Sdim // Assume that the OS portion of the triple starts with the canonical name. 532221345Sdim StringRef OSTypeName = getOSTypeName(getOS()); 533221345Sdim if (OSName.startswith(OSTypeName)) 534221345Sdim OSName = OSName.substr(OSTypeName.size()); 535218893Sdim 536221345Sdim // Any unset version defaults to 0. 537221345Sdim Major = Minor = Micro = 0; 538198090Srdivacky 539221345Sdim // Parse up to three components. 540221345Sdim unsigned *Components[3] = { &Major, &Minor, &Micro }; 541221345Sdim for (unsigned i = 0; i != 3; ++i) { 542221345Sdim if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 543221345Sdim break; 544198090Srdivacky 545221345Sdim // Consume the leading number. 546221345Sdim *Components[i] = EatNumber(OSName); 547218893Sdim 548221345Sdim // Consume the separator, if present. 549221345Sdim if (OSName.startswith(".")) 550221345Sdim OSName = OSName.substr(1); 551221345Sdim } 552193323Sed} 553193323Sed 554234353Sdimbool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor, 555234353Sdim unsigned &Micro) const { 556234353Sdim getOSVersion(Major, Minor, Micro); 557234353Sdim 558234353Sdim switch (getOS()) { 559234353Sdim default: llvm_unreachable("unexpected OS for Darwin triple"); 560234353Sdim case Darwin: 561234353Sdim // Default to darwin8, i.e., MacOSX 10.4. 562234353Sdim if (Major == 0) 563234353Sdim Major = 8; 564234353Sdim // Darwin version numbers are skewed from OS X versions. 565234353Sdim if (Major < 4) 566234353Sdim return false; 567234353Sdim Micro = 0; 568234353Sdim Minor = Major - 4; 569234353Sdim Major = 10; 570234353Sdim break; 571234353Sdim case MacOSX: 572234353Sdim // Default to 10.4. 573234353Sdim if (Major == 0) { 574234353Sdim Major = 10; 575234353Sdim Minor = 4; 576234353Sdim } 577234353Sdim if (Major != 10) 578234353Sdim return false; 579234353Sdim break; 580234353Sdim case IOS: 581234353Sdim // Ignore the version from the triple. This is only handled because the 582234353Sdim // the clang driver combines OS X and IOS support into a common Darwin 583234353Sdim // toolchain that wants to know the OS X version number even when targeting 584234353Sdim // IOS. 585234353Sdim Major = 10; 586234353Sdim Minor = 4; 587234353Sdim Micro = 0; 588234353Sdim break; 589234353Sdim } 590234353Sdim return true; 591234353Sdim} 592234353Sdim 593239462Sdimvoid Triple::getiOSVersion(unsigned &Major, unsigned &Minor, 594239462Sdim unsigned &Micro) const { 595239462Sdim switch (getOS()) { 596239462Sdim default: llvm_unreachable("unexpected OS for Darwin triple"); 597239462Sdim case Darwin: 598239462Sdim case MacOSX: 599239462Sdim // Ignore the version from the triple. This is only handled because the 600239462Sdim // the clang driver combines OS X and IOS support into a common Darwin 601239462Sdim // toolchain that wants to know the iOS version number even when targeting 602239462Sdim // OS X. 603239462Sdim Major = 3; 604239462Sdim Minor = 0; 605239462Sdim Micro = 0; 606239462Sdim break; 607239462Sdim case IOS: 608239462Sdim getOSVersion(Major, Minor, Micro); 609239462Sdim // Default to 3.0. 610239462Sdim if (Major == 0) 611239462Sdim Major = 3; 612239462Sdim break; 613239462Sdim } 614239462Sdim} 615239462Sdim 616198090Srdivackyvoid Triple::setTriple(const Twine &Str) { 617234353Sdim *this = Triple(Str); 618193323Sed} 619193323Sed 620193323Sedvoid Triple::setArch(ArchType Kind) { 621193323Sed setArchName(getArchTypeName(Kind)); 622193323Sed} 623193323Sed 624193323Sedvoid Triple::setVendor(VendorType Kind) { 625193323Sed setVendorName(getVendorTypeName(Kind)); 626193323Sed} 627193323Sed 628193323Sedvoid Triple::setOS(OSType Kind) { 629193323Sed setOSName(getOSTypeName(Kind)); 630193323Sed} 631193323Sed 632218893Sdimvoid Triple::setEnvironment(EnvironmentType Kind) { 633218893Sdim setEnvironmentName(getEnvironmentTypeName(Kind)); 634218893Sdim} 635218893Sdim 636199481Srdivackyvoid Triple::setArchName(StringRef Str) { 637198090Srdivacky // Work around a miscompilation bug for Twines in gcc 4.0.3. 638198090Srdivacky SmallString<64> Triple; 639198090Srdivacky Triple += Str; 640198090Srdivacky Triple += "-"; 641198090Srdivacky Triple += getVendorName(); 642198090Srdivacky Triple += "-"; 643198090Srdivacky Triple += getOSAndEnvironmentName(); 644198090Srdivacky setTriple(Triple.str()); 645193323Sed} 646193323Sed 647199481Srdivackyvoid Triple::setVendorName(StringRef Str) { 648193323Sed setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 649193323Sed} 650193323Sed 651199481Srdivackyvoid Triple::setOSName(StringRef Str) { 652193323Sed if (hasEnvironment()) 653193323Sed setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 654193323Sed "-" + getEnvironmentName()); 655193323Sed else 656193323Sed setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 657193323Sed} 658193323Sed 659199481Srdivackyvoid Triple::setEnvironmentName(StringRef Str) { 660199481Srdivacky setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 661193323Sed "-" + Str); 662193323Sed} 663193323Sed 664199481Srdivackyvoid Triple::setOSAndEnvironmentName(StringRef Str) { 665193323Sed setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 666193323Sed} 667234353Sdim 668234353Sdimstatic unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { 669234353Sdim switch (Arch) { 670234353Sdim case llvm::Triple::UnknownArch: 671234353Sdim return 0; 672234353Sdim 673234353Sdim case llvm::Triple::msp430: 674234353Sdim return 16; 675234353Sdim 676234353Sdim case llvm::Triple::amdil: 677234353Sdim case llvm::Triple::arm: 678234353Sdim case llvm::Triple::hexagon: 679234353Sdim case llvm::Triple::le32: 680234353Sdim case llvm::Triple::mips: 681234353Sdim case llvm::Triple::mipsel: 682239462Sdim case llvm::Triple::nvptx: 683234353Sdim case llvm::Triple::ppc: 684234353Sdim case llvm::Triple::r600: 685234353Sdim case llvm::Triple::sparc: 686234353Sdim case llvm::Triple::tce: 687234353Sdim case llvm::Triple::thumb: 688234353Sdim case llvm::Triple::x86: 689234353Sdim case llvm::Triple::xcore: 690243830Sdim case llvm::Triple::spir: 691234353Sdim return 32; 692234353Sdim 693249423Sdim case llvm::Triple::aarch64: 694234353Sdim case llvm::Triple::mips64: 695234353Sdim case llvm::Triple::mips64el: 696239462Sdim case llvm::Triple::nvptx64: 697234353Sdim case llvm::Triple::ppc64: 698263508Sdim case llvm::Triple::ppc64le: 699234353Sdim case llvm::Triple::sparcv9: 700251662Sdim case llvm::Triple::systemz: 701234353Sdim case llvm::Triple::x86_64: 702243830Sdim case llvm::Triple::spir64: 703234353Sdim return 64; 704234353Sdim } 705234353Sdim llvm_unreachable("Invalid architecture value"); 706234353Sdim} 707234353Sdim 708234353Sdimbool Triple::isArch64Bit() const { 709234353Sdim return getArchPointerBitWidth(getArch()) == 64; 710234353Sdim} 711234353Sdim 712234353Sdimbool Triple::isArch32Bit() const { 713234353Sdim return getArchPointerBitWidth(getArch()) == 32; 714234353Sdim} 715234353Sdim 716234353Sdimbool Triple::isArch16Bit() const { 717234353Sdim return getArchPointerBitWidth(getArch()) == 16; 718234353Sdim} 719234353Sdim 720234353SdimTriple Triple::get32BitArchVariant() const { 721234353Sdim Triple T(*this); 722234353Sdim switch (getArch()) { 723234353Sdim case Triple::UnknownArch: 724249423Sdim case Triple::aarch64: 725234353Sdim case Triple::msp430: 726251662Sdim case Triple::systemz: 727263508Sdim case Triple::ppc64le: 728234353Sdim T.setArch(UnknownArch); 729234353Sdim break; 730234353Sdim 731234353Sdim case Triple::amdil: 732243830Sdim case Triple::spir: 733234353Sdim case Triple::arm: 734234353Sdim case Triple::hexagon: 735234353Sdim case Triple::le32: 736234353Sdim case Triple::mips: 737234353Sdim case Triple::mipsel: 738239462Sdim case Triple::nvptx: 739234353Sdim case Triple::ppc: 740234353Sdim case Triple::r600: 741234353Sdim case Triple::sparc: 742234353Sdim case Triple::tce: 743234353Sdim case Triple::thumb: 744234353Sdim case Triple::x86: 745234353Sdim case Triple::xcore: 746234353Sdim // Already 32-bit. 747234353Sdim break; 748234353Sdim 749234353Sdim case Triple::mips64: T.setArch(Triple::mips); break; 750234353Sdim case Triple::mips64el: T.setArch(Triple::mipsel); break; 751239462Sdim case Triple::nvptx64: T.setArch(Triple::nvptx); break; 752234353Sdim case Triple::ppc64: T.setArch(Triple::ppc); break; 753234353Sdim case Triple::sparcv9: T.setArch(Triple::sparc); break; 754234353Sdim case Triple::x86_64: T.setArch(Triple::x86); break; 755243830Sdim case Triple::spir64: T.setArch(Triple::spir); break; 756234353Sdim } 757234353Sdim return T; 758234353Sdim} 759234353Sdim 760234353SdimTriple Triple::get64BitArchVariant() const { 761234353Sdim Triple T(*this); 762234353Sdim switch (getArch()) { 763234353Sdim case Triple::UnknownArch: 764234353Sdim case Triple::amdil: 765234353Sdim case Triple::arm: 766234353Sdim case Triple::hexagon: 767234353Sdim case Triple::le32: 768234353Sdim case Triple::msp430: 769234353Sdim case Triple::r600: 770234353Sdim case Triple::tce: 771234353Sdim case Triple::thumb: 772234353Sdim case Triple::xcore: 773234353Sdim T.setArch(UnknownArch); 774234353Sdim break; 775234353Sdim 776249423Sdim case Triple::aarch64: 777243830Sdim case Triple::spir64: 778234353Sdim case Triple::mips64: 779234353Sdim case Triple::mips64el: 780239462Sdim case Triple::nvptx64: 781234353Sdim case Triple::ppc64: 782263508Sdim case Triple::ppc64le: 783234353Sdim case Triple::sparcv9: 784251662Sdim case Triple::systemz: 785234353Sdim case Triple::x86_64: 786234353Sdim // Already 64-bit. 787234353Sdim break; 788234353Sdim 789234353Sdim case Triple::mips: T.setArch(Triple::mips64); break; 790234353Sdim case Triple::mipsel: T.setArch(Triple::mips64el); break; 791239462Sdim case Triple::nvptx: T.setArch(Triple::nvptx64); break; 792234353Sdim case Triple::ppc: T.setArch(Triple::ppc64); break; 793234353Sdim case Triple::sparc: T.setArch(Triple::sparcv9); break; 794234353Sdim case Triple::x86: T.setArch(Triple::x86_64); break; 795243830Sdim case Triple::spir: T.setArch(Triple::spir64); break; 796234353Sdim } 797234353Sdim return T; 798234353Sdim} 799