diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
commit | cd749a9c07f1de2fb8affde90537efa4bc3e7c54 (patch) | |
tree | b21f6de4e08b89bb7931806bab798fc2a5e3a686 /lib/Support/Triple.cpp | |
parent | 72621d11de5b873f1695f391eb95f0b336c3d2d4 (diff) | |
download | FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.zip FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.tar.gz |
Update llvm to r84119.
Diffstat (limited to 'lib/Support/Triple.cpp')
-rw-r--r-- | lib/Support/Triple.cpp | 352 |
1 files changed, 291 insertions, 61 deletions
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 279bd43..6f805da 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -8,6 +8,9 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/Triple.h" + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Twine.h" #include <cassert> #include <cstring> using namespace llvm; @@ -18,22 +21,60 @@ const char *Triple::getArchTypeName(ArchType Kind) { switch (Kind) { case InvalidArch: return "<invalid>"; case UnknownArch: return "unknown"; - - case x86: return "i386"; - case x86_64: return "x86_64"; - case ppc: return "powerpc"; - case ppc64: return "powerpc64"; + + case alpha: return "alpha"; + case arm: return "arm"; + case bfin: return "bfin"; + case cellspu: return "cellspu"; + case mips: return "mips"; + case mipsel: return "mipsel"; + case msp430: return "msp430"; + case pic16: return "pic16"; + case ppc64: return "powerpc64"; + case ppc: return "powerpc"; + case sparc: return "sparc"; + case systemz: return "s390x"; + case tce: return "tce"; + case thumb: return "thumb"; + case x86: return "i386"; + case x86_64: return "x86_64"; + case xcore: return "xcore"; } return "<invalid>"; } +const char *Triple::getArchTypePrefix(ArchType Kind) { + switch (Kind) { + default: + return 0; + + case alpha: return "alpha"; + + case arm: + case thumb: return "arm"; + + case bfin: return "bfin"; + + case cellspu: return "spu"; + + case ppc64: + case ppc: return "ppc"; + + case sparc: return "sparc"; + + case x86: + case x86_64: return "x86"; + case xcore: return "xcore"; + } +} + const char *Triple::getVendorTypeName(VendorType Kind) { switch (Kind) { case UnknownVendor: return "unknown"; case Apple: return "apple"; - case PC: return "PC"; + case PC: return "pc"; } return "<invalid>"; @@ -44,35 +85,166 @@ const char *Triple::getOSTypeName(OSType Kind) { case UnknownOS: return "unknown"; case AuroraUX: return "auroraux"; + case Cygwin: return "cygwin"; case Darwin: return "darwin"; case DragonFly: return "dragonfly"; case FreeBSD: return "freebsd"; case Linux: return "linux"; + case MinGW32: return "mingw32"; + case MinGW64: return "mingw64"; + case NetBSD: return "netbsd"; case OpenBSD: return "openbsd"; + case Solaris: return "solaris"; + case Win32: return "win32"; } return "<invalid>"; } +Triple::ArchType Triple::getArchTypeForLLVMName(const StringRef &Name) { + if (Name == "alpha") + return alpha; + if (Name == "arm") + return arm; + if (Name == "bfin") + return bfin; + if (Name == "cellspu") + return cellspu; + if (Name == "mips") + return mips; + if (Name == "mipsel") + return mipsel; + if (Name == "msp430") + return msp430; + if (Name == "pic16") + return pic16; + if (Name == "ppc64") + return ppc64; + if (Name == "ppc") + return ppc; + if (Name == "sparc") + return sparc; + if (Name == "systemz") + return systemz; + if (Name == "tce") + return tce; + if (Name == "thumb") + return thumb; + if (Name == "x86") + return x86; + if (Name == "x86-64") + return x86_64; + if (Name == "xcore") + return xcore; + + return UnknownArch; +} + +Triple::ArchType Triple::getArchTypeForDarwinArchName(const StringRef &Str) { + // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for + // archs which Darwin doesn't use. + + // The matching this routine does is fairly pointless, since it is neither the + // complete architecture list, nor a reasonable subset. The problem is that + // historically the driver driver accepts this and also ties its -march= + // handling to the architecture name, so we need to be careful before removing + // support for it. + + // This code must be kept in sync with Clang's Darwin specific argument + // translation. + + if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" || + Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" || + Str == "ppc7450" || Str == "ppc970") + return Triple::ppc; + + if (Str == "ppc64") + return Triple::ppc64; + + if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" || + Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" || + Str == "pentIIm5" || Str == "pentium4") + return Triple::x86; + + if (Str == "x86_64") + return Triple::x86_64; + + // This is derived from the driver driver. + if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" || + Str == "armv6" || Str == "armv7") + return Triple::arm; + + return Triple::UnknownArch; +} + // void Triple::Parse() const { assert(!isInitialized() && "Invalid parse call."); - std::string ArchName = getArchName(); + StringRef ArchName = getArchName(); + StringRef VendorName = getVendorName(); + StringRef OSName = getOSName(); + if (ArchName.size() == 4 && ArchName[0] == 'i' && - ArchName[2] == '8' && ArchName[3] == '6') + ArchName[2] == '8' && ArchName[3] == '6' && + ArchName[1] - '3' < 6) // i[3-9]86 Arch = x86; else if (ArchName == "amd64" || ArchName == "x86_64") Arch = x86_64; + else if (ArchName == "bfin") + Arch = bfin; + else if (ArchName == "pic16") + Arch = pic16; else if (ArchName == "powerpc") Arch = ppc; else if (ArchName == "powerpc64") Arch = ppc64; + else if (ArchName == "arm" || + ArchName.startswith("armv") || + ArchName == "xscale") + Arch = arm; + else if (ArchName == "thumb" || + ArchName.startswith("thumbv")) + Arch = thumb; + else if (ArchName.startswith("alpha")) + Arch = alpha; + else if (ArchName == "spu" || ArchName == "cellspu") + Arch = cellspu; + else if (ArchName == "msp430") + Arch = msp430; + else if (ArchName == "mips" || ArchName == "mipsallegrex") + Arch = mips; + else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" || + ArchName == "psp") + Arch = mipsel; + else if (ArchName == "sparc") + Arch = sparc; + else if (ArchName == "s390x") + Arch = systemz; + else if (ArchName == "tce") + Arch = tce; + else if (ArchName == "xcore") + Arch = xcore; else Arch = UnknownArch; - std::string VendorName = getVendorName(); + + // Handle some exceptional cases where the OS / environment components are + // stuck into the vendor field. + if (StringRef(getTriple()).count('-') == 1) { + StringRef VendorName = getVendorName(); + + if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc. + Vendor = PC; + OS = MinGW32; + return; + } + + // arm-elf is another example, but we don't currently parse anything about + // the environment. + } + if (VendorName == "apple") Vendor = Apple; else if (VendorName == "pc") @@ -80,78 +252,129 @@ void Triple::Parse() const { else Vendor = UnknownVendor; - std::string OSName = getOSName(); - if (memcmp(&OSName[0], "auroraux", 8) == 0) + if (OSName.startswith("auroraux")) OS = AuroraUX; - else if (memcmp(&OSName[0], "darwin", 6) == 0) + else if (OSName.startswith("cygwin")) + OS = Cygwin; + else if (OSName.startswith("darwin")) OS = Darwin; - else if (memcmp(&OSName[0], "dragonfly", 9) == 0) + else if (OSName.startswith("dragonfly")) OS = DragonFly; - else if (memcmp(&OSName[0], "freebsd", 7) == 0) + else if (OSName.startswith("freebsd")) OS = FreeBSD; - else if (memcmp(&OSName[0], "linux", 5) == 0) + else if (OSName.startswith("linux")) OS = Linux; - else if (memcmp(&OSName[0], "openbsd", 7) == 0) + else if (OSName.startswith("mingw32")) + OS = MinGW32; + else if (OSName.startswith("mingw64")) + OS = MinGW64; + else if (OSName.startswith("netbsd")) + OS = NetBSD; + else if (OSName.startswith("openbsd")) OS = OpenBSD; + else if (OSName.startswith("solaris")) + OS = Solaris; + else if (OSName.startswith("win32")) + OS = Win32; else OS = UnknownOS; assert(isInitialized() && "Failed to initialize!"); } -static std::string extract(const std::string &A, - std::string::size_type begin, - std::string::size_type end) { - if (begin == std::string::npos) - return ""; - if (end == std::string::npos) - return A.substr(begin); - return A.substr(begin, end - begin); +StringRef Triple::getArchName() const { + return StringRef(Data).split('-').first; // Isolate first component } -static std::string extract1(const std::string &A, - std::string::size_type begin, - std::string::size_type end) { - if (begin == std::string::npos || begin == end) - return ""; - return extract(A, begin + 1, end); +StringRef Triple::getVendorName() const { + StringRef Tmp = StringRef(Data).split('-').second; // Strip first component + return Tmp.split('-').first; // Isolate second component } -std::string Triple::getArchName() const { - std::string Tmp = Data; - return extract(Tmp, 0, Tmp.find('-')); +StringRef Triple::getOSName() const { + StringRef Tmp = StringRef(Data).split('-').second; // Strip first component + Tmp = Tmp.split('-').second; // Strip second component + return Tmp.split('-').first; // Isolate third component } -std::string Triple::getVendorName() const { - std::string Tmp = Data; - Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos); - return extract(Tmp, 0, Tmp.find('-')); +StringRef Triple::getEnvironmentName() const { + StringRef Tmp = StringRef(Data).split('-').second; // Strip first component + Tmp = Tmp.split('-').second; // Strip second component + return Tmp.split('-').second; // Strip third component } -std::string Triple::getOSName() const { - std::string Tmp = Data; - Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos); - Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos); - return extract(Tmp, 0, Tmp.find('-')); +StringRef Triple::getOSAndEnvironmentName() const { + StringRef Tmp = StringRef(Data).split('-').second; // Strip first component + return Tmp.split('-').second; // Strip second component } -std::string Triple::getEnvironmentName() const { - std::string Tmp = Data; - Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos); - Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos); - Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos); - return extract(Tmp, 0, std::string::npos); +static unsigned EatNumber(StringRef &Str) { + assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); + unsigned Result = Str[0]-'0'; + + // Eat the digit. + Str = Str.substr(1); + + // Handle "darwin11". + if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') { + Result = Result*10 + (Str[0] - '0'); + // Eat the digit. + Str = Str.substr(1); + } + + return Result; } -std::string Triple::getOSAndEnvironmentName() const { - std::string Tmp = Data; - Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos); - Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos); - return extract(Tmp, 0, std::string::npos); +/// getDarwinNumber - Parse the 'darwin number' out of the specific target +/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is +/// not defined, return 0's. This requires that the triple have an OSType of +/// darwin before it is called. +void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min, + unsigned &Revision) const { + assert(getOS() == Darwin && "Not a darwin target triple!"); + StringRef OSName = getOSName(); + assert(OSName.startswith("darwin") && "Unknown darwin target triple!"); + + // Strip off "darwin". + OSName = OSName.substr(6); + + Maj = Min = Revision = 0; + + if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') + return; + + // The major version is the first digit. + Maj = EatNumber(OSName); + if (OSName.empty()) return; + + // Handle minor version: 10.4.9 -> darwin8.9. + if (OSName[0] != '.') + return; + + // Eat the '.'. + OSName = OSName.substr(1); + + if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') + return; + + Min = EatNumber(OSName); + if (OSName.empty()) return; + + // Handle revision darwin8.9.1 + if (OSName[0] != '.') + return; + + // Eat the '.'. + OSName = OSName.substr(1); + + if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') + return; + + Revision = EatNumber(OSName); } -void Triple::setTriple(const std::string &Str) { - Data = Str; +void Triple::setTriple(const Twine &Str) { + Data = Str.str(); Arch = InvalidArch; } @@ -167,15 +390,22 @@ void Triple::setOS(OSType Kind) { setOSName(getOSTypeName(Kind)); } -void Triple::setArchName(const std::string &Str) { - setTriple(Str + "-" + getVendorName() + "-" + getOSAndEnvironmentName()); +void Triple::setArchName(const StringRef &Str) { + // Work around a miscompilation bug for Twines in gcc 4.0.3. + SmallString<64> Triple; + Triple += Str; + Triple += "-"; + Triple += getVendorName(); + Triple += "-"; + Triple += getOSAndEnvironmentName(); + setTriple(Triple.str()); } -void Triple::setVendorName(const std::string &Str) { +void Triple::setVendorName(const StringRef &Str) { setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); } -void Triple::setOSName(const std::string &Str) { +void Triple::setOSName(const StringRef &Str) { if (hasEnvironment()) setTriple(getArchName() + "-" + getVendorName() + "-" + Str + "-" + getEnvironmentName()); @@ -183,11 +413,11 @@ void Triple::setOSName(const std::string &Str) { setTriple(getArchName() + "-" + getVendorName() + "-" + Str); } -void Triple::setEnvironmentName(const std::string &Str) { +void Triple::setEnvironmentName(const StringRef &Str) { setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + "-" + Str); } -void Triple::setOSAndEnvironmentName(const std::string &Str) { +void Triple::setOSAndEnvironmentName(const StringRef &Str) { setTriple(getArchName() + "-" + getVendorName() + "-" + Str); } |