diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 60 |
2 files changed, 60 insertions, 3 deletions
diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index eb51aaf394d..73bc734aec6 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -2892,6 +2892,9 @@ bool Generic_GCC::isPICDefault() const { case llvm::Triple::ppc64: case llvm::Triple::ppc64le: return !getTriple().isOSBinFormatMachO() && !getTriple().isMacOSX(); + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + return true; default: return false; } diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 854b5d5cccb..ca12a533e97 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1540,8 +1540,54 @@ static void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName); ABIName = getGnuCompatibleMipsABIName(ABIName); - AddTargetFeature(Args, Features, options::OPT_mno_abicalls, - options::OPT_mabicalls, "noabicalls"); + // Historically, PIC code for MIPS was associated with -mabicalls, a.k.a + // SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI + // extension was developed by Richard Sandiford & Code Sourcery to support + // static code calling PIC code (CPIC). For O32 and N32 this means we have + // several combinations of PIC/static and abicalls. Pure static, static + // with the CPIC extension, and pure PIC code. + + // At final link time, O32 and N32 with CPIC will have another section + // added to the binary which contains the stub functions to perform + // any fixups required for PIC code. + + // For N64, the situation is more regular: code can either be static + // (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code + // code for N64. Since Clang has already built the relocation model portion + // of the commandline, we pick add +noabicalls feature in the N64 static + // case. + + // The is another case to be accounted for: -msym32, which enforces that all + // symbols have 32 bits in size. In this case, N64 can in theory use CPIC + // but it is unsupported. + + // The combinations for N64 are: + // a) Static without abicalls and 64bit symbols. + // b) Static with abicalls and 32bit symbols. + // c) PIC with abicalls and 64bit symbols. + + // For case (a) we need to add +noabicalls for N64. + + bool IsN64 = ABIName == "64"; + bool NonPIC = false; + + Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, + options::OPT_fpic, options::OPT_fno_pic, + options::OPT_fPIE, options::OPT_fno_PIE, + options::OPT_fpie, options::OPT_fno_pie); + if (LastPICArg) { + Option O = LastPICArg->getOption(); + NonPIC = + (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) || + O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie)); + } + + if (IsN64 && NonPIC) { + Features.push_back("+noabicalls"); + } else { + AddTargetFeature(Args, Features, options::OPT_mno_abicalls, + options::OPT_mabicalls, "noabicalls"); + } mips::FloatABI FloatABI = getMipsFloatABI(D, Args); if (FloatABI == mips::FloatABI::Soft) { @@ -3973,6 +4019,13 @@ ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { if ((ROPI || RWPI) && (PIC || PIE)) ToolChain.getDriver().Diag(diag::err_drv_ropi_rwpi_incompatible_with_pic); + // When targettng MIPS64 with N64, the default is PIC, unless -mno-abicalls is + // used. + if ((Triple.getArch() == llvm::Triple::mips64 || + Triple.getArch() == llvm::Triple::mips64el) && + Args.hasArg(options::OPT_mno_abicalls)) + return std::make_tuple(llvm::Reloc::Static, 0U, false); + if (PIC) return std::make_tuple(llvm::Reloc::PIC_, IsPICLevelTwo ? 2U : 1U, PIE); @@ -9856,7 +9909,8 @@ void gnutools::Assembler::ConstructJob(Compilation &C, const JobAction &JA, // LLVM doesn't support -mplt yet and acts as if it is always given. // However, -mplt has no effect with the N64 ABI. - CmdArgs.push_back(ABIName == "64" ? "-KPIC" : "-call_nonpic"); + if (ABIName != "64" && !Args.hasArg(options::OPT_mno_abicalls)) + CmdArgs.push_back("-call_nonpic"); if (getToolChain().getArch() == llvm::Triple::mips || getToolChain().getArch() == llvm::Triple::mips64) |