configure.ac: Check assembler support for R_PPC64_ENTRY relocation.
authorUlrich Weigand <uweigand@de.ibm.com>
Wed, 2 Dec 2015 19:52:53 +0000 (19:52 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Wed, 2 Dec 2015 19:52:53 +0000 (19:52 +0000)
* configure.ac: Check assembler support for R_PPC64_ENTRY relocation.
* configure: Regenerate.
* config.in: Regenerate.
* config/rs6000/rs6000.c (rs6000_global_entry_point_needed_p): New
function.
(rs6000_output_function_prologue): Use it instead of checking
cfun->machine->r2_setup_needed.  Use internal labels instead of
GNU as local label extension.  Handle ELFv2 large code model.
(rs6000_output_mi_thunk): Do not set cfun->machine->r2_setup_needed.
(rs6000_elf_declare_function_name): Handle ELFv2 large code model.

From-SVN: r231202

gcc/ChangeLog
gcc/config.in
gcc/config/rs6000/rs6000.c
gcc/configure
gcc/configure.ac

index c90a062dd022071a76ad798d0bee6fb85a0bfc25..28ba7fba7dba3bb53abf5a192f0edbb9d722041d 100644 (file)
@@ -1,3 +1,16 @@
+2015-12-02  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
+
+       * configure.ac: Check assembler support for R_PPC64_ENTRY relocation.
+       * configure: Regenerate.
+       * config.in: Regenerate.
+       * config/rs6000/rs6000.c (rs6000_global_entry_point_needed_p): New
+       function.
+       (rs6000_output_function_prologue): Use it instead of checking
+       cfun->machine->r2_setup_needed.  Use internal labels instead of
+       GNU as local label extension.  Handle ELFv2 large code model.
+       (rs6000_output_mi_thunk): Do not set cfun->machine->r2_setup_needed.
+       (rs6000_elf_declare_function_name): Handle ELFv2 large code model.
+
 2015-12-02  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/68647
index bb0d22053e9b73b1469f7bd32f5bb9cfe1207699..a1762bec4367a53460e8ea77029783e9d6c4c9d2 100644 (file)
 #endif
 
 
+/* Define if your assembler supports the R_PPC64_ENTRY relocation. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_ENTRY_MARKERS
+#endif
+
+
 /* Define if your assembler supports explicit relocations. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_AS_EXPLICIT_RELOCS
index d451d7686cccb9f0abf999b8737141479561f766..22eb0e5b713a3fb28747b601d188cc9ce786a044 100644 (file)
@@ -24888,6 +24888,31 @@ split_stack_arg_pointer_used_p (void)
   return bitmap_bit_p (DF_LR_OUT (bb), 12);
 }
 
+/* Return whether we need to emit an ELFv2 global entry point prologue.  */
+
+static bool
+rs6000_global_entry_point_needed_p (void)
+{
+  /* Only needed for the ELFv2 ABI.  */
+  if (DEFAULT_ABI != ABI_ELFv2)
+    return false;
+
+  /* With -msingle-pic-base, we assume the whole program shares the same
+     TOC, so no global entry point prologues are needed anywhere.  */
+  if (TARGET_SINGLE_PIC_BASE)
+    return false;
+
+  /* Ensure we have a global entry point for thunks.   ??? We could
+     avoid that if the target routine doesn't need a global entry point,
+     but we do not know whether this is the case at this point.  */
+  if (cfun->is_thunk)
+    return true;
+
+  /* For regular functions, rs6000_emit_prologue sets this flag if the
+     routine ever uses the TOC pointer.  */
+  return cfun->machine->r2_setup_needed;
+}
+
 /* Emit function prologue as insns.  */
 
 void
@@ -25951,12 +25976,52 @@ rs6000_output_function_prologue (FILE *file,
 
   /* ELFv2 ABI r2 setup code and local entry point.  This must follow
      immediately after the global entry point label.  */
-  if (DEFAULT_ABI == ABI_ELFv2 && cfun->machine->r2_setup_needed)
+  if (rs6000_global_entry_point_needed_p ())
     {
       const char *name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
 
-      fprintf (file, "0:\taddis 2,12,.TOC.-0b@ha\n");
-      fprintf (file, "\taddi 2,2,.TOC.-0b@l\n");
+      (*targetm.asm_out.internal_label) (file, "LCF", rs6000_pic_labelno);
+
+      if (TARGET_CMODEL != CMODEL_LARGE)
+       {
+         /* In the small and medium code models, we assume the TOC is less
+            2 GB away from the text section, so it can be computed via the
+            following two-instruction sequence.  */
+         char buf[256];
+
+         ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
+         fprintf (file, "0:\taddis 2,12,.TOC.-");
+         assemble_name (file, buf);
+         fprintf (file, "@ha\n");
+         fprintf (file, "\taddi 2,2,.TOC.-");
+         assemble_name (file, buf);
+         fprintf (file, "@l\n");
+       }
+      else
+       {
+         /* In the large code model, we allow arbitrary offsets between the
+            TOC and the text section, so we have to load the offset from
+            memory.  The data field is emitted directly before the global
+            entry point in rs6000_elf_declare_function_name.  */
+         char buf[256];
+
+#ifdef HAVE_AS_ENTRY_MARKERS
+         /* If supported by the linker, emit a marker relocation.  If the
+            total code size of the final executable or shared library
+            happens to fit into 2 GB after all, the linker will replace
+            this code sequence with the sequence for the small or medium
+            code model.  */
+         fprintf (file, "\t.reloc .,R_PPC64_ENTRY\n");
+#endif
+         fprintf (file, "\tld 2,");
+         ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
+         assemble_name (file, buf);
+         fprintf (file, "-");
+         ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
+         assemble_name (file, buf);
+         fprintf (file, "(12)\n");
+         fprintf (file, "\tadd 2,2,12\n");
+       }
 
       fputs ("\t.localentry\t", file);
       assemble_name (file, name);
@@ -27620,13 +27685,6 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
   SIBLING_CALL_P (insn) = 1;
   emit_barrier ();
 
-  /* Ensure we have a global entry point for the thunk.   ??? We could
-     avoid that if the target routine doesn't need a global entry point,
-     but we do not know whether this is the case at this point.  */
-  if (DEFAULT_ABI == ABI_ELFv2
-      && !TARGET_SINGLE_PIC_BASE)
-    cfun->machine->r2_setup_needed = true;
-
   /* Run just enough of rest_of_compilation to get the insns emitted.
      There's not really enough bulk here to make other passes such as
      instruction scheduling worth while.  Note that use_thunk calls
@@ -31493,6 +31551,18 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
   ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
   ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
 
+  if (TARGET_CMODEL == CMODEL_LARGE && rs6000_global_entry_point_needed_p ())
+    {
+      char buf[256];
+
+      (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
+
+      fprintf (file, "\t.quad .TOC.-");
+      ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
+      assemble_name (file, buf);
+      putc ('\n', file);
+    }
+
   if (DEFAULT_ABI == ABI_AIX)
     {
       const char *desc_name, *orig_name;
index bb5e02bec505c0710f81bde1ef11b507ce252030..b21c864466d7d19cd8b4aaf35a199519eea029c6 100755 (executable)
@@ -26532,6 +26532,41 @@ if test $gcc_cv_as_powerpc_tls_markers = yes; then
 
 $as_echo "#define HAVE_AS_TLS_MARKERS 1" >>confdefs.h
 
+fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for prologue entry point marker support" >&5
+$as_echo_n "checking assembler for prologue entry point marker support... " >&6; }
+if test "${gcc_cv_as_powerpc_entry_markers+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_powerpc_entry_markers=no
+    if test $in_tree_gas = yes; then
+    if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 26 \) \* 1000 + 0`
+  then gcc_cv_as_powerpc_entry_markers=yes
+fi
+  elif test x$gcc_cv_as != x; then
+    $as_echo ' .reloc .,R_PPC64_ENTRY; nop' > conftest.s
+    if { ac_try='$gcc_cv_as $gcc_cv_as_flags -a64 --fatal-warnings -o conftest.o conftest.s >&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+       gcc_cv_as_powerpc_entry_markers=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_entry_markers" >&5
+$as_echo "$gcc_cv_as_powerpc_entry_markers" >&6; }
+if test $gcc_cv_as_powerpc_entry_markers = yes; then
+
+$as_echo "#define HAVE_AS_ENTRY_MARKERS 1" >>confdefs.h
+
 fi
 
     case $target in
index 5990b7cadebe4dd257963aeb98394f0bb98c77ba..cff95bc9c6d37c433f262f6d985be36bc5f0a02c 100644 (file)
@@ -4371,6 +4371,12 @@ LCF0:
       [AC_DEFINE(HAVE_AS_TLS_MARKERS, 1,
          [Define if your assembler supports arg info for __tls_get_addr.])])
 
+    gcc_GAS_CHECK_FEATURE([prologue entry point marker support],
+      gcc_cv_as_powerpc_entry_markers, [2,26,0],-a64 --fatal-warnings,
+      [ .reloc .,R_PPC64_ENTRY; nop],,
+      [AC_DEFINE(HAVE_AS_ENTRY_MARKERS, 1,
+         [Define if your assembler supports the R_PPC64_ENTRY relocation.])])
+
     case $target in
       *-*-aix*)
        gcc_GAS_CHECK_FEATURE([.ref support],