From: Saleem Abdulrasool Date: Sat, 7 Jun 2014 19:32:38 +0000 (+0000) Subject: Driver: add -m{,no-}long-calls support X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c2c5f2f7b54d201ca63828cf63fbe5c808ef9b94;p=clang Driver: add -m{,no-}long-calls support 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 --- diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 6dc9c23c37..85f2e0c740 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -1106,6 +1106,10 @@ def mcrc : Flag<["-"], "mcrc">, Group, HelpText<"Allow use of CRC instructions (ARM only)">; def mnocrc : Flag<["-"], "mnocrc">, Group, HelpText<"Disallow use of CRC instructions (ARM only)">; +def mlong_calls : Flag<["-"], "mlong-calls">, Group, + HelpText<"Generate an indirect jump to enable jumps further than 64M">; +def mno_long_calls : Flag<["-"], "mno-long-calls">, Group, + HelpText<"Restore the default behaviour of not generating long calls">; def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group, HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 0316357bd1..dfbc280c55 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -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 index 0000000000..8181f9d0f4 --- /dev/null +++ b/test/Driver/arm-long-calls.c @@ -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" +