summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Targets.cpp16
-rw-r--r--clang/lib/Driver/ToolChains.cpp77
-rw-r--r--clang/lib/Driver/Tools.cpp11
3 files changed, 76 insertions, 28 deletions
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index a38e752c1f9..c45a9ca035a 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -3272,18 +3272,24 @@ namespace {
class X86_64TargetInfo : public X86TargetInfo {
public:
X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
- LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+ const bool IsX32{getTriple().getEnvironment() == llvm::Triple::GNUX32};
+ LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
LongDoubleWidth = 128;
LongDoubleAlign = 128;
LargeArrayMinWidth = 128;
LargeArrayAlign = 128;
SuitableAlign = 128;
- IntMaxType = SignedLong;
- UIntMaxType = UnsignedLong;
- Int64Type = SignedLong;
+ SizeType = IsX32 ? UnsignedInt : UnsignedLong;
+ PtrDiffType = IsX32 ? SignedInt : SignedLong;
+ IntPtrType = IsX32 ? SignedInt : SignedLong;
+ IntMaxType = IsX32 ? SignedLongLong : SignedLong;
+ UIntMaxType = IsX32 ? UnsignedLongLong : UnsignedLong;
+ Int64Type = IsX32 ? SignedLongLong : SignedLong;
RegParmMax = 6;
- DescriptionString = "e-m:e-i64:64-f80:128-n8:16:32:64-S128";
+ DescriptionString = (IsX32)
+ ? "e-m:e-" "p:32:32-" "i64:64-f80:128-n8:16:32:64-S128"
+ : "e-m:e-" "i64:64-f80:128-n8:16:32:64-S128";
// Use fpret only for long double.
RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp
index aba6d38e23d..e403fbe594e 100644
--- a/clang/lib/Driver/ToolChains.cpp
+++ b/clang/lib/Driver/ToolChains.cpp
@@ -1341,8 +1341,9 @@ bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
"x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu",
"x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux",
"x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux",
- "x86_64-linux-android"
+ "x86_64-linux-android", "x86_64-unknown-linux"
};
+ static const char *const X32LibDirs[] = { "/libx32" };
static const char *const X86LibDirs[] = { "/lib32", "/lib" };
static const char *const X86Triples[] = {
"i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu",
@@ -1451,10 +1452,19 @@ bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
TripleAliases.append(X86_64Triples,
X86_64Triples + llvm::array_lengthof(X86_64Triples));
- BiarchLibDirs.append(X86LibDirs,
- X86LibDirs + llvm::array_lengthof(X86LibDirs));
- BiarchTripleAliases.append(X86Triples,
- X86Triples + llvm::array_lengthof(X86Triples));
+ // x32 is always available when x86_64 is available, so adding it as secondary
+ // arch with x86_64 triples
+ if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) {
+ BiarchLibDirs.append(X32LibDirs,
+ X32LibDirs + llvm::array_lengthof(X32LibDirs));
+ BiarchTripleAliases.append(X86_64Triples,
+ X86_64Triples + llvm::array_lengthof(X86_64Triples));
+ } else {
+ BiarchLibDirs.append(X86LibDirs,
+ X86LibDirs + llvm::array_lengthof(X86LibDirs));
+ BiarchTripleAliases.append(X86Triples,
+ X86Triples + llvm::array_lengthof(X86Triples));
+ }
break;
case llvm::Triple::x86:
LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));
@@ -1992,47 +2002,64 @@ static bool findBiarchMultilibs(const llvm::Triple &TargetTriple,
Multilib Alt64 = Multilib()
.gccSuffix("/64")
.includeSuffix("/64")
- .flag("-m32").flag("+m64");
+ .flag("-m32").flag("+m64").flag("-mx32");
Multilib Alt32 = Multilib()
.gccSuffix("/32")
.includeSuffix("/32")
- .flag("+m32").flag("-m64");
+ .flag("+m32").flag("-m64").flag("-mx32");
+ Multilib Altx32 = Multilib()
+ .gccSuffix("/x32")
+ .includeSuffix("/x32")
+ .flag("-m32").flag("-m64").flag("+mx32");
FilterNonExistent NonExistent(Path);
- // Decide whether the default multilib is 32bit, correcting for
- // when the default multilib and the alternate appear backwards
- bool DefaultIs32Bit;
+ // Determine default multilib from: 32, 64, x32
+ // Also handle cases such as 64 on 32, 32 on 64, etc.
+ enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;
+ const bool isX32 {TargetTriple.getEnvironment() == llvm::Triple::GNUX32};
if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))
- DefaultIs32Bit = false;
- else if (TargetTriple.isArch64Bit() && !NonExistent(Alt64))
- DefaultIs32Bit = true;
+ Want = WANT64;
+ else if (TargetTriple.isArch64Bit() && isX32 && !NonExistent(Altx32))
+ Want = WANT64;
+ else if (TargetTriple.isArch64Bit() && !isX32 && !NonExistent(Alt64))
+ Want = WANT32;
else {
- if (NeedsBiarchSuffix)
- DefaultIs32Bit = TargetTriple.isArch64Bit();
+ if (TargetTriple.isArch32Bit())
+ Want = NeedsBiarchSuffix ? WANT64 : WANT32;
+ else if (isX32)
+ Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
else
- DefaultIs32Bit = TargetTriple.isArch32Bit();
+ Want = NeedsBiarchSuffix ? WANT32 : WANT64;
}
- if (DefaultIs32Bit)
- Default.flag("+m32").flag("-m64");
+ if (Want == WANT32)
+ Default.flag("+m32").flag("-m64").flag("-mx32");
+ else if (Want == WANT64)
+ Default.flag("-m32").flag("+m64").flag("-mx32");
+ else if (Want == WANTX32)
+ Default.flag("-m32").flag("-m64").flag("+mx32");
else
- Default.flag("-m32").flag("+m64");
+ return false;
Result.Multilibs.push_back(Default);
Result.Multilibs.push_back(Alt64);
Result.Multilibs.push_back(Alt32);
+ Result.Multilibs.push_back(Altx32);
Result.Multilibs.FilterOut(NonExistent);
Multilib::flags_list Flags;
- addMultilibFlag(TargetTriple.isArch64Bit(), "m64", Flags);
+ addMultilibFlag(TargetTriple.isArch64Bit() && !isX32, "m64", Flags);
addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags);
+ addMultilibFlag(TargetTriple.isArch64Bit() && isX32, "mx32", Flags);
if (!Result.Multilibs.select(Flags, Result.SelectedMultilib))
return false;
- if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32)
+ if (Result.SelectedMultilib == Alt64 ||
+ Result.SelectedMultilib == Alt32 ||
+ Result.SelectedMultilib == Altx32)
Result.BiarchSibling = Default;
return true;
@@ -2949,7 +2976,9 @@ static std::string getMultiarchTriple(const llvm::Triple &TargetTriple,
return "i386-linux-gnu";
return TargetTriple.str();
case llvm::Triple::x86_64:
- if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
+ // We don't want this for x32, otherwise it will match x86_64 libs
+ if (TargetTriple.getEnvironment() != llvm::Triple::GNUX32 &&
+ llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
return "x86_64-linux-gnu";
return TargetTriple.str();
case llvm::Triple::arm64:
@@ -3025,6 +3054,10 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
Triple.getArch() == llvm::Triple::ppc)
return "lib32";
+ if (Triple.getArch() == llvm::Triple::x86_64 &&
+ Triple.getEnvironment() == llvm::Triple::GNUX32)
+ return "libx32";
+
return Triple.isArch32Bit() ? "lib" : "lib64";
}
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 4c5b3ea627f..0c2f5264d26 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -6848,7 +6848,10 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
if (getToolChain().getArch() == llvm::Triple::x86) {
CmdArgs.push_back("--32");
} else if (getToolChain().getArch() == llvm::Triple::x86_64) {
- CmdArgs.push_back("--64");
+ if (getToolChain().getTriple().getEnvironment() == llvm::Triple::GNUX32)
+ CmdArgs.push_back("--x32");
+ else
+ CmdArgs.push_back("--64");
} else if (getToolChain().getArch() == llvm::Triple::ppc) {
CmdArgs.push_back("-a32");
CmdArgs.push_back("-mppc");
@@ -7048,6 +7051,9 @@ static StringRef getLinuxDynamicLinker(const ArgList &Args,
return "/lib64/ld64.so.2";
else if (ToolChain.getArch() == llvm::Triple::sparcv9)
return "/lib64/ld-linux.so.2";
+ else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
+ ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32)
+ return "/libx32/ld-linux-x32.so.2";
else
return "/lib64/ld-linux-x86-64.so.2";
}
@@ -7158,6 +7164,9 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
}
else if (ToolChain.getArch() == llvm::Triple::systemz)
CmdArgs.push_back("elf64_s390");
+ else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
+ ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32)
+ CmdArgs.push_back("elf32_x86_64");
else
CmdArgs.push_back("elf_x86_64");
OpenPOWER on IntegriCloud