@@ -, +, @@ vendor --- include/llvm/ADT/Triple.h | 5 ++++- lib/Support/Triple.cpp | 37 +++++++++++++++++++++++++++++++------ unittests/ADT/TripleTest.cpp | 13 +++++++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) --- a/include/llvm/ADT/Triple.h +++ a/include/llvm/ADT/Triple.h @@ -139,7 +139,10 @@ public: Myriad, AMD, Mesa, - LastVendorType = Mesa + // special values used on Gentoo to indicate ARM softfloat/hardfloat + SoftFloat, + HardFloat, + LastVendorType = HardFloat }; enum OSType { UnknownOS, --- a/lib/Support/Triple.cpp +++ a/lib/Support/Triple.cpp @@ -161,6 +161,8 @@ StringRef Triple::getVendorTypeName(VendorType Kind) { case Myriad: return "myriad"; case AMD: return "amd"; case Mesa: return "mesa"; + case SoftFloat: return "softfloat"; + case HardFloat: return "hardfloat"; } llvm_unreachable("Invalid VendorType!"); @@ -443,6 +445,8 @@ static Triple::VendorType parseVendor(StringRef VendorName) { .Case("myriad", Triple::Myriad) .Case("amd", Triple::AMD) .Case("mesa", Triple::Mesa) + .Case("softfloat", Triple::SoftFloat) + .Case("hardfloat", Triple::HardFloat) .Default(Triple::UnknownVendor); } @@ -482,8 +486,9 @@ static Triple::OSType parseOS(StringRef OSName) { .Default(Triple::UnknownOS); } -static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { - return StringSwitch(EnvironmentName) +static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName, + Triple::VendorType Vendor) { + auto ET = StringSwitch(EnvironmentName) .StartsWith("eabihf", Triple::EABIHF) .StartsWith("eabi", Triple::EABI) .StartsWith("gnuabi64", Triple::GNUABI64) @@ -503,6 +508,26 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { .StartsWith("coreclr", Triple::CoreCLR) .StartsWith("opencl", Triple::OpenCL) .Default(Triple::UnknownEnvironment); + + // Gentoo abuses the vendor field for softfloat/hardfloat ARM + // e.g. arm-softfloat-linux-gnueabi, arm-hardfloat-linux-gnueabi + if (Vendor == Triple::HardFloat) { + switch (ET) { + case Triple::EABI: + ET = Triple::EABIHF; + break; + case Triple::GNUEABI: + ET = Triple::GNUEABIHF; + break; + case Triple::MuslEABI: + ET = Triple::MuslEABIHF; + break; + default: + break; + } + } + + return ET; } static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) { @@ -670,7 +695,7 @@ Triple::Triple(const Twine &Str) if (Components.size() > 2) { OS = parseOS(Components[2]); if (Components.size() > 3) { - Environment = parseEnvironment(Components[3]); + Environment = parseEnvironment(Components[3], Vendor); ObjectFormat = parseFormat(Components[3]); } } @@ -709,7 +734,7 @@ Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, SubArch(parseSubArch(ArchStr.str())), Vendor(parseVendor(VendorStr.str())), OS(parseOS(OSStr.str())), - Environment(parseEnvironment(EnvironmentStr.str())), + Environment(parseEnvironment(EnvironmentStr.str(), Vendor)), ObjectFormat(parseFormat(EnvironmentStr.str())) { if (ObjectFormat == Triple::UnknownObjectFormat) ObjectFormat = getDefaultFormat(*this); @@ -742,7 +767,7 @@ std::string Triple::normalize(StringRef Str) { } EnvironmentType Environment = UnknownEnvironment; if (Components.size() > 3) - Environment = parseEnvironment(Components[3]); + Environment = parseEnvironment(Components[3], Vendor); ObjectFormatType ObjectFormat = UnknownObjectFormat; if (Components.size() > 4) ObjectFormat = parseFormat(Components[4]); @@ -787,7 +812,7 @@ std::string Triple::normalize(StringRef Str) { Valid = OS != UnknownOS || IsCygwin || IsMinGW32; break; case 3: - Environment = parseEnvironment(Comp); + Environment = parseEnvironment(Comp, Vendor); Valid = Environment != UnknownEnvironment; if (!Valid) { ObjectFormat = parseFormat(Comp); --- a/unittests/ADT/TripleTest.cpp +++ a/unittests/ADT/TripleTest.cpp @@ -284,6 +284,19 @@ TEST(TripleTest, ParsedIDs) { EXPECT_EQ(Triple::FreeBSD, T.getOS()); EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); + // Triples used for Gentoo ARM targets + T = Triple("armv5tel-softfloat-linux-gnueabi"); + EXPECT_EQ(Triple::arm, T.getArch()); + EXPECT_EQ(Triple::SoftFloat, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::GNUEABI, T.getEnvironment()); + + T = Triple("armv7a-hardfloat-linux-gnueabi"); + EXPECT_EQ(Triple::arm, T.getArch()); + EXPECT_EQ(Triple::HardFloat, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::GNUEABIHF, T.getEnvironment()); + T = Triple("huh"); EXPECT_EQ(Triple::UnknownArch, T.getArch()); } --