diff options
author | Renato Golin <renato.golin@arm.com> | 2011-01-21 18:25:47 +0000 |
---|---|---|
committer | Renato Golin <renato.golin@arm.com> | 2011-01-21 18:25:47 +0000 |
commit | 859f8183639346378ed29d1e04a4b070ebc7e97f (patch) | |
tree | c52e2cb8579093cc8e76670765e8b3f07d5e52fa /lib/Support/Triple.cpp | |
parent | 596937914548c181f2504aad3b709189e87a561b (diff) |
Clang was not parsing target triples involving EABI and was generating wrong IR (wrong PCS) and passing the wrong information down llc via the target-triple printed in IR. I've fixed this by adding the parsing of EABI into LLVM's Triple class and using it to choose the correct PCS in Clang's Tools. A Clang patch is on its way to use this infrastructure.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123990 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/Triple.cpp')
-rw-r--r-- | lib/Support/Triple.cpp | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index c7ad7b7611..c9da964ce1 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -84,6 +84,7 @@ const char *Triple::getVendorTypeName(VendorType Kind) { case Apple: return "apple"; case PC: return "pc"; + case NoVendor: return "none"; } return "<invalid>"; @@ -109,6 +110,7 @@ const char *Triple::getOSTypeName(OSType Kind) { case Win32: return "win32"; case Haiku: return "haiku"; case Minix: return "minix"; + case NoOS: return "none"; } return "<invalid>"; @@ -117,6 +119,9 @@ const char *Triple::getOSTypeName(OSType Kind) { const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { switch (Kind) { case UnknownEnvironment: return "unknown"; + case GNU: return "gnu"; + case GNUEABI: return "gnueabi"; + case EABI: return "eabi"; } return "<invalid>"; @@ -293,6 +298,8 @@ Triple::VendorType Triple::ParseVendor(StringRef VendorName) { return Apple; else if (VendorName == "pc") return PC; + else if (VendorName == "none") + return NoVendor; else return UnknownVendor; } @@ -330,12 +337,21 @@ Triple::OSType Triple::ParseOS(StringRef OSName) { return Haiku; else if (OSName.startswith("minix")) return Minix; + else if (OSName.startswith("eabi")) + return NoOS; else return UnknownOS; } Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) { - return UnknownEnvironment; + if (EnvironmentName.startswith("eabi")) + return EABI; + else if (EnvironmentName.startswith("gnueabi")) + return GNUEABI; + else if (EnvironmentName.startswith("gnu")) + return GNU; + else + return UnknownEnvironment; } void Triple::Parse() const { @@ -344,7 +360,12 @@ void Triple::Parse() const { Arch = ParseArch(getArchName()); Vendor = ParseVendor(getVendorName()); OS = ParseOS(getOSName()); - Environment = ParseEnvironment(getEnvironmentName()); + if (OS == NoOS) { + // Some targets don't have an OS (embedded systems) + Environment = ParseEnvironment(getOSName()); + } else { + Environment = ParseEnvironment(getEnvironmentName()); + } assert(isInitialized() && "Failed to initialize!"); } @@ -411,7 +432,13 @@ std::string Triple::normalize(StringRef Str) { break; case 2: OS = ParseOS(Comp); - Valid = OS != UnknownOS; + // Some targets don't have an OS (embedded systems) + if (OS == NoOS) { + Environment = ParseEnvironment(Comp); + Valid = Environment != UnknownEnvironment; + } else { + Valid = OS != UnknownOS; + } break; case 3: Environment = ParseEnvironment(Comp); @@ -450,6 +477,9 @@ std::string Triple::normalize(StringRef Str) { for (unsigned i = Idx; i < Components.size(); ++i) { // Skip over any fixed components. while (i < array_lengthof(Found) && Found[i]) ++i; + // Fix problem when Components vector is not big enough + if (i >= Components.size()) + Components.push_back(StringRef("")); // Place the component at the new position, getting the component // that was at this position - it will be moved right. std::swap(CurrentComponent, Components[i]); |