Index: cfe/trunk/lib/Driver/ToolChains.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains.cpp +++ cfe/trunk/lib/Driver/ToolChains.cpp @@ -2892,6 +2892,9 @@ 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; } Index: cfe/trunk/lib/Driver/Tools.cpp =================================================================== --- cfe/trunk/lib/Driver/Tools.cpp +++ cfe/trunk/lib/Driver/Tools.cpp @@ -1540,8 +1540,54 @@ 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 @@ 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 @@ // 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) Index: cfe/trunk/test/Driver/mips-as.c =================================================================== --- cfe/trunk/test/Driver/mips-as.c +++ cfe/trunk/test/Driver/mips-as.c @@ -21,17 +21,32 @@ // MIPS32R2-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EL" // // RUN: %clang -target mips64-linux-gnu -### \ -// RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: -no-integrated-as -fno-pic -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS64R2-EB-AS %s -// MIPS64R2-EB-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS64R2-EB-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-EB" // -// RUN: %clang -target mips64el-linux-gnu -### \ +// RUN: %clang -target mips64-linux-gnu -### \ // RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS64R2-EB-AS-PIC %s +// MIPS64R2-EB-AS-PIC: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB" "-KPIC" +// +// RUN: %clang -target mips64el-linux-gnu -### \ +// RUN: -no-integrated-as -c -fno-pic %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS64R2-DEF-EL-AS %s -// MIPS64R2-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-KPIC" "-EL" +// MIPS64R2-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-EL" +// +// RUN: %clang -target mips64el-linux-gnu -### \ +// RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS64R2-DEF-EL-AS-PIC %s +// MIPS64R2-DEF-EL-AS-PIC: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EL" "-KPIC" // // RUN: %clang -target mips64-linux-gnu -mabi=n32 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-N32-PIC %s +// MIPS-N32-PIC: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "n32" "-call_nonpic" "-EB" "-KPIC" +// +// RUN: %clang -target mips64-linux-gnu -mabi=n32 -### \ +// RUN: -no-integrated-as -c %s -fno-pic 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-N32 %s // MIPS-N32: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "n32" "-mno-shared" "-call_nonpic" "-EB" // @@ -45,8 +60,13 @@ // // RUN: %clang -target mips64el-linux-gnu -mabi=64 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS64R2-EL-AS-PIC %s +// MIPS64R2-EL-AS-PIC: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EL" "-KPIC" +// +// RUN: %clang -target mips64el-linux-gnu -mabi=64 -### \ +// RUN: -no-integrated-as -c %s -fno-pic 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS64R2-EL-AS %s -// MIPS64R2-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-KPIC" "-EL" +// MIPS64R2-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-EL" // // RUN: %clang -target mips-linux-gnu -march=mips32r2 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ @@ -60,8 +80,13 @@ // // RUN: %clang -target mips64-linux-gnu -march=octeon -### \ // RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-OCTEON-PIC %s +// MIPS-OCTEON-PIC: as{{(.exe)?}}" "-march" "octeon" "-mabi" "64" "-EB" "-KPIC" +// +// RUN: %clang -target mips64-linux-gnu -march=octeon -### \ +// RUN: -no-integrated-as -c %s -fno-pic 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-OCTEON %s -// MIPS-OCTEON: as{{(.exe)?}}" "-march" "octeon" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS-OCTEON: as{{(.exe)?}}" "-march" "octeon" "-mabi" "64" "-mno-shared" "-EB" // // RUN: %clang -target mips-linux-gnu -mips1 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ @@ -115,28 +140,48 @@ // // RUN: %clang -target mips64-linux-gnu -mips64 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ALIAS-64-PIC %s +// MIPS-ALIAS-64-PIC: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB" "-KPIC" +// +// RUN: %clang -target mips64-linux-gnu -mips64 -### \ +// RUN: -no-integrated-as -c -fno-pic %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ALIAS-64 %s -// MIPS-ALIAS-64: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS-ALIAS-64: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-mno-shared" "-EB" // // RUN: %clang -target mips64-linux-gnu -mips64r2 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ -// RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R2 %s -// MIPS-ALIAS-64R2: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R2-PIC %s +// MIPS-ALIAS-64R2-PIC: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB" "-KPIC" // // RUN: %clang -target mips64-linux-gnu -mips64r3 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R3-PIC %s +// MIPS-ALIAS-64R3-PIC: as{{(.exe)?}}" "-march" "mips64r3" "-mabi" "64" "-EB" "-KPIC" +// +// RUN: %clang -target mips64-linux-gnu -mips64r3 -### \ +// RUN: -no-integrated-as -c %s -fno-pic 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R3 %s -// MIPS-ALIAS-64R3: as{{(.exe)?}}" "-march" "mips64r3" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS-ALIAS-64R3: as{{(.exe)?}}" "-march" "mips64r3" "-mabi" "64" "-mno-shared" "-EB" // // RUN: %clang -target mips64-linux-gnu -mips64r5 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R5-PIC %s +// MIPS-ALIAS-64R5-PIC: as{{(.exe)?}}" "-march" "mips64r5" "-mabi" "64" "-EB" "-KPIC" +// +// RUN: %clang -target mips64-linux-gnu -mips64r5 -### \ +// RUN: -no-integrated-as -c %s -fno-pic 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R5 %s -// MIPS-ALIAS-64R5: as{{(.exe)?}}" "-march" "mips64r5" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS-ALIAS-64R5: as{{(.exe)?}}" "-march" "mips64r5" "-mabi" "64" "-mno-shared" "-EB" // // RUN: %clang -target mips64-linux-gnu -mips64r6 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R6-PIC %s +// MIPS-ALIAS-64R6-PIC: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-EB" "-KPIC" +// +// RUN: %clang -target mips64-linux-gnu -mips64r6 -### \ +// RUN: -no-integrated-as -c %s -fno-pic 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R6 %s -// MIPS-ALIAS-64R6: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS-ALIAS-64R6: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-mno-shared" "-EB" // // RUN: %clang -target mips-linux-gnu -mno-mips16 -mips16 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ @@ -234,15 +279,15 @@ // // RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips3 \ // RUN: 2>&1 | FileCheck -check-prefix=MIPS3-EB-AS %s -// MIPS3-EB-AS: as{{(.exe)?}}" "-march" "mips3" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS3-EB-AS: as{{(.exe)?}}" "-march" "mips3" "-mabi" "64" "-EB" "-KPIC" // // RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips4 \ // RUN: 2>&1 | FileCheck -check-prefix=MIPS4-EB-AS %s -// MIPS4-EB-AS: as{{(.exe)?}}" "-march" "mips4" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS4-EB-AS: as{{(.exe)?}}" "-march" "mips4" "-mabi" "64" "-EB" "-KPIC" // // RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips5 \ // RUN: 2>&1 | FileCheck -check-prefix=MIPS5-EB-AS %s -// MIPS5-EB-AS: as{{(.exe)?}}" "-march" "mips5" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS5-EB-AS: as{{(.exe)?}}" "-march" "mips5" "-mabi" "64" "-EB" "-KPIC" // // RUN: %clang -target mips-linux-gnu -### -no-integrated-as -c %s -mcpu=mips32 \ // RUN: 2>&1 | FileCheck -check-prefix=MIPS32-EB-AS %s @@ -256,11 +301,11 @@ // // RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips64 \ // RUN: 2>&1 | FileCheck -check-prefix=MIPS64-EB-AS %s -// MIPS64-EB-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS64-EB-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB" "-KPIC" // // RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips64r6 \ // RUN: 2>&1 | FileCheck -check-prefix=MIPS64R6-EB-AS %s -// MIPS64R6-EB-AS: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-mno-shared" "-KPIC" "-EB" +// MIPS64R6-EB-AS: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-EB" "-KPIC" // // RUN: %clang -target mips-linux-gnu -### -no-integrated-as -msoft-float -mhard-float -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=HARDFLOAT --implicit-check-not=-msoft-float %s