summaryrefslogtreecommitdiffstats
path: root/lib/Support/Triple.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Support/Triple.cpp')
-rw-r--r--lib/Support/Triple.cpp352
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);
}
OpenPOWER on IntegriCloud