diff options
author | Simon Dardis <simon.dardis@imgtec.com> | 2017-01-27 15:05:25 +0000 |
---|---|---|
committer | Simon Dardis <simon.dardis@imgtec.com> | 2017-01-27 15:05:25 +0000 |
commit | 9e962add708d450230cfa2d754082f1eaf95a2ec (patch) | |
tree | 12a57c2519e17e0c656c3d7df54b59444667dd0b /clang/lib/Driver/Tools.cpp | |
parent | 5191c6f9456f893ff6160b83b6a5d816c0535fff (diff) | |
download | bcm5719-llvm-9e962add708d450230cfa2d754082f1eaf95a2ec.tar.gz bcm5719-llvm-9e962add708d450230cfa2d754082f1eaf95a2ec.zip |
[mips] Add support for static model on N64
The patch teaches the Clang driver how to handle the N64 static
relocation model properly. It enforces the correct target feature
(+noabicalls) when -fno-pic is used. This is required as non-pic
N64 code as the abi extension to call PIC code (CPIC) is unsupported.
Make PIC the default for mips64 and mips64el, this affects both N32
& N64 ABIs, to better match GCC.
As part of this effort, clean up the assembler invocation command
builder, so the correct flags are used.
This and r293279 in LLVM resolves PR/23485.
Thanks to Brooks Davis for reporting the issue!
Reviewers: slthakur, seanbruno
Differential Revision: https://reviews.llvm.org/D29031
llvm-svn: 293285
Diffstat (limited to 'clang/lib/Driver/Tools.cpp')
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 60 |
1 files changed, 57 insertions, 3 deletions
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) |