aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r--gcc/config/rs6000/rs6000.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 512e7d65632..824e2d308e0 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -29100,6 +29100,15 @@ rs6000_elf_asm_out_destructor (rtx symbol, int priority)
assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
}
+#ifdef HAVE_LD_OVERLAPPING_OPD
+/* If the linker supports overlapping .opd entries and we know this function
+ doesn't ever use r11 passed to it, we can overlap the fd_aux function
+ descriptor field with next function descriptor's fd_func field. */
+# define OVERLAPPING_OPD (cfun->static_chain_decl == NULL)
+#else
+# define OVERLAPPING_OPD 0
+#endif
+
void
rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
{
@@ -29109,7 +29118,8 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
ASM_OUTPUT_LABEL (file, name);
fputs (DOUBLE_INT_ASM_OP, file);
rs6000_output_function_entry (file, name);
- fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
+ fprintf (file, ",.TOC.@tocbase%s\n\t.previous\n",
+ OVERLAPPING_OPD ? "" : ",0");
if (DOT_SYMBOLS)
{
fputs ("\t.size\t", file);
@@ -29200,6 +29210,13 @@ rs6000_elf_file_end (void)
#if defined (POWERPC_LINUX) || defined (POWERPC_FREEBSD)
if (TARGET_32BIT || DEFAULT_ABI == ABI_ELFv2)
file_end_indicate_exec_stack ();
+ else
+ {
+ int saved_trampolines_created = trampolines_created;
+ trampolines_created = 0;
+ file_end_indicate_exec_stack ();
+ trampolines_created = saved_trampolines_created;
+ }
#endif
}
#endif