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
This commit is contained in:
Alan Modra 2011-08-02 00:35:24 +09:30 committed by Alan Modra
parent 607d0635d8
commit bd15e32c71
5 changed files with 57 additions and 29 deletions

View file

@ -1,5 +1,15 @@
2011-08-02 Alan Modra <amodra@gmail.com>
* 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.
2011-08-01 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr-devices.c: Delete SVN property svn:executable.
* config/avr/predicates.md: Ditto.
* config/avr/driver-avr.c: Ditto.
@ -137,7 +147,7 @@
(loop_carried_phi): Likewise.
(propagate_rank): Likewise.
(get_rank): Add calls to phi_rank and propagate_rank.
2011-07-31 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/x86-64.h (SIZE_TYPE): Check TARGET_LP64 instead

View file

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

View file

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

View file

@ -1,3 +1,9 @@
2011-08-02 Alan Modra <amodra@gmail.com>
* 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.
2011-08-01 Julian Brown <julian@codesourcery.com>
* config.host (arm*-*-linux*, arm*-*-uclinux*, arm*-*-eabi*)

View file

@ -354,20 +354,22 @@ frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATT
/* We are in a plt call stub or r2 adjusting long branch stub,
before r2 has been saved. Keep REG_UNSAVED. */
}
else if (pc[0] == 0x4E800421
&& pc[1] == 0xE8410028)
{
/* We are at the bctrl instruction in a call via function
pointer. gcc always emits the load of the new r2 just
before the bctrl. */
_Unwind_SetGRPtr (context, 2, context->cfa + 40);
}
else
{
unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, R_LR);
if (insn && *insn == 0xE8410028)
_Unwind_SetGRPtr (context, 2, context->cfa + 40);
else if (pc[0] == 0x4E800421
&& pc[1] == 0xE8410028)
{
/* We are at the bctrl instruction in a call via function
pointer. gcc always emits the load of the new R2 just
before the bctrl so this is the first and only place
we need to use the stored R2. */
_Unwind_Word sp = _Unwind_GetGR (context, 1);
_Unwind_SetGRPtr (context, 2, sp + 40);
}
}
}
#endif