diff options
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config.in | 6 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 90 | ||||
-rwxr-xr-x | gcc/configure | 35 | ||||
-rw-r--r-- | gcc/configure.ac | 6 |
5 files changed, 140 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c90a062..28ba7fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config.in b/gcc/config.in index bb0d220..a1762be 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -327,6 +327,12 @@ #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 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d451d76..22eb0e5 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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; diff --git a/gcc/configure b/gcc/configure index bb5e02b..b21c864 100755 --- a/gcc/configure +++ b/gcc/configure @@ -26534,6 +26534,41 @@ $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 *-*-aix*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .ref support" >&5 diff --git a/gcc/configure.ac b/gcc/configure.ac index 5990b7c..cff95bc 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -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], |