aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2011-08-02 00:35:24 +0930
committerAlan Modra <amodra@gcc.gnu.org>2011-08-02 00:35:24 +0930
commitbd15e32c71b65cf399dfe72708b8ab3f35550dfe (patch)
treec6bcd1e86393045e79e0942fc18bb2e86285cf56 /gcc/config
parent607d0635d893d141b3d4fd682b625df70b52a805 (diff)
downloadgcc-bd15e32c71b65cf399dfe72708b8ab3f35550dfe.zip
gcc-bd15e32c71b65cf399dfe72708b8ab3f35550dfe.tar.gz
gcc-bd15e32c71b65cf399dfe72708b8ab3f35550dfe.tar.bz2
linux-unwind.h (frob_update_context <__powerpc64__>): Restore for indirect call bcrtl from correct stack slot...
libgcc/ * config/rs6000/linux-unwind.h (frob_update_context <__powerpc64__>): Restore for indirect call bcrtl from correct stack slot, and only if cfa+40 isn't valid. gcc/ * config/rs6000/rs6000-protos.h (rs6000_save_toc_in_prologue_p): Delete. * config/rs6000/rs6000.c (rs6000_save_toc_in_prologue_p): Make static. (rs6000_emit_prologue): Don't prematurely return when TARGET_SINGLE_PIC_BASE. Don't emit eh_frame info in save_toc_in_prologue case. (rs6000_call_indirect_aix): Only disallow save_toc_in_prologue for calls_alloca. From-SVN: r177041
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/rs6000/rs6000-protos.h2
-rw-r--r--gcc/config/rs6000/rs6000.c46
2 files changed, 29 insertions, 19 deletions
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 357f7e7..73da0f6 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -172,8 +172,6 @@ extern void rs6000_emit_epilogue (int);
extern void rs6000_emit_eh_reg_restore (rtx, rtx);
extern const char * output_isel (rtx *);
extern void rs6000_call_indirect_aix (rtx, rtx, rtx);
-extern bool rs6000_save_toc_in_prologue_p (void);
-
extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
/* Declare functions in rs6000-c.c */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index fa367fe..dcf7856 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1178,6 +1178,7 @@ static void rs6000_conditional_register_usage (void);
static void rs6000_trampoline_init (rtx, tree, rtx);
static bool rs6000_cannot_force_const_mem (enum machine_mode, rtx);
static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
+static bool rs6000_save_toc_in_prologue_p (void);
/* Hash table stuff for keeping track of TOC entries. */
@@ -20478,14 +20479,12 @@ rs6000_emit_prologue (void)
insn = emit_insn (generate_set_vrsave (reg, info, 0));
}
- if (TARGET_SINGLE_PIC_BASE)
- return; /* Do not set PIC register */
-
/* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
- if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
- || (DEFAULT_ABI == ABI_V4
- && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
- && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
+ if (!TARGET_SINGLE_PIC_BASE
+ && ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
+ || (DEFAULT_ABI == ABI_V4
+ && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
+ && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))))
{
/* If emit_load_toc_table will use the link register, we need to save
it. We use R12 for this purpose because emit_load_toc_table
@@ -20513,7 +20512,8 @@ rs6000_emit_prologue (void)
}
#if TARGET_MACHO
- if (DEFAULT_ABI == ABI_DARWIN
+ if (!TARGET_SINGLE_PIC_BASE
+ && DEFAULT_ABI == ABI_DARWIN
&& flag_pic && crtl->uses_pic_offset_table)
{
rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
@@ -20534,10 +20534,26 @@ rs6000_emit_prologue (void)
}
#endif
- /* If we need to, save the TOC register after doing the stack setup. */
+ /* If we need to, save the TOC register after doing the stack setup.
+ Do not emit eh frame info for this save. The unwinder wants info,
+ conceptually attached to instructions in this function, about
+ register values in the caller of this function. This R2 may have
+ already been changed from the value in the caller.
+ We don't attempt to write accurate DWARF EH frame info for R2
+ because code emitted by gcc for a (non-pointer) function call
+ doesn't save and restore R2. Instead, R2 is managed out-of-line
+ by a linker generated plt call stub when the function resides in
+ a shared library. This behaviour is costly to describe in DWARF,
+ both in terms of the size of DWARF info and the time taken in the
+ unwinder to interpret it. R2 changes, apart from the
+ calls_eh_return case earlier in this function, are handled by
+ linux-unwind.h frob_update_context. */
if (rs6000_save_toc_in_prologue_p ())
- emit_frame_save (sp_reg_rtx, sp_reg_rtx, reg_mode, TOC_REGNUM,
- 5 * reg_size, info->total_size);
+ {
+ rtx addr = gen_rtx_PLUS (Pmode, sp_reg_rtx, GEN_INT (5 * reg_size));
+ rtx mem = gen_frame_mem (reg_mode, addr);
+ emit_move_insn (mem, gen_rtx_REG (reg_mode, TOC_REGNUM));
+ }
}
/* Write function prologue. */
@@ -27795,10 +27811,7 @@ rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag)
/* Can we optimize saving the TOC in the prologue or do we need to do it at
every call? */
- if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca
- && !cfun->calls_setjmp && !cfun->has_nonlocal_label
- && !cfun->can_throw_non_call_exceptions
- && ((flags_from_decl_or_type (cfun->decl) & ECF_NOTHROW) == ECF_NOTHROW))
+ if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca)
cfun->machine->save_toc_in_prologue = true;
else
@@ -27834,13 +27847,12 @@ rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag)
insn = call_func (func_addr, flag, func_toc_mem, stack_toc_mem);
emit_call_insn (insn);
- return;
}
/* Return whether we need to always update the saved TOC pointer when we update
the stack pointer. */
-bool
+static bool
rs6000_save_toc_in_prologue_p (void)
{
return (cfun && cfun->machine && cfun->machine->save_toc_in_prologue);