]> granicus.if.org Git - clang/commitdiff
[mips] Add support for static model on N64
authorSimon Dardis <simon.dardis@imgtec.com>
Fri, 27 Jan 2017 15:05:25 +0000 (15:05 +0000)
committerSimon Dardis <simon.dardis@imgtec.com>
Fri, 27 Jan 2017 15:05:25 +0000 (15:05 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@293285 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Driver/ToolChains.cpp
lib/Driver/Tools.cpp
test/Driver/mips-as.c

index eb51aaf394d907af06bdef1ce3c756e2061b022e..73bc734aec6b9a1bf745bc0e7ed71b115b71cee1 100644 (file)
@@ -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;
   }
index 854b5d5cccbcccf2c19caee3c851839302cce3fb..ca12a533e97411f7bd74a1f1913e95b2275daacd 100644 (file)
@@ -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)
index 4d956208f064227cb26fc7984d48706e190af708..560b5952db5329faebd411a8600b6a057c0ba5ee 100644 (file)
 // 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"
 //
 //
 // 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 \
 //
 // 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 \
 //
 // 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 \
 //
 // 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
 //
 // 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