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.

llvm-svn: 123990
This commit is contained in:
Renato Golin 2011-01-21 18:25:47 +00:00
parent fee882c203
commit 83758d5cd7
3 changed files with 53 additions and 9 deletions

View File

@ -72,7 +72,8 @@ public:
UnknownVendor,
Apple,
PC
PC,
NoVendor
};
enum OSType {
UnknownOS,
@ -92,10 +93,15 @@ public:
Solaris,
Win32,
Haiku,
Minix
Minix,
NoOS
};
enum EnvironmentType {
UnknownEnvironment
UnknownEnvironment,
GNU,
GNUEABI,
EABI
};
private:

View File

@ -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]);

View File

@ -85,9 +85,7 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::x86_64, T.getArch());
EXPECT_EQ(Triple::PC, T.getVendor());
EXPECT_EQ(Triple::Linux, T.getOS());
// When environments are defined, change this test to verify the "gnu"
// environment.
EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
EXPECT_EQ(Triple::GNU, T.getEnvironment());
T = Triple("powerpc-dunno-notsure");
EXPECT_EQ(Triple::ppc, T.getArch());
@ -95,6 +93,12 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::UnknownOS, T.getOS());
EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
T = Triple("arm-none-eabi");
EXPECT_EQ(Triple::arm, T.getArch());
EXPECT_EQ(Triple::NoVendor, T.getVendor());
EXPECT_EQ(Triple::NoOS, T.getOS());
EXPECT_EQ(Triple::EABI, T.getEnvironment());
T = Triple("huh");
EXPECT_EQ(Triple::UnknownArch, T.getArch());
}
@ -110,6 +114,7 @@ static std::string Join(StringRef A, StringRef B, StringRef C, StringRef D) {
}
TEST(TripleTest, Normalization) {
EXPECT_EQ("", Triple::normalize(""));
EXPECT_EQ("-", Triple::normalize("-"));
EXPECT_EQ("--", Triple::normalize("--"));
@ -144,6 +149,8 @@ TEST(TripleTest, Normalization) {
EXPECT_EQ("-pc", Triple::normalize("pc"));
EXPECT_EQ("--linux", Triple::normalize("linux"));
EXPECT_EQ("x86_64--linux-gnu", Triple::normalize("x86_64-gnu-linux"));
// Check that normalizing a permutated set of valid components returns a
// triple with the unpermuted components.
StringRef C[4];
@ -251,6 +258,7 @@ TEST(TripleTest, MutateName) {
EXPECT_EQ(Triple::PC, T.getVendor());
EXPECT_EQ(Triple::Darwin, T.getOS());
EXPECT_EQ("i386-pc-darwin", T.getTriple());
}
}