configure.ac: Check assembler support for R_PPC64_ENTRY relocation.

* 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
This commit is contained in:
Ulrich Weigand 2015-12-02 19:52:53 +00:00 committed by Ulrich Weigand
parent 8923e02ee4
commit 157bb85d48
5 changed files with 140 additions and 10 deletions

View 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

View file

@ -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

View 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;

35
gcc/configure vendored
View file

@ -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

View 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],