Commit bd15e32c by Alan Modra Committed by Alan Modra

linux-unwind.h (frob_update_context <__powerpc64__>): Restore for indirect call…

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
parent 607d0635
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> 2011-08-01 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr-devices.c: Delete SVN property svn:executable. * config/avr/avr-devices.c: Delete SVN property svn:executable.
* config/avr/predicates.md: Ditto. * config/avr/predicates.md: Ditto.
* config/avr/driver-avr.c: Ditto. * config/avr/driver-avr.c: Ditto.
...@@ -137,7 +147,7 @@ ...@@ -137,7 +147,7 @@
(loop_carried_phi): Likewise. (loop_carried_phi): Likewise.
(propagate_rank): Likewise. (propagate_rank): Likewise.
(get_rank): Add calls to phi_rank and propagate_rank. (get_rank): Add calls to phi_rank and propagate_rank.
2011-07-31 H.J. Lu <hongjiu.lu@intel.com> 2011-07-31 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/x86-64.h (SIZE_TYPE): Check TARGET_LP64 instead * config/i386/x86-64.h (SIZE_TYPE): Check TARGET_LP64 instead
......
...@@ -172,8 +172,6 @@ extern void rs6000_emit_epilogue (int); ...@@ -172,8 +172,6 @@ extern void rs6000_emit_epilogue (int);
extern void rs6000_emit_eh_reg_restore (rtx, rtx); extern void rs6000_emit_eh_reg_restore (rtx, rtx);
extern const char * output_isel (rtx *); extern const char * output_isel (rtx *);
extern void rs6000_call_indirect_aix (rtx, rtx, 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 *); extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
/* Declare functions in rs6000-c.c */ /* Declare functions in rs6000-c.c */
......
...@@ -1178,6 +1178,7 @@ static void rs6000_conditional_register_usage (void); ...@@ -1178,6 +1178,7 @@ static void rs6000_conditional_register_usage (void);
static void rs6000_trampoline_init (rtx, tree, rtx); static void rs6000_trampoline_init (rtx, tree, rtx);
static bool rs6000_cannot_force_const_mem (enum machine_mode, 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_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. */ /* Hash table stuff for keeping track of TOC entries. */
...@@ -20478,14 +20479,12 @@ rs6000_emit_prologue (void) ...@@ -20478,14 +20479,12 @@ rs6000_emit_prologue (void)
insn = emit_insn (generate_set_vrsave (reg, info, 0)); 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 we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0) if (!TARGET_SINGLE_PIC_BASE
|| (DEFAULT_ABI == ABI_V4 && ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
&& (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT)) || (DEFAULT_ABI == ABI_V4
&& df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))) && (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 /* 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 it. We use R12 for this purpose because emit_load_toc_table
...@@ -20513,7 +20512,8 @@ rs6000_emit_prologue (void) ...@@ -20513,7 +20512,8 @@ rs6000_emit_prologue (void)
} }
#if TARGET_MACHO #if TARGET_MACHO
if (DEFAULT_ABI == ABI_DARWIN if (!TARGET_SINGLE_PIC_BASE
&& DEFAULT_ABI == ABI_DARWIN
&& flag_pic && crtl->uses_pic_offset_table) && flag_pic && crtl->uses_pic_offset_table)
{ {
rtx lr = gen_rtx_REG (Pmode, LR_REGNO); rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
...@@ -20534,10 +20534,26 @@ rs6000_emit_prologue (void) ...@@ -20534,10 +20534,26 @@ rs6000_emit_prologue (void)
} }
#endif #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 ()) 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. */ /* Write function prologue. */
...@@ -27795,10 +27811,7 @@ rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag) ...@@ -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 /* Can we optimize saving the TOC in the prologue or do we need to do it at
every call? */ every call? */
if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca 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))
cfun->machine->save_toc_in_prologue = true; cfun->machine->save_toc_in_prologue = true;
else else
...@@ -27834,13 +27847,12 @@ rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag) ...@@ -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); insn = call_func (func_addr, flag, func_toc_mem, stack_toc_mem);
emit_call_insn (insn); emit_call_insn (insn);
return;
} }
/* Return whether we need to always update the saved TOC pointer when we update /* Return whether we need to always update the saved TOC pointer when we update
the stack pointer. */ the stack pointer. */
bool static bool
rs6000_save_toc_in_prologue_p (void) rs6000_save_toc_in_prologue_p (void)
{ {
return (cfun && cfun->machine && cfun->machine->save_toc_in_prologue); return (cfun && cfun->machine && cfun->machine->save_toc_in_prologue);
......
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> 2011-08-01 Julian Brown <julian@codesourcery.com>
* config.host (arm*-*-linux*, arm*-*-uclinux*, arm*-*-eabi*) * config.host (arm*-*-linux*, arm*-*-uclinux*, arm*-*-eabi*)
......
...@@ -354,20 +354,22 @@ frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATT ...@@ -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, /* We are in a plt call stub or r2 adjusting long branch stub,
before r2 has been saved. Keep REG_UNSAVED. */ 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 else
{ {
unsigned int *insn unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, R_LR); = (unsigned int *) _Unwind_GetGR (context, R_LR);
if (insn && *insn == 0xE8410028) if (insn && *insn == 0xE8410028)
_Unwind_SetGRPtr (context, 2, context->cfa + 40); _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 #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment