]> granicus.if.org Git - clang/commitdiff
Driver: add -m{,no-}long-calls support
authorSaleem Abdulrasool <compnerd@compnerd.org>
Sat, 7 Jun 2014 19:32:38 +0000 (19:32 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Sat, 7 Jun 2014 19:32:38 +0000 (19:32 +0000)
This mirrors the GCC option for the ARM backend.  This option enables the
backend option "-enable-arm-long-calls".  The default behaviour is that this is
disabled due to the slight overhead of the generated calls.

If the target of jumps are greater than 64M range of offset-based jumps, then
the target address must be loaded into a register to make an indirect jump.  The
backend support for this has been present, but was not previously controllable
by the proper flag.

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

include/clang/Driver/Options.td
lib/Driver/Tools.cpp
test/Driver/arm-long-calls.c [new file with mode: 0644]

index 6dc9c23c3703f8bfde83d6196e365dd1204f1994..85f2e0c740b24ff38e82e3eba4823533692604df 100644 (file)
@@ -1106,6 +1106,10 @@ def mcrc : Flag<["-"], "mcrc">, Group<m_arm_Features_Group>,
   HelpText<"Allow use of CRC instructions (ARM only)">;
 def mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>,
   HelpText<"Disallow use of CRC instructions (ARM only)">;
+def mlong_calls : Flag<["-"], "mlong-calls">, Group<m_arm_Features_Group>,
+  HelpText<"Generate an indirect jump to enable jumps further than 64M">;
+def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_arm_Features_Group>,
+  HelpText<"Restore the default behaviour of not generating long calls">;
 
 def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>,
   HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
index 0316357bd162b5f050b03ace4e5c227bf7d9b94a..dfbc280c55c4f2e228587fd414a33107e18c2cda 100644 (file)
@@ -3469,6 +3469,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     CmdArgs.push_back("-arm-restrict-it");
   }
 
+  if (TT.getArch() == llvm::Triple::arm ||
+      TT.getArch() == llvm::Triple::thumb) {
+    if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
+                                 options::OPT_mno_long_calls)) {
+      if (A->getOption().matches(options::OPT_mlong_calls)) {
+        CmdArgs.push_back("-backend-option");
+        CmdArgs.push_back("-enable-arm-long-calls");
+      }
+    }
+  }
+
   // Forward -f options with positive and negative forms; we translate
   // these by hand.
   if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) {
diff --git a/test/Driver/arm-long-calls.c b/test/Driver/arm-long-calls.c
new file mode 100644 (file)
index 0000000..8181f9d
--- /dev/null
@@ -0,0 +1,15 @@
+// RUN: %clang -target armv7-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-DEFAULT
+
+// RUN: %clang -target armv7-eabi -### -mlong-calls %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-LONG-CALLS
+
+// RUN: %clang -target armv7-eabi -### -mlong-calls -mno-long-calls %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-LONG-CALLS
+
+// CHECK-DEFAULT-NOT: "-backend-option" "-enable-arm-long-calls"
+
+// CHECK-LONG-CALLS: "-backend-option" "-enable-arm-long-calls"
+
+// CHECK-NO-LONG-CALLS-NOT: "-backend-option" "-enable-arm-long-calls"
+