diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/Targets.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 77 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 11 |
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"); |