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 arm:     return "arm";
00024   case hexagon: return "hexagon";
00025   case mips:    return "mips";
00026   case mipsel:  return "mipsel";
00027   case mips64:  return "mips64";
00028   case mips64el:return "mips64el";
00029   case msp430:  return "msp430";
00030   case ppc64:   return "powerpc64";
00031   case ppc:     return "powerpc";
00032   case r600:    return "r600";
00033   case sparc:   return "sparc";
00034   case sparcv9: return "sparcv9";
00035   case systemz: return "s390x";
00036   case tce:     return "tce";
00037   case thumb:   return "thumb";
00038   case x86:     return "i386";
00039   case x86_64:  return "x86_64";
00040   case xcore:   return "xcore";
00041   case mblaze:  return "mblaze";
00042   case nvptx:   return "nvptx";
00043   case nvptx64: return "nvptx64";
00044   case le32:    return "le32";
00045   case amdil:   return "amdil";
00046   case spir:    return "spir";
00047   case spir64:  return "spir64";
00048   }
00049 
00050   llvm_unreachable("Invalid ArchType!");
00051 }
00052 
00053 const char *Triple::getArchTypePrefix(ArchType Kind) {
00054   switch (Kind) {
00055   default:
00056     return 0;
00057 
00058   case aarch64: return "aarch64";
00059 
00060   case arm:
00061   case thumb:   return "arm";
00062 
00063   case ppc64:
00064   case ppc:     return "ppc";
00065 
00066   case mblaze:  return "mblaze";
00067 
00068   case mips:
00069   case mipsel:
00070   case mips64:
00071   case mips64el:return "mips";
00072 
00073   case hexagon: return "hexagon";
00074 
00075   case r600:    return "r600";
00076 
00077   case sparcv9:
00078   case sparc:   return "sparc";
00079 
00080   case systemz: return "systemz";
00081 
00082   case x86:
00083   case x86_64:  return "x86";
00084 
00085   case xcore:   return "xcore";
00086 
00087   case nvptx:   return "nvptx";
00088   case nvptx64: return "nvptx";
00089   case le32:    return "le32";
00090   case amdil:   return "amdil";
00091   case spir:    return "spir";
00092   case spir64:  return "spir";
00093   }
00094 }
00095 
00096 const char *Triple::getVendorTypeName(VendorType Kind) {
00097   switch (Kind) {
00098   case UnknownVendor: return "unknown";
00099 
00100   case Apple: return "apple";
00101   case PC: return "pc";
00102   case SCEI: return "scei";
00103   case BGP: return "bgp";
00104   case BGQ: return "bgq";
00105   case Freescale: return "fsl";
00106   case IBM: return "ibm";
00107   }
00108 
00109   llvm_unreachable("Invalid VendorType!");
00110 }
00111 
00112 const char *Triple::getOSTypeName(OSType Kind) {
00113   switch (Kind) {
00114   case UnknownOS: return "unknown";
00115 
00116   case AuroraUX: return "auroraux";
00117   case Cygwin: return "cygwin";
00118   case Darwin: return "darwin";
00119   case DragonFly: return "dragonfly";
00120   case FreeBSD: return "freebsd";
00121   case IOS: return "ios";
00122   case KFreeBSD: return "kfreebsd";
00123   case Linux: return "linux";
00124   case Lv2: return "lv2";
00125   case MacOSX: return "macosx";
00126   case MinGW32: return "mingw32";
00127   case NetBSD: return "netbsd";
00128   case OpenBSD: return "openbsd";
00129   case Solaris: return "solaris";
00130   case Win32: return "win32";
00131   case Haiku: return "haiku";
00132   case Minix: return "minix";
00133   case RTEMS: return "rtems";
00134   case NaCl: return "nacl";
00135   case CNK: return "cnk";
00136   case Bitrig: return "bitrig";
00137   case AIX: return "aix";
00138   }
00139 
00140   llvm_unreachable("Invalid OSType");
00141 }
00142 
00143 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
00144   switch (Kind) {
00145   case UnknownEnvironment: return "unknown";
00146   case GNU: return "gnu";
00147   case GNUEABIHF: return "gnueabihf";
00148   case GNUEABI: return "gnueabi";
00149   case GNUX32: return "gnux32";
00150   case EABI: return "eabi";
00151   case MachO: return "macho";
00152   case Android: return "android";
00153   case ELF: return "elf";
00154   }
00155 
00156   llvm_unreachable("Invalid EnvironmentType!");
00157 }
00158 
00159 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
00160   return StringSwitch<Triple::ArchType>(Name)
00161     .Case("aarch64", aarch64)
00162     .Case("arm", arm)
00163     .Case("mips", mips)
00164     .Case("mipsel", mipsel)
00165     .Case("mips64", mips64)
00166     .Case("mips64el", mips64el)
00167     .Case("msp430", msp430)
00168     .Case("ppc64", ppc64)
00169     .Case("ppc32", ppc)
00170     .Case("ppc", ppc)
00171     .Case("mblaze", mblaze)
00172     .Case("r600", r600)
00173     .Case("hexagon", hexagon)
00174     .Case("sparc", sparc)
00175     .Case("sparcv9", sparcv9)
00176     .Case("systemz", systemz)
00177     .Case("tce", tce)
00178     .Case("thumb", thumb)
00179     .Case("x86", x86)
00180     .Case("x86-64", x86_64)
00181     .Case("xcore", xcore)
00182     .Case("nvptx", nvptx)
00183     .Case("nvptx64", nvptx64)
00184     .Case("le32", le32)
00185     .Case("amdil", amdil)
00186     .Case("spir", spir)
00187     .Case("spir64", spir64)
00188     .Default(UnknownArch);
00189 }
00190 
00191 // Returns architecture name that is understood by the target assembler.
00192 const char *Triple::getArchNameForAssembler() {
00193   if (!isOSDarwin() && getVendor() != Triple::Apple)
00194     return NULL;
00195 
00196   return StringSwitch<const char*>(getArchName())
00197     .Case("i386", "i386")
00198     .Case("x86_64", "x86_64")
00199     .Case("powerpc", "ppc")
00200     .Case("powerpc64", "ppc64")
00201     .Cases("mblaze", "microblaze", "mblaze")
00202     .Case("arm", "arm")
00203     .Cases("armv4t", "thumbv4t", "armv4t")
00204     .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
00205     .Cases("armv6", "thumbv6", "armv6")
00206     .Cases("armv7", "thumbv7", "armv7")
00207     .Case("r600", "r600")
00208     .Case("nvptx", "nvptx")
00209     .Case("nvptx64", "nvptx64")
00210     .Case("le32", "le32")
00211     .Case("amdil", "amdil")
00212     .Case("spir", "spir")
00213     .Case("spir64", "spir64")
00214     .Default(NULL);
00215 }
00216 
00217 static Triple::ArchType parseArch(StringRef ArchName) {
00218   return StringSwitch<Triple::ArchType>(ArchName)
00219     .Cases("i386", "i486", "i586", "i686", Triple::x86)
00220     // FIXME: Do we need to support these?
00221     .Cases("i786", "i886", "i986", Triple::x86)
00222     .Cases("amd64", "x86_64", Triple::x86_64)
00223     .Case("powerpc", Triple::ppc)
00224     .Cases("powerpc64", "ppu", Triple::ppc64)
00225     .Case("mblaze", Triple::mblaze)
00226     .Case("aarch64", Triple::aarch64)
00227     .Cases("arm", "xscale", Triple::arm)
00228     // FIXME: It would be good to replace these with explicit names for all the
00229     // various suffixes supported.
00230     .StartsWith("armv", Triple::arm)
00231     .Case("thumb", Triple::thumb)
00232     .StartsWith("thumbv", Triple::thumb)
00233     .Case("msp430", Triple::msp430)
00234     .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
00235     .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
00236     .Cases("mips64", "mips64eb", Triple::mips64)
00237     .Case("mips64el", Triple::mips64el)
00238     .Case("r600", Triple::r600)
00239     .Case("hexagon", Triple::hexagon)
00240     .Case("s390x", Triple::systemz)
00241     .Case("sparc", Triple::sparc)
00242     .Cases("sparcv9", "sparc64", Triple::sparcv9)
00243     .Case("tce", Triple::tce)
00244     .Case("xcore", Triple::xcore)
00245     .Case("nvptx", Triple::nvptx)
00246     .Case("nvptx64", Triple::nvptx64)
00247     .Case("le32", Triple::le32)
00248     .Case("amdil", Triple::amdil)
00249     .Case("spir", Triple::spir)
00250     .Case("spir64", Triple::spir64)
00251     .Default(Triple::UnknownArch);
00252 }
00253 
00254 static Triple::VendorType parseVendor(StringRef VendorName) {
00255   return StringSwitch<Triple::VendorType>(VendorName)
00256     .Case("apple", Triple::Apple)
00257     .Case("pc", Triple::PC)
00258     .Case("scei", Triple::SCEI)
00259     .Case("bgp", Triple::BGP)
00260     .Case("bgq", Triple::BGQ)
00261     .Case("fsl", Triple::Freescale)
00262     .Case("ibm", Triple::IBM)
00263     .Default(Triple::UnknownVendor);
00264 }
00265 
00266 static Triple::OSType parseOS(StringRef OSName) {
00267   return StringSwitch<Triple::OSType>(OSName)
00268     .StartsWith("auroraux", Triple::AuroraUX)
00269     .StartsWith("cygwin", Triple::Cygwin)
00270     .StartsWith("darwin", Triple::Darwin)
00271     .StartsWith("dragonfly", Triple::DragonFly)
00272     .StartsWith("freebsd", Triple::FreeBSD)
00273     .StartsWith("ios", Triple::IOS)
00274     .StartsWith("kfreebsd", Triple::KFreeBSD)
00275     .StartsWith("linux", Triple::Linux)
00276     .StartsWith("lv2", Triple::Lv2)
00277     .StartsWith("macosx", Triple::MacOSX)
00278     .StartsWith("mingw32", Triple::MinGW32)
00279     .StartsWith("netbsd", Triple::NetBSD)
00280     .StartsWith("openbsd", Triple::OpenBSD)
00281     .StartsWith("solaris", Triple::Solaris)
00282     .StartsWith("win32", Triple::Win32)
00283     .StartsWith("haiku", Triple::Haiku)
00284     .StartsWith("minix", Triple::Minix)
00285     .StartsWith("rtems", Triple::RTEMS)
00286     .StartsWith("nacl", Triple::NaCl)
00287     .StartsWith("cnk", Triple::CNK)
00288     .StartsWith("bitrig", Triple::Bitrig)
00289     .StartsWith("aix", Triple::AIX)
00290     .Default(Triple::UnknownOS);
00291 }
00292 
00293 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
00294   return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
00295     .StartsWith("eabi", Triple::EABI)
00296     .StartsWith("gnueabihf", Triple::GNUEABIHF)
00297     .StartsWith("gnueabi", Triple::GNUEABI)
00298     .StartsWith("gnux32", Triple::GNUX32)
00299     .StartsWith("gnu", Triple::GNU)
00300     .StartsWith("macho", Triple::MachO)
00301     .StartsWith("android", Triple::Android)
00302     .StartsWith("elf", Triple::ELF)
00303     .Default(Triple::UnknownEnvironment);
00304 }
00305 
00306 /// \brief Construct a triple from the string representation provided.
00307 ///
00308 /// This stores the string representation and parses the various pieces into
00309 /// enum members.
00310 Triple::Triple(const Twine &Str)
00311     : Data(Str.str()),
00312       Arch(parseArch(getArchName())),
00313       Vendor(parseVendor(getVendorName())),
00314       OS(parseOS(getOSName())),
00315       Environment(parseEnvironment(getEnvironmentName())) {
00316 }
00317 
00318 /// \brief Construct a triple from string representations of the architecture,
00319 /// vendor, and OS.
00320 ///
00321 /// This joins each argument into a canonical string representation and parses
00322 /// them into enum members. It leaves the environment unknown and omits it from
00323 /// the string representation.
00324 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
00325     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
00326       Arch(parseArch(ArchStr.str())),
00327       Vendor(parseVendor(VendorStr.str())),
00328       OS(parseOS(OSStr.str())),
00329       Environment() {
00330 }
00331 
00332 /// \brief Construct a triple from string representations of the architecture,
00333 /// vendor, OS, and environment.
00334 ///
00335 /// This joins each argument into a canonical string representation and parses
00336 /// them into enum members.
00337 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
00338                const Twine &EnvironmentStr)
00339     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
00340             EnvironmentStr).str()),
00341       Arch(parseArch(ArchStr.str())),
00342       Vendor(parseVendor(VendorStr.str())),
00343       OS(parseOS(OSStr.str())),
00344       Environment(parseEnvironment(EnvironmentStr.str())) {
00345 }
00346 
00347 std::string Triple::normalize(StringRef Str) {
00348   // Parse into components.
00349   SmallVector<StringRef, 4> Components;
00350   Str.split(Components, "-");
00351 
00352   // If the first component corresponds to a known architecture, preferentially
00353   // use it for the architecture.  If the second component corresponds to a
00354   // known vendor, preferentially use it for the vendor, etc.  This avoids silly
00355   // component movement when a component parses as (eg) both a valid arch and a
00356   // valid os.
00357   ArchType Arch = UnknownArch;
00358   if (Components.size() > 0)
00359     Arch = parseArch(Components[0]);
00360   VendorType Vendor = UnknownVendor;
00361   if (Components.size() > 1)
00362     Vendor = parseVendor(Components[1]);
00363   OSType OS = UnknownOS;
00364   if (Components.size() > 2)
00365     OS = parseOS(Components[2]);
00366   EnvironmentType Environment = UnknownEnvironment;
00367   if (Components.size() > 3)
00368     Environment = parseEnvironment(Components[3]);
00369 
00370   // Note which components are already in their final position.  These will not
00371   // be moved.
00372   bool Found[4];
00373   Found[0] = Arch != UnknownArch;
00374   Found[1] = Vendor != UnknownVendor;
00375   Found[2] = OS != UnknownOS;
00376   Found[3] = Environment != UnknownEnvironment;
00377 
00378   // If they are not there already, permute the components into their canonical
00379   // positions by seeing if they parse as a valid architecture, and if so moving
00380   // the component to the architecture position etc.
00381   for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
00382     if (Found[Pos])
00383       continue; // Already in the canonical position.
00384 
00385     for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
00386       // Do not reparse any components that already matched.
00387       if (Idx < array_lengthof(Found) && Found[Idx])
00388         continue;
00389 
00390       // Does this component parse as valid for the target position?
00391       bool Valid = false;
00392       StringRef Comp = Components[Idx];
00393       switch (Pos) {
00394       default: llvm_unreachable("unexpected component type!");
00395       case 0:
00396         Arch = parseArch(Comp);
00397         Valid = Arch != UnknownArch;
00398         break;
00399       case 1:
00400         Vendor = parseVendor(Comp);
00401         Valid = Vendor != UnknownVendor;
00402         break;
00403       case 2:
00404         OS = parseOS(Comp);
00405         Valid = OS != UnknownOS;
00406         break;
00407       case 3:
00408         Environment = parseEnvironment(Comp);
00409         Valid = Environment != UnknownEnvironment;
00410         break;
00411       }
00412       if (!Valid)
00413         continue; // Nope, try the next component.
00414 
00415       // Move the component to the target position, pushing any non-fixed
00416       // components that are in the way to the right.  This tends to give
00417       // good results in the common cases of a forgotten vendor component
00418       // or a wrongly positioned environment.
00419       if (Pos < Idx) {
00420         // Insert left, pushing the existing components to the right.  For
00421         // example, a-b-i386 -> i386-a-b when moving i386 to the front.
00422         StringRef CurrentComponent(""); // The empty component.
00423         // Replace the component we are moving with an empty component.
00424         std::swap(CurrentComponent, Components[Idx]);
00425         // Insert the component being moved at Pos, displacing any existing
00426         // components to the right.
00427         for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
00428           // Skip over any fixed components.
00429           while (i < array_lengthof(Found) && Found[i])
00430             ++i;
00431           // Place the component at the new position, getting the component
00432           // that was at this position - it will be moved right.
00433           std::swap(CurrentComponent, Components[i]);
00434         }
00435       } else if (Pos > Idx) {
00436         // Push right by inserting empty components until the component at Idx
00437         // reaches the target position Pos.  For example, pc-a -> -pc-a when
00438         // moving pc to the second position.
00439         do {
00440           // Insert one empty component at Idx.
00441           StringRef CurrentComponent(""); // The empty component.
00442           for (unsigned i = Idx; i < Components.size();) {
00443             // Place the component at the new position, getting the component
00444             // that was at this position - it will be moved right.
00445             std::swap(CurrentComponent, Components[i]);
00446             // If it was placed on top of an empty component then we are done.
00447             if (CurrentComponent.empty())
00448               break;
00449             // Advance to the next component, skipping any fixed components.
00450             while (++i < array_lengthof(Found) && Found[i])
00451               ;
00452           }
00453           // The last component was pushed off the end - append it.
00454           if (!CurrentComponent.empty())
00455             Components.push_back(CurrentComponent);
00456 
00457           // Advance Idx to the component's new position.
00458           while (++Idx < array_lengthof(Found) && Found[Idx])
00459             ;
00460         } while (Idx < Pos); // Add more until the final position is reached.
00461       }
00462       assert(Pos < Components.size() && Components[Pos] == Comp &&
00463              "Component moved wrong!");
00464       Found[Pos] = true;
00465       break;
00466     }
00467   }
00468 
00469   // Special case logic goes here.  At this point Arch, Vendor and OS have the
00470   // correct values for the computed components.
00471 
00472   // Stick the corrected components back together to form the normalized string.
00473   std::string Normalized;
00474   for (unsigned i = 0, e = Components.size(); i != e; ++i) {
00475     if (i) Normalized += '-';
00476     Normalized += Components[i];
00477   }
00478   return Normalized;
00479 }
00480 
00481 StringRef Triple::getArchName() const {
00482   return StringRef(Data).split('-').first;           // Isolate first component
00483 }
00484 
00485 StringRef Triple::getVendorName() const {
00486   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
00487   return Tmp.split('-').first;                       // Isolate second component
00488 }
00489 
00490 StringRef Triple::getOSName() const {
00491   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
00492   Tmp = Tmp.split('-').second;                       // Strip second component
00493   return Tmp.split('-').first;                       // Isolate third component
00494 }
00495 
00496 StringRef Triple::getEnvironmentName() const {
00497   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
00498   Tmp = Tmp.split('-').second;                       // Strip second component
00499   return Tmp.split('-').second;                      // Strip third component
00500 }
00501 
00502 StringRef Triple::getOSAndEnvironmentName() const {
00503   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
00504   return Tmp.split('-').second;                      // Strip second component
00505 }
00506 
00507 static unsigned EatNumber(StringRef &Str) {
00508   assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
00509   unsigned Result = 0;
00510 
00511   do {
00512     // Consume the leading digit.
00513     Result = Result*10 + (Str[0] - '0');
00514 
00515     // Eat the digit.
00516     Str = Str.substr(1);
00517   } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
00518 
00519   return Result;
00520 }
00521 
00522 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
00523                           unsigned &Micro) const {
00524   StringRef OSName = getOSName();
00525 
00526   // Assume that the OS portion of the triple starts with the canonical name.
00527   StringRef OSTypeName = getOSTypeName(getOS());
00528   if (OSName.startswith(OSTypeName))
00529     OSName = OSName.substr(OSTypeName.size());
00530 
00531   // Any unset version defaults to 0.
00532   Major = Minor = Micro = 0;
00533 
00534   // Parse up to three components.
00535   unsigned *Components[3] = { &Major, &Minor, &Micro };
00536   for (unsigned i = 0; i != 3; ++i) {
00537     if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
00538       break;
00539 
00540     // Consume the leading number.
00541     *Components[i] = EatNumber(OSName);
00542 
00543     // Consume the separator, if present.
00544     if (OSName.startswith("."))
00545       OSName = OSName.substr(1);
00546   }
00547 }
00548 
00549 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
00550                               unsigned &Micro) const {
00551   getOSVersion(Major, Minor, Micro);
00552 
00553   switch (getOS()) {
00554   default: llvm_unreachable("unexpected OS for Darwin triple");
00555   case Darwin:
00556     // Default to darwin8, i.e., MacOSX 10.4.
00557     if (Major == 0)
00558       Major = 8;
00559     // Darwin version numbers are skewed from OS X versions.
00560     if (Major < 4)
00561       return false;
00562     Micro = 0;
00563     Minor = Major - 4;
00564     Major = 10;
00565     break;
00566   case MacOSX:
00567     // Default to 10.4.
00568     if (Major == 0) {
00569       Major = 10;
00570       Minor = 4;
00571     }
00572     if (Major != 10)
00573       return false;
00574     break;
00575   case IOS:
00576     // Ignore the version from the triple.  This is only handled because the
00577     // the clang driver combines OS X and IOS support into a common Darwin
00578     // toolchain that wants to know the OS X version number even when targeting
00579     // IOS.
00580     Major = 10;
00581     Minor = 4;
00582     Micro = 0;
00583     break;
00584   }
00585   return true;
00586 }
00587 
00588 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
00589                            unsigned &Micro) const {
00590   switch (getOS()) {
00591   default: llvm_unreachable("unexpected OS for Darwin triple");
00592   case Darwin:
00593   case MacOSX:
00594     // Ignore the version from the triple.  This is only handled because the
00595     // the clang driver combines OS X and IOS support into a common Darwin
00596     // toolchain that wants to know the iOS version number even when targeting
00597     // OS X.
00598     Major = 3;
00599     Minor = 0;
00600     Micro = 0;
00601     break;
00602   case IOS:
00603     getOSVersion(Major, Minor, Micro);
00604     // Default to 3.0.
00605     if (Major == 0)
00606       Major = 3;
00607     break;
00608   }
00609 }
00610 
00611 void Triple::setTriple(const Twine &Str) {
00612   *this = Triple(Str);
00613 }
00614 
00615 void Triple::setArch(ArchType Kind) {
00616   setArchName(getArchTypeName(Kind));
00617 }
00618 
00619 void Triple::setVendor(VendorType Kind) {
00620   setVendorName(getVendorTypeName(Kind));
00621 }
00622 
00623 void Triple::setOS(OSType Kind) {
00624   setOSName(getOSTypeName(Kind));
00625 }
00626 
00627 void Triple::setEnvironment(EnvironmentType Kind) {
00628   setEnvironmentName(getEnvironmentTypeName(Kind));
00629 }
00630 
00631 void Triple::setArchName(StringRef Str) {
00632   // Work around a miscompilation bug for Twines in gcc 4.0.3.
00633   SmallString<64> Triple;
00634   Triple += Str;
00635   Triple += "-";
00636   Triple += getVendorName();
00637   Triple += "-";
00638   Triple += getOSAndEnvironmentName();
00639   setTriple(Triple.str());
00640 }
00641 
00642 void Triple::setVendorName(StringRef Str) {
00643   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
00644 }
00645 
00646 void Triple::setOSName(StringRef Str) {
00647   if (hasEnvironment())
00648     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
00649               "-" + getEnvironmentName());
00650   else
00651     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
00652 }
00653 
00654 void Triple::setEnvironmentName(StringRef Str) {
00655   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
00656             "-" + Str);
00657 }
00658 
00659 void Triple::setOSAndEnvironmentName(StringRef Str) {
00660   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
00661 }
00662 
00663 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
00664   switch (Arch) {
00665   case llvm::Triple::UnknownArch:
00666     return 0;
00667 
00668   case llvm::Triple::msp430:
00669     return 16;
00670 
00671   case llvm::Triple::amdil:
00672   case llvm::Triple::arm:
00673   case llvm::Triple::hexagon:
00674   case llvm::Triple::le32:
00675   case llvm::Triple::mblaze:
00676   case llvm::Triple::mips:
00677   case llvm::Triple::mipsel:
00678   case llvm::Triple::nvptx:
00679   case llvm::Triple::ppc:
00680   case llvm::Triple::r600:
00681   case llvm::Triple::sparc:
00682   case llvm::Triple::tce:
00683   case llvm::Triple::thumb:
00684   case llvm::Triple::x86:
00685   case llvm::Triple::xcore:
00686   case llvm::Triple::spir:
00687     return 32;
00688 
00689   case llvm::Triple::aarch64:
00690   case llvm::Triple::mips64:
00691   case llvm::Triple::mips64el:
00692   case llvm::Triple::nvptx64:
00693   case llvm::Triple::ppc64:
00694   case llvm::Triple::sparcv9:
00695   case llvm::Triple::systemz:
00696   case llvm::Triple::x86_64:
00697   case llvm::Triple::spir64:
00698     return 64;
00699   }
00700   llvm_unreachable("Invalid architecture value");
00701 }
00702 
00703 bool Triple::isArch64Bit() const {
00704   return getArchPointerBitWidth(getArch()) == 64;
00705 }
00706 
00707 bool Triple::isArch32Bit() const {
00708   return getArchPointerBitWidth(getArch()) == 32;
00709 }
00710 
00711 bool Triple::isArch16Bit() const {
00712   return getArchPointerBitWidth(getArch()) == 16;
00713 }
00714 
00715 Triple Triple::get32BitArchVariant() const {
00716   Triple T(*this);
00717   switch (getArch()) {
00718   case Triple::UnknownArch:
00719   case Triple::aarch64:
00720   case Triple::msp430:
00721   case Triple::systemz:
00722     T.setArch(UnknownArch);
00723     break;
00724 
00725   case Triple::amdil:
00726   case Triple::spir:
00727   case Triple::arm:
00728   case Triple::hexagon:
00729   case Triple::le32:
00730   case Triple::mblaze:
00731   case Triple::mips:
00732   case Triple::mipsel:
00733   case Triple::nvptx:
00734   case Triple::ppc:
00735   case Triple::r600:
00736   case Triple::sparc:
00737   case Triple::tce:
00738   case Triple::thumb:
00739   case Triple::x86:
00740   case Triple::xcore:
00741     // Already 32-bit.
00742     break;
00743 
00744   case Triple::mips64:    T.setArch(Triple::mips);    break;
00745   case Triple::mips64el:  T.setArch(Triple::mipsel);  break;
00746   case Triple::nvptx64:   T.setArch(Triple::nvptx);   break;
00747   case Triple::ppc64:     T.setArch(Triple::ppc);   break;
00748   case Triple::sparcv9:   T.setArch(Triple::sparc);   break;
00749   case Triple::x86_64:    T.setArch(Triple::x86);     break;
00750   case Triple::spir64:    T.setArch(Triple::spir);    break;
00751   }
00752   return T;
00753 }
00754 
00755 Triple Triple::get64BitArchVariant() const {
00756   Triple T(*this);
00757   switch (getArch()) {
00758   case Triple::UnknownArch:
00759   case Triple::amdil:
00760   case Triple::arm:
00761   case Triple::hexagon:
00762   case Triple::le32:
00763   case Triple::mblaze:
00764   case Triple::msp430:
00765   case Triple::r600:
00766   case Triple::tce:
00767   case Triple::thumb:
00768   case Triple::xcore:
00769     T.setArch(UnknownArch);
00770     break;
00771 
00772   case Triple::aarch64:
00773   case Triple::spir64:
00774   case Triple::mips64:
00775   case Triple::mips64el:
00776   case Triple::nvptx64:
00777   case Triple::ppc64:
00778   case Triple::sparcv9:
00779   case Triple::systemz:
00780   case Triple::x86_64:
00781     // Already 64-bit.
00782     break;
00783 
00784   case Triple::mips:    T.setArch(Triple::mips64);    break;
00785   case Triple::mipsel:  T.setArch(Triple::mips64el);  break;
00786   case Triple::nvptx:   T.setArch(Triple::nvptx64);   break;
00787   case Triple::ppc:     T.setArch(Triple::ppc64);     break;
00788   case Triple::sparc:   T.setArch(Triple::sparcv9);   break;
00789   case Triple::x86:     T.setArch(Triple::x86_64);    break;
00790   case Triple::spir:    T.setArch(Triple::spir64);    break;
00791   }
00792   return T;
00793 }