LLVM API Documentation

Triple.cpp
Go to the documentation of this file.
00001 //===--- Triple.cpp - Target triple helper class --------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "llvm/ADT/Triple.h"
00011 #include "llvm/ADT/STLExtras.h"
00012 #include "llvm/ADT/SmallString.h"
00013 #include "llvm/ADT/StringSwitch.h"
00014 #include "llvm/Support/ErrorHandling.h"
00015 #include <cstring>
00016 using namespace llvm;
00017 
00018 const char *Triple::getArchTypeName(ArchType Kind) {
00019   switch (Kind) {
00020   case UnknownArch: return "unknown";
00021 
00022   case aarch64:     return "aarch64";
00023   case aarch64_be:  return "aarch64_be";
00024   case arm:         return "arm";
00025   case armeb:       return "armeb";
00026   case hexagon:     return "hexagon";
00027   case mips:        return "mips";
00028   case mipsel:      return "mipsel";
00029   case mips64:      return "mips64";
00030   case mips64el:    return "mips64el";
00031   case msp430:      return "msp430";
00032   case ppc64:       return "powerpc64";
00033   case ppc64le:     return "powerpc64le";
00034   case ppc:         return "powerpc";
00035   case r600:        return "r600";
00036   case sparc:       return "sparc";
00037   case sparcv9:     return "sparcv9";
00038   case systemz:     return "s390x";
00039   case tce:         return "tce";
00040   case thumb:       return "thumb";
00041   case thumbeb:     return "thumbeb";
00042   case x86:         return "i386";
00043   case x86_64:      return "x86_64";
00044   case xcore:       return "xcore";
00045   case nvptx:       return "nvptx";
00046   case nvptx64:     return "nvptx64";
00047   case le32:        return "le32";
00048   case le64:        return "le64";
00049   case amdil:       return "amdil";
00050   case spir:        return "spir";
00051   case spir64:      return "spir64";
00052   case kalimba:     return "kalimba";
00053   }
00054 
00055   llvm_unreachable("Invalid ArchType!");
00056 }
00057 
00058 const char *Triple::getArchTypePrefix(ArchType Kind) {
00059   switch (Kind) {
00060   default:
00061     return nullptr;
00062 
00063   case aarch64:
00064   case aarch64_be:  return "aarch64";
00065 
00066   case arm:
00067   case armeb:
00068   case thumb:
00069   case thumbeb:     return "arm";
00070 
00071   case ppc64:
00072   case ppc64le:
00073   case ppc:         return "ppc";
00074 
00075   case mips:
00076   case mipsel:
00077   case mips64:
00078   case mips64el:    return "mips";
00079 
00080   case hexagon:     return "hexagon";
00081 
00082   case r600:        return "r600";
00083 
00084   case sparcv9:
00085   case sparc:       return "sparc";
00086 
00087   case systemz:     return "systemz";
00088 
00089   case x86:
00090   case x86_64:      return "x86";
00091 
00092   case xcore:       return "xcore";
00093 
00094   case nvptx:       return "nvptx";
00095   case nvptx64:     return "nvptx";
00096 
00097   case le32:        return "le32";
00098   case le64:        return "le64";
00099   case amdil:       return "amdil";
00100   case spir:        return "spir";
00101   case spir64:      return "spir";
00102   case kalimba:     return "kalimba";
00103   }
00104 }
00105 
00106 const char *Triple::getVendorTypeName(VendorType Kind) {
00107   switch (Kind) {
00108   case UnknownVendor: return "unknown";
00109 
00110   case Apple: return "apple";
00111   case PC: return "pc";
00112   case SCEI: return "scei";
00113   case BGP: return "bgp";
00114   case BGQ: return "bgq";
00115   case Freescale: return "fsl";
00116   case IBM: return "ibm";
00117   case ImaginationTechnologies: return "img";
00118   case MipsTechnologies: return "mti";
00119   case NVIDIA: return "nvidia";
00120   case CSR: return "csr";
00121   }
00122 
00123   llvm_unreachable("Invalid VendorType!");
00124 }
00125 
00126 const char *Triple::getOSTypeName(OSType Kind) {
00127   switch (Kind) {
00128   case UnknownOS: return "unknown";
00129 
00130   case Darwin: return "darwin";
00131   case DragonFly: return "dragonfly";
00132   case FreeBSD: return "freebsd";
00133   case IOS: return "ios";
00134   case KFreeBSD: return "kfreebsd";
00135   case Linux: return "linux";
00136   case Lv2: return "lv2";
00137   case MacOSX: return "macosx";
00138   case NetBSD: return "netbsd";
00139   case OpenBSD: return "openbsd";
00140   case Solaris: return "solaris";
00141   case Win32: return "windows";
00142   case Haiku: return "haiku";
00143   case Minix: return "minix";
00144   case RTEMS: return "rtems";
00145   case NaCl: return "nacl";
00146   case CNK: return "cnk";
00147   case Bitrig: return "bitrig";
00148   case AIX: return "aix";
00149   case CUDA: return "cuda";
00150   case NVCL: return "nvcl";
00151   }
00152 
00153   llvm_unreachable("Invalid OSType");
00154 }
00155 
00156 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
00157   switch (Kind) {
00158   case UnknownEnvironment: return "unknown";
00159   case GNU: return "gnu";
00160   case GNUEABIHF: return "gnueabihf";
00161   case GNUEABI: return "gnueabi";
00162   case GNUX32: return "gnux32";
00163   case CODE16: return "code16";
00164   case EABI: return "eabi";
00165   case EABIHF: return "eabihf";
00166   case Android: return "android";
00167   case MSVC: return "msvc";
00168   case Itanium: return "itanium";
00169   case Cygnus: return "cygnus";
00170   }
00171 
00172   llvm_unreachable("Invalid EnvironmentType!");
00173 }
00174 
00175 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
00176   return StringSwitch<Triple::ArchType>(Name)
00177     .Case("aarch64", aarch64)
00178     .Case("aarch64_be", aarch64_be)
00179     .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
00180     .Case("arm", arm)
00181     .Case("armeb", armeb)
00182     .Case("mips", mips)
00183     .Case("mipsel", mipsel)
00184     .Case("mips64", mips64)
00185     .Case("mips64el", mips64el)
00186     .Case("msp430", msp430)
00187     .Case("ppc64", ppc64)
00188     .Case("ppc32", ppc)
00189     .Case("ppc", ppc)
00190     .Case("ppc64le", ppc64le)
00191     .Case("r600", r600)
00192     .Case("hexagon", hexagon)
00193     .Case("sparc", sparc)
00194     .Case("sparcv9", sparcv9)
00195     .Case("systemz", systemz)
00196     .Case("tce", tce)
00197     .Case("thumb", thumb)
00198     .Case("thumbeb", thumbeb)
00199     .Case("x86", x86)
00200     .Case("x86-64", x86_64)
00201     .Case("xcore", xcore)
00202     .Case("nvptx", nvptx)
00203     .Case("nvptx64", nvptx64)
00204     .Case("le32", le32)
00205     .Case("le64", le64)
00206     .Case("amdil", amdil)
00207     .Case("spir", spir)
00208     .Case("spir64", spir64)
00209     .Case("kalimba", kalimba)
00210     .Default(UnknownArch);
00211 }
00212 
00213 static Triple::ArchType parseArch(StringRef ArchName) {
00214   return StringSwitch<Triple::ArchType>(ArchName)
00215     .Cases("i386", "i486", "i586", "i686", Triple::x86)
00216     // FIXME: Do we need to support these?
00217     .Cases("i786", "i886", "i986", Triple::x86)
00218     .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
00219     .Case("powerpc", Triple::ppc)
00220     .Cases("powerpc64", "ppu", Triple::ppc64)
00221     .Case("powerpc64le", Triple::ppc64le)
00222     .Case("aarch64", Triple::aarch64)
00223     .Case("aarch64_be", Triple::aarch64_be)
00224     .Case("arm64", Triple::aarch64)
00225     .Cases("arm", "xscale", Triple::arm)
00226     // FIXME: It would be good to replace these with explicit names for all the
00227     // various suffixes supported.
00228     .StartsWith("armv", Triple::arm)
00229     .Case("armeb", Triple::armeb)
00230     .StartsWith("armebv", Triple::armeb)
00231     .Case("thumb", Triple::thumb)
00232     .StartsWith("thumbv", Triple::thumb)
00233     .Case("thumbeb", Triple::thumbeb)
00234     .StartsWith("thumbebv", Triple::thumbeb)
00235     .Case("msp430", Triple::msp430)
00236     .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
00237     .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
00238     .Cases("mips64", "mips64eb", Triple::mips64)
00239     .Case("mips64el", Triple::mips64el)
00240     .Case("r600", Triple::r600)
00241     .Case("hexagon", Triple::hexagon)
00242     .Case("s390x", Triple::systemz)
00243     .Case("sparc", Triple::sparc)
00244     .Cases("sparcv9", "sparc64", Triple::sparcv9)
00245     .Case("tce", Triple::tce)
00246     .Case("xcore", Triple::xcore)
00247     .Case("nvptx", Triple::nvptx)
00248     .Case("nvptx64", Triple::nvptx64)
00249     .Case("le32", Triple::le32)
00250     .Case("le64", Triple::le64)
00251     .Case("amdil", Triple::amdil)
00252     .Case("spir", Triple::spir)
00253     .Case("spir64", Triple::spir64)
00254     .StartsWith("kalimba", Triple::kalimba)
00255     .Default(Triple::UnknownArch);
00256 }
00257 
00258 static Triple::VendorType parseVendor(StringRef VendorName) {
00259   return StringSwitch<Triple::VendorType>(VendorName)
00260     .Case("apple", Triple::Apple)
00261     .Case("pc", Triple::PC)
00262     .Case("scei", Triple::SCEI)
00263     .Case("bgp", Triple::BGP)
00264     .Case("bgq", Triple::BGQ)
00265     .Case("fsl", Triple::Freescale)
00266     .Case("ibm", Triple::IBM)
00267     .Case("img", Triple::ImaginationTechnologies)
00268     .Case("mti", Triple::MipsTechnologies)
00269     .Case("nvidia", Triple::NVIDIA)
00270     .Case("csr", Triple::CSR)
00271     .Default(Triple::UnknownVendor);
00272 }
00273 
00274 static Triple::OSType parseOS(StringRef OSName) {
00275   return StringSwitch<Triple::OSType>(OSName)
00276     .StartsWith("darwin", Triple::Darwin)
00277     .StartsWith("dragonfly", Triple::DragonFly)
00278     .StartsWith("freebsd", Triple::FreeBSD)
00279     .StartsWith("ios", Triple::IOS)
00280     .StartsWith("kfreebsd", Triple::KFreeBSD)
00281     .StartsWith("linux", Triple::Linux)
00282     .StartsWith("lv2", Triple::Lv2)
00283     .StartsWith("macosx", Triple::MacOSX)
00284     .StartsWith("netbsd", Triple::NetBSD)
00285     .StartsWith("openbsd", Triple::OpenBSD)
00286     .StartsWith("solaris", Triple::Solaris)
00287     .StartsWith("win32", Triple::Win32)
00288     .StartsWith("windows", Triple::Win32)
00289     .StartsWith("haiku", Triple::Haiku)
00290     .StartsWith("minix", Triple::Minix)
00291     .StartsWith("rtems", Triple::RTEMS)
00292     .StartsWith("nacl", Triple::NaCl)
00293     .StartsWith("cnk", Triple::CNK)
00294     .StartsWith("bitrig", Triple::Bitrig)
00295     .StartsWith("aix", Triple::AIX)
00296     .StartsWith("cuda", Triple::CUDA)
00297     .StartsWith("nvcl", Triple::NVCL)
00298     .Default(Triple::UnknownOS);
00299 }
00300 
00301 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
00302   return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
00303     .StartsWith("eabihf", Triple::EABIHF)
00304     .StartsWith("eabi", Triple::EABI)
00305     .StartsWith("gnueabihf", Triple::GNUEABIHF)
00306     .StartsWith("gnueabi", Triple::GNUEABI)
00307     .StartsWith("gnux32", Triple::GNUX32)
00308     .StartsWith("code16", Triple::CODE16)
00309     .StartsWith("gnu", Triple::GNU)
00310     .StartsWith("android", Triple::Android)
00311     .StartsWith("msvc", Triple::MSVC)
00312     .StartsWith("itanium", Triple::Itanium)
00313     .StartsWith("cygnus", Triple::Cygnus)
00314     .Default(Triple::UnknownEnvironment);
00315 }
00316 
00317 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
00318   return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
00319     .EndsWith("coff", Triple::COFF)
00320     .EndsWith("elf", Triple::ELF)
00321     .EndsWith("macho", Triple::MachO)
00322     .Default(Triple::UnknownObjectFormat);
00323 }
00324 
00325 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
00326   return StringSwitch<Triple::SubArchType>(SubArchName)
00327     .EndsWith("v8", Triple::ARMSubArch_v8)
00328     .EndsWith("v8a", Triple::ARMSubArch_v8)
00329     .EndsWith("v7", Triple::ARMSubArch_v7)
00330     .EndsWith("v7a", Triple::ARMSubArch_v7)
00331     .EndsWith("v7em", Triple::ARMSubArch_v7em)
00332     .EndsWith("v7l", Triple::ARMSubArch_v7)
00333     .EndsWith("v7m", Triple::ARMSubArch_v7m)
00334     .EndsWith("v7r", Triple::ARMSubArch_v7)
00335     .EndsWith("v7s", Triple::ARMSubArch_v7s)
00336     .EndsWith("v6", Triple::ARMSubArch_v6)
00337     .EndsWith("v6m", Triple::ARMSubArch_v6m)
00338     .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
00339     .EndsWith("v5", Triple::ARMSubArch_v5)
00340     .EndsWith("v5e", Triple::ARMSubArch_v5)
00341     .EndsWith("v5t", Triple::ARMSubArch_v5)
00342     .EndsWith("v5te", Triple::ARMSubArch_v5te)
00343     .EndsWith("v4t", Triple::ARMSubArch_v4t)
00344     .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
00345     .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
00346     .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
00347     .Default(Triple::NoSubArch);
00348 }
00349 
00350 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
00351   switch (Kind) {
00352   case Triple::UnknownObjectFormat: return "";
00353   case Triple::COFF: return "coff";
00354   case Triple::ELF: return "elf";
00355   case Triple::MachO: return "macho";
00356   }
00357   llvm_unreachable("unknown object format type");
00358 }
00359 
00360 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
00361   if (T.isOSDarwin())
00362     return Triple::MachO;
00363   else if (T.isOSWindows())
00364     return Triple::COFF;
00365   return Triple::ELF;
00366 }
00367 
00368 /// \brief Construct a triple from the string representation provided.
00369 ///
00370 /// This stores the string representation and parses the various pieces into
00371 /// enum members.
00372 Triple::Triple(const Twine &Str)
00373     : Data(Str.str()),
00374       Arch(parseArch(getArchName())),
00375       SubArch(parseSubArch(getArchName())),
00376       Vendor(parseVendor(getVendorName())),
00377       OS(parseOS(getOSName())),
00378       Environment(parseEnvironment(getEnvironmentName())),
00379       ObjectFormat(parseFormat(getEnvironmentName())) {
00380   if (ObjectFormat == Triple::UnknownObjectFormat)
00381     ObjectFormat = getDefaultFormat(*this);
00382 }
00383 
00384 /// \brief Construct a triple from string representations of the architecture,
00385 /// vendor, and OS.
00386 ///
00387 /// This joins each argument into a canonical string representation and parses
00388 /// them into enum members. It leaves the environment unknown and omits it from
00389 /// the string representation.
00390 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
00391     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
00392       Arch(parseArch(ArchStr.str())),
00393       SubArch(parseSubArch(ArchStr.str())),
00394       Vendor(parseVendor(VendorStr.str())),
00395       OS(parseOS(OSStr.str())),
00396       Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
00397   ObjectFormat = getDefaultFormat(*this);
00398 }
00399 
00400 /// \brief Construct a triple from string representations of the architecture,
00401 /// vendor, OS, and environment.
00402 ///
00403 /// This joins each argument into a canonical string representation and parses
00404 /// them into enum members.
00405 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
00406                const Twine &EnvironmentStr)
00407     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
00408             EnvironmentStr).str()),
00409       Arch(parseArch(ArchStr.str())),
00410       SubArch(parseSubArch(ArchStr.str())),
00411       Vendor(parseVendor(VendorStr.str())),
00412       OS(parseOS(OSStr.str())),
00413       Environment(parseEnvironment(EnvironmentStr.str())),
00414       ObjectFormat(parseFormat(EnvironmentStr.str())) {
00415   if (ObjectFormat == Triple::UnknownObjectFormat)
00416     ObjectFormat = getDefaultFormat(*this);
00417 }
00418 
00419 std::string Triple::normalize(StringRef Str) {
00420   bool IsMinGW32 = false;
00421   bool IsCygwin = false;
00422 
00423   // Parse into components.
00424   SmallVector<StringRef, 4> Components;
00425   Str.split(Components, "-");
00426 
00427   // If the first component corresponds to a known architecture, preferentially
00428   // use it for the architecture.  If the second component corresponds to a
00429   // known vendor, preferentially use it for the vendor, etc.  This avoids silly
00430   // component movement when a component parses as (eg) both a valid arch and a
00431   // valid os.
00432   ArchType Arch = UnknownArch;
00433   if (Components.size() > 0)
00434     Arch = parseArch(Components[0]);
00435   VendorType Vendor = UnknownVendor;
00436   if (Components.size() > 1)
00437     Vendor = parseVendor(Components[1]);
00438   OSType OS = UnknownOS;
00439   if (Components.size() > 2) {
00440     OS = parseOS(Components[2]);
00441     IsCygwin = Components[2].startswith("cygwin");
00442     IsMinGW32 = Components[2].startswith("mingw");
00443   }
00444   EnvironmentType Environment = UnknownEnvironment;
00445   if (Components.size() > 3)
00446     Environment = parseEnvironment(Components[3]);
00447   ObjectFormatType ObjectFormat = UnknownObjectFormat;
00448   if (Components.size() > 4)
00449     ObjectFormat = parseFormat(Components[4]);
00450 
00451   // Note which components are already in their final position.  These will not
00452   // be moved.
00453   bool Found[4];
00454   Found[0] = Arch != UnknownArch;
00455   Found[1] = Vendor != UnknownVendor;
00456   Found[2] = OS != UnknownOS;
00457   Found[3] = Environment != UnknownEnvironment;
00458 
00459   // If they are not there already, permute the components into their canonical
00460   // positions by seeing if they parse as a valid architecture, and if so moving
00461   // the component to the architecture position etc.
00462   for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
00463     if (Found[Pos])
00464       continue; // Already in the canonical position.
00465 
00466     for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
00467       // Do not reparse any components that already matched.
00468       if (Idx < array_lengthof(Found) && Found[Idx])
00469         continue;
00470 
00471       // Does this component parse as valid for the target position?
00472       bool Valid = false;
00473       StringRef Comp = Components[Idx];
00474       switch (Pos) {
00475       default: llvm_unreachable("unexpected component type!");
00476       case 0:
00477         Arch = parseArch(Comp);
00478         Valid = Arch != UnknownArch;
00479         break;
00480       case 1:
00481         Vendor = parseVendor(Comp);
00482         Valid = Vendor != UnknownVendor;
00483         break;
00484       case 2:
00485         OS = parseOS(Comp);
00486         IsCygwin = Comp.startswith("cygwin");
00487         IsMinGW32 = Comp.startswith("mingw");
00488         Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
00489         break;
00490       case 3:
00491         Environment = parseEnvironment(Comp);
00492         Valid = Environment != UnknownEnvironment;
00493         if (!Valid) {
00494           ObjectFormat = parseFormat(Comp);
00495           Valid = ObjectFormat != UnknownObjectFormat;
00496         }
00497         break;
00498       }
00499       if (!Valid)
00500         continue; // Nope, try the next component.
00501 
00502       // Move the component to the target position, pushing any non-fixed
00503       // components that are in the way to the right.  This tends to give
00504       // good results in the common cases of a forgotten vendor component
00505       // or a wrongly positioned environment.
00506       if (Pos < Idx) {
00507         // Insert left, pushing the existing components to the right.  For
00508         // example, a-b-i386 -> i386-a-b when moving i386 to the front.
00509         StringRef CurrentComponent(""); // The empty component.
00510         // Replace the component we are moving with an empty component.
00511         std::swap(CurrentComponent, Components[Idx]);
00512         // Insert the component being moved at Pos, displacing any existing
00513         // components to the right.
00514         for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
00515           // Skip over any fixed components.
00516           while (i < array_lengthof(Found) && Found[i])
00517             ++i;
00518           // Place the component at the new position, getting the component
00519           // that was at this position - it will be moved right.
00520           std::swap(CurrentComponent, Components[i]);
00521         }
00522       } else if (Pos > Idx) {
00523         // Push right by inserting empty components until the component at Idx
00524         // reaches the target position Pos.  For example, pc-a -> -pc-a when
00525         // moving pc to the second position.
00526         do {
00527           // Insert one empty component at Idx.
00528           StringRef CurrentComponent(""); // The empty component.
00529           for (unsigned i = Idx; i < Components.size();) {
00530             // Place the component at the new position, getting the component
00531             // that was at this position - it will be moved right.
00532             std::swap(CurrentComponent, Components[i]);
00533             // If it was placed on top of an empty component then we are done.
00534             if (CurrentComponent.empty())
00535               break;
00536             // Advance to the next component, skipping any fixed components.
00537             while (++i < array_lengthof(Found) && Found[i])
00538               ;
00539           }
00540           // The last component was pushed off the end - append it.
00541           if (!CurrentComponent.empty())
00542             Components.push_back(CurrentComponent);
00543 
00544           // Advance Idx to the component's new position.
00545           while (++Idx < array_lengthof(Found) && Found[Idx])
00546             ;
00547         } while (Idx < Pos); // Add more until the final position is reached.
00548       }
00549       assert(Pos < Components.size() && Components[Pos] == Comp &&
00550              "Component moved wrong!");
00551       Found[Pos] = true;
00552       break;
00553     }
00554   }
00555 
00556   // Special case logic goes here.  At this point Arch, Vendor and OS have the
00557   // correct values for the computed components.
00558 
00559   if (OS == Triple::Win32) {
00560     Components.resize(4);
00561     Components[2] = "windows";
00562     if (Environment == UnknownEnvironment) {
00563       if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
00564         Components[3] = "msvc";
00565       else
00566         Components[3] = getObjectFormatTypeName(ObjectFormat);
00567     }
00568   } else if (IsMinGW32) {
00569     Components.resize(4);
00570     Components[2] = "windows";
00571     Components[3] = "gnu";
00572   } else if (IsCygwin) {
00573     Components.resize(4);
00574     Components[2] = "windows";
00575     Components[3] = "cygnus";
00576   }
00577   if (IsMinGW32 || IsCygwin ||
00578       (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
00579     if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
00580       Components.resize(5);
00581       Components[4] = getObjectFormatTypeName(ObjectFormat);
00582     }
00583   }
00584 
00585   // Stick the corrected components back together to form the normalized string.
00586   std::string Normalized;
00587   for (unsigned i = 0, e = Components.size(); i != e; ++i) {
00588     if (i) Normalized += '-';
00589     Normalized += Components[i];
00590   }
00591   return Normalized;
00592 }
00593 
00594 StringRef Triple::getArchName() const {
00595   return StringRef(Data).split('-').first;           // Isolate first component
00596 }
00597 
00598 StringRef Triple::getVendorName() const {
00599   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
00600   return Tmp.split('-').first;                       // Isolate second component
00601 }
00602 
00603 StringRef Triple::getOSName() const {
00604   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
00605   Tmp = Tmp.split('-').second;                       // Strip second component
00606   return Tmp.split('-').first;                       // Isolate third component
00607 }
00608 
00609 StringRef Triple::getEnvironmentName() const {
00610   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
00611   Tmp = Tmp.split('-').second;                       // Strip second component
00612   return Tmp.split('-').second;                      // Strip third component
00613 }
00614 
00615 StringRef Triple::getOSAndEnvironmentName() const {
00616   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
00617   return Tmp.split('-').second;                      // Strip second component
00618 }
00619 
00620 static unsigned EatNumber(StringRef &Str) {
00621   assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
00622   unsigned Result = 0;
00623 
00624   do {
00625     // Consume the leading digit.
00626     Result = Result*10 + (Str[0] - '0');
00627 
00628     // Eat the digit.
00629     Str = Str.substr(1);
00630   } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
00631 
00632   return Result;
00633 }
00634 
00635 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
00636                           unsigned &Micro) const {
00637   StringRef OSName = getOSName();
00638 
00639   // Assume that the OS portion of the triple starts with the canonical name.
00640   StringRef OSTypeName = getOSTypeName(getOS());
00641   if (OSName.startswith(OSTypeName))
00642     OSName = OSName.substr(OSTypeName.size());
00643 
00644   // Any unset version defaults to 0.
00645   Major = Minor = Micro = 0;
00646 
00647   // Parse up to three components.
00648   unsigned *Components[3] = { &Major, &Minor, &Micro };
00649   for (unsigned i = 0; i != 3; ++i) {
00650     if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
00651       break;
00652 
00653     // Consume the leading number.
00654     *Components[i] = EatNumber(OSName);
00655 
00656     // Consume the separator, if present.
00657     if (OSName.startswith("."))
00658       OSName = OSName.substr(1);
00659   }
00660 }
00661 
00662 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
00663                               unsigned &Micro) const {
00664   getOSVersion(Major, Minor, Micro);
00665 
00666   switch (getOS()) {
00667   default: llvm_unreachable("unexpected OS for Darwin triple");
00668   case Darwin:
00669     // Default to darwin8, i.e., MacOSX 10.4.
00670     if (Major == 0)
00671       Major = 8;
00672     // Darwin version numbers are skewed from OS X versions.
00673     if (Major < 4)
00674       return false;
00675     Micro = 0;
00676     Minor = Major - 4;
00677     Major = 10;
00678     break;
00679   case MacOSX:
00680     // Default to 10.4.
00681     if (Major == 0) {
00682       Major = 10;
00683       Minor = 4;
00684     }
00685     if (Major != 10)
00686       return false;
00687     break;
00688   case IOS:
00689     // Ignore the version from the triple.  This is only handled because the
00690     // the clang driver combines OS X and IOS support into a common Darwin
00691     // toolchain that wants to know the OS X version number even when targeting
00692     // IOS.
00693     Major = 10;
00694     Minor = 4;
00695     Micro = 0;
00696     break;
00697   }
00698   return true;
00699 }
00700 
00701 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
00702                            unsigned &Micro) const {
00703   switch (getOS()) {
00704   default: llvm_unreachable("unexpected OS for Darwin triple");
00705   case Darwin:
00706   case MacOSX:
00707     // Ignore the version from the triple.  This is only handled because the
00708     // the clang driver combines OS X and IOS support into a common Darwin
00709     // toolchain that wants to know the iOS version number even when targeting
00710     // OS X.
00711     Major = 5;
00712     Minor = 0;
00713     Micro = 0;
00714     break;
00715   case IOS:
00716     getOSVersion(Major, Minor, Micro);
00717     // Default to 5.0 (or 7.0 for arm64).
00718     if (Major == 0)
00719       Major = (getArch() == aarch64) ? 7 : 5;
00720     break;
00721   }
00722 }
00723 
00724 void Triple::setTriple(const Twine &Str) {
00725   *this = Triple(Str);
00726 }
00727 
00728 void Triple::setArch(ArchType Kind) {
00729   setArchName(getArchTypeName(Kind));
00730 }
00731 
00732 void Triple::setVendor(VendorType Kind) {
00733   setVendorName(getVendorTypeName(Kind));
00734 }
00735 
00736 void Triple::setOS(OSType Kind) {
00737   setOSName(getOSTypeName(Kind));
00738 }
00739 
00740 void Triple::setEnvironment(EnvironmentType Kind) {
00741   setEnvironmentName(getEnvironmentTypeName(Kind));
00742 }
00743 
00744 void Triple::setObjectFormat(ObjectFormatType Kind) {
00745   if (Environment == UnknownEnvironment)
00746     return setEnvironmentName(getObjectFormatTypeName(Kind));
00747 
00748   setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
00749                       getObjectFormatTypeName(Kind)).str());
00750 }
00751 
00752 void Triple::setArchName(StringRef Str) {
00753   // Work around a miscompilation bug for Twines in gcc 4.0.3.
00754   SmallString<64> Triple;
00755   Triple += Str;
00756   Triple += "-";
00757   Triple += getVendorName();
00758   Triple += "-";
00759   Triple += getOSAndEnvironmentName();
00760   setTriple(Triple.str());
00761 }
00762 
00763 void Triple::setVendorName(StringRef Str) {
00764   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
00765 }
00766 
00767 void Triple::setOSName(StringRef Str) {
00768   if (hasEnvironment())
00769     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
00770               "-" + getEnvironmentName());
00771   else
00772     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
00773 }
00774 
00775 void Triple::setEnvironmentName(StringRef Str) {
00776   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
00777             "-" + Str);
00778 }
00779 
00780 void Triple::setOSAndEnvironmentName(StringRef Str) {
00781   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
00782 }
00783 
00784 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
00785   switch (Arch) {
00786   case llvm::Triple::UnknownArch:
00787     return 0;
00788 
00789   case llvm::Triple::msp430:
00790     return 16;
00791 
00792   case llvm::Triple::amdil:
00793   case llvm::Triple::arm:
00794   case llvm::Triple::armeb:
00795   case llvm::Triple::hexagon:
00796   case llvm::Triple::le32:
00797   case llvm::Triple::mips:
00798   case llvm::Triple::mipsel:
00799   case llvm::Triple::nvptx:
00800   case llvm::Triple::ppc:
00801   case llvm::Triple::r600:
00802   case llvm::Triple::sparc:
00803   case llvm::Triple::tce:
00804   case llvm::Triple::thumb:
00805   case llvm::Triple::thumbeb:
00806   case llvm::Triple::x86:
00807   case llvm::Triple::xcore:
00808   case llvm::Triple::spir:
00809   case llvm::Triple::kalimba:
00810     return 32;
00811 
00812   case llvm::Triple::aarch64:
00813   case llvm::Triple::aarch64_be:
00814   case llvm::Triple::le64:
00815   case llvm::Triple::mips64:
00816   case llvm::Triple::mips64el:
00817   case llvm::Triple::nvptx64:
00818   case llvm::Triple::ppc64:
00819   case llvm::Triple::ppc64le:
00820   case llvm::Triple::sparcv9:
00821   case llvm::Triple::systemz:
00822   case llvm::Triple::x86_64:
00823   case llvm::Triple::spir64:
00824     return 64;
00825   }
00826   llvm_unreachable("Invalid architecture value");
00827 }
00828 
00829 bool Triple::isArch64Bit() const {
00830   return getArchPointerBitWidth(getArch()) == 64;
00831 }
00832 
00833 bool Triple::isArch32Bit() const {
00834   return getArchPointerBitWidth(getArch()) == 32;
00835 }
00836 
00837 bool Triple::isArch16Bit() const {
00838   return getArchPointerBitWidth(getArch()) == 16;
00839 }
00840 
00841 Triple Triple::get32BitArchVariant() const {
00842   Triple T(*this);
00843   switch (getArch()) {
00844   case Triple::UnknownArch:
00845   case Triple::aarch64:
00846   case Triple::aarch64_be:
00847   case Triple::msp430:
00848   case Triple::systemz:
00849   case Triple::ppc64le:
00850     T.setArch(UnknownArch);
00851     break;
00852 
00853   case Triple::amdil:
00854   case Triple::spir:
00855   case Triple::arm:
00856   case Triple::armeb:
00857   case Triple::hexagon:
00858   case Triple::kalimba:
00859   case Triple::le32:
00860   case Triple::mips:
00861   case Triple::mipsel:
00862   case Triple::nvptx:
00863   case Triple::ppc:
00864   case Triple::r600:
00865   case Triple::sparc:
00866   case Triple::tce:
00867   case Triple::thumb:
00868   case Triple::thumbeb:
00869   case Triple::x86:
00870   case Triple::xcore:
00871     // Already 32-bit.
00872     break;
00873 
00874   case Triple::le64:      T.setArch(Triple::le32);    break;
00875   case Triple::mips64:    T.setArch(Triple::mips);    break;
00876   case Triple::mips64el:  T.setArch(Triple::mipsel);  break;
00877   case Triple::nvptx64:   T.setArch(Triple::nvptx);   break;
00878   case Triple::ppc64:     T.setArch(Triple::ppc);     break;
00879   case Triple::sparcv9:   T.setArch(Triple::sparc);   break;
00880   case Triple::x86_64:    T.setArch(Triple::x86);     break;
00881   case Triple::spir64:    T.setArch(Triple::spir);    break;
00882   }
00883   return T;
00884 }
00885 
00886 Triple Triple::get64BitArchVariant() const {
00887   Triple T(*this);
00888   switch (getArch()) {
00889   case Triple::UnknownArch:
00890   case Triple::amdil:
00891   case Triple::arm:
00892   case Triple::armeb:
00893   case Triple::hexagon:
00894   case Triple::kalimba:
00895   case Triple::msp430:
00896   case Triple::r600:
00897   case Triple::tce:
00898   case Triple::thumb:
00899   case Triple::thumbeb:
00900   case Triple::xcore:
00901     T.setArch(UnknownArch);
00902     break;
00903 
00904   case Triple::aarch64:
00905   case Triple::aarch64_be:
00906   case Triple::le64:
00907   case Triple::mips64:
00908   case Triple::mips64el:
00909   case Triple::nvptx64:
00910   case Triple::ppc64:
00911   case Triple::ppc64le:
00912   case Triple::sparcv9:
00913   case Triple::spir64:
00914   case Triple::systemz:
00915   case Triple::x86_64:
00916     // Already 64-bit.
00917     break;
00918 
00919   case Triple::le32:    T.setArch(Triple::le64);      break;
00920   case Triple::mips:    T.setArch(Triple::mips64);    break;
00921   case Triple::mipsel:  T.setArch(Triple::mips64el);  break;
00922   case Triple::nvptx:   T.setArch(Triple::nvptx64);   break;
00923   case Triple::ppc:     T.setArch(Triple::ppc64);     break;
00924   case Triple::sparc:   T.setArch(Triple::sparcv9);   break;
00925   case Triple::x86:     T.setArch(Triple::x86_64);    break;
00926   case Triple::spir:    T.setArch(Triple::spir64);    break;
00927   }
00928   return T;
00929 }
00930 
00931 // FIXME: tblgen this.
00932 const char *Triple::getARMCPUForArch(StringRef MArch) const {
00933   if (MArch.empty())
00934     MArch = getArchName();
00935 
00936   switch (getOS()) {
00937   case llvm::Triple::FreeBSD:
00938   case llvm::Triple::NetBSD:
00939     if (MArch == "armv6")
00940       return "arm1176jzf-s";
00941     break;
00942   case llvm::Triple::Win32:
00943     // FIXME: this is invalid for WindowsCE
00944     return "cortex-a9";
00945   default:
00946     break;
00947   }
00948 
00949   const char *result = nullptr;
00950   size_t offset = StringRef::npos;
00951   if (MArch.startswith("arm"))
00952     offset = 3;
00953   if (MArch.startswith("thumb"))
00954     offset = 5;
00955   if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
00956     offset += 2;
00957   if (offset != StringRef::npos)
00958     result = llvm::StringSwitch<const char *>(MArch.substr(offset))
00959       .Cases("v2", "v2a", "arm2")
00960       .Case("v3", "arm6")
00961       .Case("v3m", "arm7m")
00962       .Case("v4", "strongarm")
00963       .Case("v4t", "arm7tdmi")
00964       .Cases("v5", "v5t", "arm10tdmi")
00965       .Cases("v5e", "v5te", "arm1022e")
00966       .Case("v5tej", "arm926ej-s")
00967       .Cases("v6", "v6k", "arm1136jf-s")
00968       .Case("v6j", "arm1136j-s")
00969       .Cases("v6z", "v6zk", "arm1176jzf-s")
00970       .Case("v6t2", "arm1156t2-s")
00971       .Cases("v6m", "v6-m", "cortex-m0")
00972       .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
00973       .Cases("v7s", "v7-s", "swift")
00974       .Cases("v7r", "v7-r", "cortex-r4")
00975       .Cases("v7m", "v7-m", "cortex-m3")
00976       .Cases("v7em", "v7e-m", "cortex-m4")
00977       .Cases("v8", "v8a", "v8-a", "cortex-a53")
00978       .Default(nullptr);
00979   else
00980     result = llvm::StringSwitch<const char *>(MArch)
00981       .Case("ep9312", "ep9312")
00982       .Case("iwmmxt", "iwmmxt")
00983       .Case("xscale", "xscale")
00984       .Default(nullptr);
00985 
00986   if (result)
00987     return result;
00988 
00989   // If all else failed, return the most base CPU with thumb interworking
00990   // supported by LLVM.
00991   // FIXME: Should warn once that we're falling back.
00992   switch (getOS()) {
00993   case llvm::Triple::NetBSD:
00994     switch (getEnvironment()) {
00995     case llvm::Triple::GNUEABIHF:
00996     case llvm::Triple::GNUEABI:
00997     case llvm::Triple::EABIHF:
00998     case llvm::Triple::EABI:
00999       return "arm926ej-s";
01000     default:
01001       return "strongarm";
01002     }
01003   default:
01004     switch (getEnvironment()) {
01005     case llvm::Triple::EABIHF:
01006     case llvm::Triple::GNUEABIHF:
01007       return "arm1176jzf-s";
01008     default:
01009       return "arm7tdmi";
01010     }
01011   }
01012 }