Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -3252,18 +3252,27 @@ 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; + if (IsX32) { + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + IntPtrType = SignedInt; + } else { + IntMaxType = SignedLong; + UIntMaxType = UnsignedLong; + Int64Type = 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); Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -1943,6 +1943,26 @@ FilterNonExistent NonExistent(Path); + // For x32 case enforce single lib support for now. + // In fact there can be 3 libs support like in GCC controlled by + // flags -m32/-m64/-mx32. + if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) { + Multilib Altx32 = Multilib() + .gccSuffix("/x32") + .includeSuffix("/x32") + .flag("+mx32") + .flag("-m64") + .flag("-m32"); + + Result.Multilibs.push_back(Altx32); + Result.Multilibs.FilterOut(NonExistent); + + Multilib::flags_list Flags; + addMultilibFlag(true, "mx32", Flags); + Result.BiarchSibling = Alt64; + + return Result.Multilibs.select(Flags, Result.SelectedMultilib); + } // Decide whether the default multilib is 32bit, correcting for // when the default multilib and the alternate appear backwards bool DefaultIs32Bit; @@ -2889,7 +2909,8 @@ return "i386-linux-gnu"; return TargetTriple.str(); case llvm::Triple::x86_64: - if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu")) + if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu") && + TargetTriple.getEnvironment() != llvm::Triple::GNUX32) return "x86_64-linux-gnu"; return TargetTriple.str(); case llvm::Triple::arm64: @@ -2953,6 +2974,9 @@ Triple.getArch() == llvm::Triple::ppc) return "lib32"; + if (Triple.getEnvironment() == llvm::Triple::GNUX32) + return "libx32"; + return Triple.isArch32Bit() ? "lib" : "lib64"; } Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -6727,6 +6727,9 @@ CmdArgs.push_back("--32"); } else if (getToolChain().getArch() == llvm::Triple::x86_64) { CmdArgs.push_back("--64"); + } else if (getToolChain().getTriple().getEnvironment() == + llvm::Triple::GNUX32) { + CmdArgs.push_back("--x32"); } else if (getToolChain().getArch() == llvm::Triple::ppc) { CmdArgs.push_back("-a32"); CmdArgs.push_back("-mppc"); @@ -6922,6 +6925,8 @@ return "/lib64/ld64.so.1"; else if (ToolChain.getArch() == llvm::Triple::sparcv9) return "/lib64/ld-linux.so.2"; + else if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32) + return "/libx32/ld-linux-x32.so.2"; else return "/lib64/ld-linux-x86-64.so.2"; } @@ -7032,6 +7037,8 @@ } else if (ToolChain.getArch() == llvm::Triple::systemz) CmdArgs.push_back("elf64_s390"); + else if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32) + CmdArgs.push_back("elf32_x86_64"); else CmdArgs.push_back("elf_x86_64");