Triple.cpp revision 206083
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" 11198090Srdivacky 12198090Srdivacky#include "llvm/ADT/SmallString.h" 13198090Srdivacky#include "llvm/ADT/Twine.h" 14193323Sed#include <cassert> 15193323Sed#include <cstring> 16193323Sedusing namespace llvm; 17193323Sed 18193323Sed// 19193323Sed 20193323Sedconst char *Triple::getArchTypeName(ArchType Kind) { 21193323Sed switch (Kind) { 22193323Sed case InvalidArch: return "<invalid>"; 23193323Sed case UnknownArch: return "unknown"; 24198090Srdivacky 25198090Srdivacky case alpha: return "alpha"; 26198090Srdivacky case arm: return "arm"; 27198090Srdivacky case bfin: return "bfin"; 28198090Srdivacky case cellspu: return "cellspu"; 29198090Srdivacky case mips: return "mips"; 30198090Srdivacky case mipsel: return "mipsel"; 31198090Srdivacky case msp430: return "msp430"; 32198090Srdivacky case pic16: return "pic16"; 33198090Srdivacky case ppc64: return "powerpc64"; 34198090Srdivacky case ppc: return "powerpc"; 35198090Srdivacky case sparc: return "sparc"; 36203954Srdivacky case sparcv9: return "sparcv9"; 37198090Srdivacky case systemz: return "s390x"; 38198090Srdivacky case tce: return "tce"; 39198090Srdivacky case thumb: return "thumb"; 40198090Srdivacky case x86: return "i386"; 41198090Srdivacky case x86_64: return "x86_64"; 42198090Srdivacky case xcore: return "xcore"; 43204642Srdivacky case mblaze: return "mblaze"; 44193323Sed } 45193323Sed 46193323Sed return "<invalid>"; 47193323Sed} 48193323Sed 49198090Srdivackyconst char *Triple::getArchTypePrefix(ArchType Kind) { 50198090Srdivacky switch (Kind) { 51198090Srdivacky default: 52198090Srdivacky return 0; 53198090Srdivacky 54198090Srdivacky case alpha: return "alpha"; 55198090Srdivacky 56198090Srdivacky case arm: 57198090Srdivacky case thumb: return "arm"; 58198090Srdivacky 59198090Srdivacky case bfin: return "bfin"; 60198090Srdivacky 61198090Srdivacky case cellspu: return "spu"; 62198090Srdivacky 63198090Srdivacky case ppc64: 64198090Srdivacky case ppc: return "ppc"; 65198090Srdivacky 66204642Srdivacky case mblaze: return "mblaze"; 67204642Srdivacky 68203954Srdivacky case sparcv9: 69198090Srdivacky case sparc: return "sparc"; 70198090Srdivacky 71198090Srdivacky case x86: 72198090Srdivacky case x86_64: return "x86"; 73198090Srdivacky case xcore: return "xcore"; 74198090Srdivacky } 75198090Srdivacky} 76198090Srdivacky 77193323Sedconst char *Triple::getVendorTypeName(VendorType Kind) { 78193323Sed switch (Kind) { 79193323Sed case UnknownVendor: return "unknown"; 80193323Sed 81193323Sed case Apple: return "apple"; 82198090Srdivacky case PC: return "pc"; 83193323Sed } 84193323Sed 85193323Sed return "<invalid>"; 86193323Sed} 87193323Sed 88193323Sedconst char *Triple::getOSTypeName(OSType Kind) { 89193323Sed switch (Kind) { 90193323Sed case UnknownOS: return "unknown"; 91193323Sed 92194612Sed case AuroraUX: return "auroraux"; 93198090Srdivacky case Cygwin: return "cygwin"; 94193323Sed case Darwin: return "darwin"; 95193323Sed case DragonFly: return "dragonfly"; 96193323Sed case FreeBSD: return "freebsd"; 97193323Sed case Linux: return "linux"; 98199989Srdivacky case Lv2: return "lv2"; 99198090Srdivacky case MinGW32: return "mingw32"; 100198090Srdivacky case MinGW64: return "mingw64"; 101198090Srdivacky case NetBSD: return "netbsd"; 102195340Sed case OpenBSD: return "openbsd"; 103199481Srdivacky case Psp: return "psp"; 104198090Srdivacky case Solaris: return "solaris"; 105198090Srdivacky case Win32: return "win32"; 106198396Srdivacky case Haiku: return "haiku"; 107193323Sed } 108193323Sed 109193323Sed return "<invalid>"; 110193323Sed} 111193323Sed 112199481SrdivackyTriple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 113198090Srdivacky if (Name == "alpha") 114198090Srdivacky return alpha; 115198090Srdivacky if (Name == "arm") 116198090Srdivacky return arm; 117198090Srdivacky if (Name == "bfin") 118198090Srdivacky return bfin; 119198090Srdivacky if (Name == "cellspu") 120198090Srdivacky return cellspu; 121198090Srdivacky if (Name == "mips") 122198090Srdivacky return mips; 123198090Srdivacky if (Name == "mipsel") 124198090Srdivacky return mipsel; 125198090Srdivacky if (Name == "msp430") 126198090Srdivacky return msp430; 127198090Srdivacky if (Name == "pic16") 128198090Srdivacky return pic16; 129198090Srdivacky if (Name == "ppc64") 130198090Srdivacky return ppc64; 131198090Srdivacky if (Name == "ppc") 132198090Srdivacky return ppc; 133204642Srdivacky if (Name == "mblaze") 134204642Srdivacky return mblaze; 135198090Srdivacky if (Name == "sparc") 136198090Srdivacky return sparc; 137203954Srdivacky if (Name == "sparcv9") 138203954Srdivacky return sparcv9; 139198090Srdivacky if (Name == "systemz") 140198090Srdivacky return systemz; 141198090Srdivacky if (Name == "tce") 142198090Srdivacky return tce; 143198090Srdivacky if (Name == "thumb") 144198090Srdivacky return thumb; 145198090Srdivacky if (Name == "x86") 146198090Srdivacky return x86; 147198090Srdivacky if (Name == "x86-64") 148198090Srdivacky return x86_64; 149198090Srdivacky if (Name == "xcore") 150198090Srdivacky return xcore; 151198090Srdivacky 152198090Srdivacky return UnknownArch; 153198090Srdivacky} 154198090Srdivacky 155199481SrdivackyTriple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) { 156198090Srdivacky // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for 157198090Srdivacky // archs which Darwin doesn't use. 158198090Srdivacky 159198090Srdivacky // The matching this routine does is fairly pointless, since it is neither the 160198090Srdivacky // complete architecture list, nor a reasonable subset. The problem is that 161198090Srdivacky // historically the driver driver accepts this and also ties its -march= 162198090Srdivacky // handling to the architecture name, so we need to be careful before removing 163198090Srdivacky // support for it. 164198090Srdivacky 165198090Srdivacky // This code must be kept in sync with Clang's Darwin specific argument 166198090Srdivacky // translation. 167198090Srdivacky 168198090Srdivacky if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" || 169198090Srdivacky Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" || 170198090Srdivacky Str == "ppc7450" || Str == "ppc970") 171198090Srdivacky return Triple::ppc; 172198090Srdivacky 173198090Srdivacky if (Str == "ppc64") 174198090Srdivacky return Triple::ppc64; 175198090Srdivacky 176198090Srdivacky if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" || 177198090Srdivacky Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" || 178198090Srdivacky Str == "pentIIm5" || Str == "pentium4") 179198090Srdivacky return Triple::x86; 180198090Srdivacky 181198090Srdivacky if (Str == "x86_64") 182198090Srdivacky return Triple::x86_64; 183198090Srdivacky 184198090Srdivacky // This is derived from the driver driver. 185198090Srdivacky if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" || 186198090Srdivacky Str == "armv6" || Str == "armv7") 187198090Srdivacky return Triple::arm; 188198090Srdivacky 189198090Srdivacky return Triple::UnknownArch; 190198090Srdivacky} 191198090Srdivacky 192206083Srdivacky// Returns architecture name that is understood by the target assembler. 193199481Srdivackyconst char *Triple::getArchNameForAssembler() { 194199481Srdivacky if (getOS() != Triple::Darwin && getVendor() != Triple::Apple) 195199481Srdivacky return NULL; 196199481Srdivacky 197199481Srdivacky StringRef Str = getArchName(); 198199481Srdivacky if (Str == "i386") 199199481Srdivacky return "i386"; 200199481Srdivacky if (Str == "x86_64") 201199481Srdivacky return "x86_64"; 202199481Srdivacky if (Str == "powerpc") 203199481Srdivacky return "ppc"; 204199481Srdivacky if (Str == "powerpc64") 205199481Srdivacky return "ppc64"; 206204642Srdivacky if (Str == "mblaze" || Str == "microblaze") 207204642Srdivacky return "mblaze"; 208199481Srdivacky if (Str == "arm") 209199481Srdivacky return "arm"; 210199481Srdivacky if (Str == "armv4t" || Str == "thumbv4t") 211199481Srdivacky return "armv4t"; 212199481Srdivacky if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e") 213199481Srdivacky return "armv5"; 214199481Srdivacky if (Str == "armv6" || Str == "thumbv6") 215199481Srdivacky return "armv6"; 216199481Srdivacky if (Str == "armv7" || Str == "thumbv7") 217199481Srdivacky return "armv7"; 218199481Srdivacky return NULL; 219199481Srdivacky} 220199481Srdivacky 221193323Sed// 222193323Sed 223193323Sedvoid Triple::Parse() const { 224193323Sed assert(!isInitialized() && "Invalid parse call."); 225193323Sed 226198090Srdivacky StringRef ArchName = getArchName(); 227198090Srdivacky StringRef VendorName = getVendorName(); 228198090Srdivacky StringRef OSName = getOSName(); 229198090Srdivacky 230193323Sed if (ArchName.size() == 4 && ArchName[0] == 'i' && 231198090Srdivacky ArchName[2] == '8' && ArchName[3] == '6' && 232198090Srdivacky ArchName[1] - '3' < 6) // i[3-9]86 233193323Sed Arch = x86; 234193323Sed else if (ArchName == "amd64" || ArchName == "x86_64") 235193323Sed Arch = x86_64; 236198090Srdivacky else if (ArchName == "bfin") 237198090Srdivacky Arch = bfin; 238198090Srdivacky else if (ArchName == "pic16") 239198090Srdivacky Arch = pic16; 240193323Sed else if (ArchName == "powerpc") 241193323Sed Arch = ppc; 242199989Srdivacky else if ((ArchName == "powerpc64") || (ArchName == "ppu")) 243193323Sed Arch = ppc64; 244204642Srdivacky else if (ArchName == "mblaze") 245204642Srdivacky Arch = mblaze; 246198090Srdivacky else if (ArchName == "arm" || 247198090Srdivacky ArchName.startswith("armv") || 248198090Srdivacky ArchName == "xscale") 249198090Srdivacky Arch = arm; 250198090Srdivacky else if (ArchName == "thumb" || 251198090Srdivacky ArchName.startswith("thumbv")) 252198090Srdivacky Arch = thumb; 253198090Srdivacky else if (ArchName.startswith("alpha")) 254198090Srdivacky Arch = alpha; 255198090Srdivacky else if (ArchName == "spu" || ArchName == "cellspu") 256198090Srdivacky Arch = cellspu; 257198090Srdivacky else if (ArchName == "msp430") 258198090Srdivacky Arch = msp430; 259198090Srdivacky else if (ArchName == "mips" || ArchName == "mipsallegrex") 260198090Srdivacky Arch = mips; 261198090Srdivacky else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" || 262198090Srdivacky ArchName == "psp") 263198090Srdivacky Arch = mipsel; 264198090Srdivacky else if (ArchName == "sparc") 265198090Srdivacky Arch = sparc; 266203954Srdivacky else if (ArchName == "sparcv9") 267203954Srdivacky Arch = sparcv9; 268198090Srdivacky else if (ArchName == "s390x") 269198090Srdivacky Arch = systemz; 270198090Srdivacky else if (ArchName == "tce") 271198090Srdivacky Arch = tce; 272198090Srdivacky else if (ArchName == "xcore") 273198090Srdivacky Arch = xcore; 274193323Sed else 275193323Sed Arch = UnknownArch; 276193323Sed 277198090Srdivacky 278198090Srdivacky // Handle some exceptional cases where the OS / environment components are 279198090Srdivacky // stuck into the vendor field. 280198090Srdivacky if (StringRef(getTriple()).count('-') == 1) { 281198090Srdivacky StringRef VendorName = getVendorName(); 282198090Srdivacky 283198090Srdivacky if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc. 284198090Srdivacky Vendor = PC; 285198090Srdivacky OS = MinGW32; 286198090Srdivacky return; 287198090Srdivacky } 288198090Srdivacky 289198090Srdivacky // arm-elf is another example, but we don't currently parse anything about 290198090Srdivacky // the environment. 291198090Srdivacky } 292198090Srdivacky 293193323Sed if (VendorName == "apple") 294193323Sed Vendor = Apple; 295193323Sed else if (VendorName == "pc") 296193323Sed Vendor = PC; 297193323Sed else 298193323Sed Vendor = UnknownVendor; 299193323Sed 300198090Srdivacky if (OSName.startswith("auroraux")) 301194612Sed OS = AuroraUX; 302198090Srdivacky else if (OSName.startswith("cygwin")) 303198090Srdivacky OS = Cygwin; 304198090Srdivacky else if (OSName.startswith("darwin")) 305193323Sed OS = Darwin; 306198090Srdivacky else if (OSName.startswith("dragonfly")) 307193323Sed OS = DragonFly; 308198090Srdivacky else if (OSName.startswith("freebsd")) 309193323Sed OS = FreeBSD; 310198090Srdivacky else if (OSName.startswith("linux")) 311193323Sed OS = Linux; 312199989Srdivacky else if (OSName.startswith("lv2")) 313199989Srdivacky OS = Lv2; 314198090Srdivacky else if (OSName.startswith("mingw32")) 315198090Srdivacky OS = MinGW32; 316198090Srdivacky else if (OSName.startswith("mingw64")) 317198090Srdivacky OS = MinGW64; 318198090Srdivacky else if (OSName.startswith("netbsd")) 319198090Srdivacky OS = NetBSD; 320198090Srdivacky else if (OSName.startswith("openbsd")) 321195340Sed OS = OpenBSD; 322199481Srdivacky else if (OSName.startswith("psp")) 323199481Srdivacky OS = Psp; 324198090Srdivacky else if (OSName.startswith("solaris")) 325198090Srdivacky OS = Solaris; 326198090Srdivacky else if (OSName.startswith("win32")) 327198090Srdivacky OS = Win32; 328198396Srdivacky else if (OSName.startswith("haiku")) 329198396Srdivacky OS = Haiku; 330193323Sed else 331193323Sed OS = UnknownOS; 332193323Sed 333193323Sed assert(isInitialized() && "Failed to initialize!"); 334193323Sed} 335193323Sed 336198090SrdivackyStringRef Triple::getArchName() const { 337198090Srdivacky return StringRef(Data).split('-').first; // Isolate first component 338193323Sed} 339193323Sed 340198090SrdivackyStringRef Triple::getVendorName() const { 341198090Srdivacky StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 342198090Srdivacky return Tmp.split('-').first; // Isolate second component 343193323Sed} 344193323Sed 345198090SrdivackyStringRef Triple::getOSName() const { 346198090Srdivacky StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 347198090Srdivacky Tmp = Tmp.split('-').second; // Strip second component 348198090Srdivacky return Tmp.split('-').first; // Isolate third component 349193323Sed} 350193323Sed 351198090SrdivackyStringRef Triple::getEnvironmentName() const { 352198090Srdivacky StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 353198090Srdivacky Tmp = Tmp.split('-').second; // Strip second component 354198090Srdivacky return Tmp.split('-').second; // Strip third component 355193323Sed} 356193323Sed 357198090SrdivackyStringRef Triple::getOSAndEnvironmentName() const { 358198090Srdivacky StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 359198090Srdivacky return Tmp.split('-').second; // Strip second component 360193323Sed} 361193323Sed 362198090Srdivackystatic unsigned EatNumber(StringRef &Str) { 363198090Srdivacky assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 364198090Srdivacky unsigned Result = Str[0]-'0'; 365198090Srdivacky 366198090Srdivacky // Eat the digit. 367198090Srdivacky Str = Str.substr(1); 368198090Srdivacky 369198090Srdivacky // Handle "darwin11". 370198090Srdivacky if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') { 371198090Srdivacky Result = Result*10 + (Str[0] - '0'); 372198090Srdivacky // Eat the digit. 373198090Srdivacky Str = Str.substr(1); 374198090Srdivacky } 375198090Srdivacky 376198090Srdivacky return Result; 377193323Sed} 378193323Sed 379198090Srdivacky/// getDarwinNumber - Parse the 'darwin number' out of the specific target 380198090Srdivacky/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is 381198090Srdivacky/// not defined, return 0's. This requires that the triple have an OSType of 382198090Srdivacky/// darwin before it is called. 383198090Srdivackyvoid Triple::getDarwinNumber(unsigned &Maj, unsigned &Min, 384198090Srdivacky unsigned &Revision) const { 385198090Srdivacky assert(getOS() == Darwin && "Not a darwin target triple!"); 386198090Srdivacky StringRef OSName = getOSName(); 387198090Srdivacky assert(OSName.startswith("darwin") && "Unknown darwin target triple!"); 388198090Srdivacky 389198090Srdivacky // Strip off "darwin". 390198090Srdivacky OSName = OSName.substr(6); 391198090Srdivacky 392198090Srdivacky Maj = Min = Revision = 0; 393198090Srdivacky 394198090Srdivacky if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 395198090Srdivacky return; 396198090Srdivacky 397198090Srdivacky // The major version is the first digit. 398198090Srdivacky Maj = EatNumber(OSName); 399198090Srdivacky if (OSName.empty()) return; 400198090Srdivacky 401198090Srdivacky // Handle minor version: 10.4.9 -> darwin8.9. 402198090Srdivacky if (OSName[0] != '.') 403198090Srdivacky return; 404198090Srdivacky 405198090Srdivacky // Eat the '.'. 406198090Srdivacky OSName = OSName.substr(1); 407198090Srdivacky 408198090Srdivacky if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 409198090Srdivacky return; 410198090Srdivacky 411198090Srdivacky Min = EatNumber(OSName); 412198090Srdivacky if (OSName.empty()) return; 413198090Srdivacky 414198090Srdivacky // Handle revision darwin8.9.1 415198090Srdivacky if (OSName[0] != '.') 416198090Srdivacky return; 417198090Srdivacky 418198090Srdivacky // Eat the '.'. 419198090Srdivacky OSName = OSName.substr(1); 420198090Srdivacky 421198090Srdivacky if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 422198090Srdivacky return; 423198090Srdivacky 424198090Srdivacky Revision = EatNumber(OSName); 425193323Sed} 426193323Sed 427198090Srdivackyvoid Triple::setTriple(const Twine &Str) { 428198090Srdivacky Data = Str.str(); 429193323Sed Arch = InvalidArch; 430193323Sed} 431193323Sed 432193323Sedvoid Triple::setArch(ArchType Kind) { 433193323Sed setArchName(getArchTypeName(Kind)); 434193323Sed} 435193323Sed 436193323Sedvoid Triple::setVendor(VendorType Kind) { 437193323Sed setVendorName(getVendorTypeName(Kind)); 438193323Sed} 439193323Sed 440193323Sedvoid Triple::setOS(OSType Kind) { 441193323Sed setOSName(getOSTypeName(Kind)); 442193323Sed} 443193323Sed 444199481Srdivackyvoid Triple::setArchName(StringRef Str) { 445198090Srdivacky // Work around a miscompilation bug for Twines in gcc 4.0.3. 446198090Srdivacky SmallString<64> Triple; 447198090Srdivacky Triple += Str; 448198090Srdivacky Triple += "-"; 449198090Srdivacky Triple += getVendorName(); 450198090Srdivacky Triple += "-"; 451198090Srdivacky Triple += getOSAndEnvironmentName(); 452198090Srdivacky setTriple(Triple.str()); 453193323Sed} 454193323Sed 455199481Srdivackyvoid Triple::setVendorName(StringRef Str) { 456193323Sed setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 457193323Sed} 458193323Sed 459199481Srdivackyvoid Triple::setOSName(StringRef Str) { 460193323Sed if (hasEnvironment()) 461193323Sed setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 462193323Sed "-" + getEnvironmentName()); 463193323Sed else 464193323Sed setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 465193323Sed} 466193323Sed 467199481Srdivackyvoid Triple::setEnvironmentName(StringRef Str) { 468199481Srdivacky setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 469193323Sed "-" + Str); 470193323Sed} 471193323Sed 472199481Srdivackyvoid Triple::setOSAndEnvironmentName(StringRef Str) { 473193323Sed setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 474193323Sed} 475