rs6000.c (rs6000_emit_stack_reset): Return generated insn if it is changing sp.

* config/rs6000/rs6000.c (rs6000_emit_stack_reset): Return generated
	insn if it is changing sp.  Use gen_add3_insn instead of
	conditionally gen_addsi3 and gen_adddi3.
	(offset_below_red_zone_p): New static inline function.
	(rs6000_emit_epilogue): Emit needed epilogue unwind info.
	Use gen_add3_insn instead of conditionally gen_addsi3 and gen_adddi3.
	* config/rs6000/ppc-asm.h: Include auto-host.h.
	(CFI_STARTPROC, CFI_ENDPROC, CFI_DEF_CFA_REGISTER, CFI_OFFSET,
	CFI_RESTORE): Define.
	* config/rs6000/crtresxgpr.asm: Add unwind info.
	* config/rs6000/crtresxfpr.asm: Likewise.
	* config/rs6000/crtresgpr.asm: Likewise.
	* config/rs6000/crtresfpr.asm: Likewise.
	* config/rs6000/crtsavgpr.asm: Likewise.
	* config/rs6000/crtsavfpr.asm: Likewise.

From-SVN: r148138
This commit is contained in:
Jakub Jelinek 2009-06-03 19:28:00 +02:00 committed by Jakub Jelinek
parent 679f33542d
commit ff35822bca
9 changed files with 287 additions and 65 deletions

View file

@ -1,5 +1,21 @@
2009-06-03 Jakub Jelinek <jakub@redhat.com>
* config/rs6000/rs6000.c (rs6000_emit_stack_reset): Return generated
insn if it is changing sp. Use gen_add3_insn instead of
conditionally gen_addsi3 and gen_adddi3.
(offset_below_red_zone_p): New static inline function.
(rs6000_emit_epilogue): Emit needed epilogue unwind info.
Use gen_add3_insn instead of conditionally gen_addsi3 and gen_adddi3.
* config/rs6000/ppc-asm.h: Include auto-host.h.
(CFI_STARTPROC, CFI_ENDPROC, CFI_DEF_CFA_REGISTER, CFI_OFFSET,
CFI_RESTORE): Define.
* config/rs6000/crtresxgpr.asm: Add unwind info.
* config/rs6000/crtresxfpr.asm: Likewise.
* config/rs6000/crtresgpr.asm: Likewise.
* config/rs6000/crtresfpr.asm: Likewise.
* config/rs6000/crtsavgpr.asm: Likewise.
* config/rs6000/crtsavfpr.asm: Likewise.
* dwarf2out.c (output_cfi_directive): Pass 1 instead of
0 to second argument of DWARF2_FRAME_REG_OUT macros.

View file

@ -38,6 +38,7 @@
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the floating point save area. */
CFI_STARTPROC
HIDDEN_FUNC(_restfpr_14) lfd 14,-144(11) /* restore fp registers */
HIDDEN_FUNC(_restfpr_15) lfd 15,-136(11)
HIDDEN_FUNC(_restfpr_16) lfd 16,-128(11)
@ -75,5 +76,6 @@ FUNC_END(_restfpr_17)
FUNC_END(_restfpr_16)
FUNC_END(_restfpr_15)
FUNC_END(_restfpr_14)
CFI_ENDPROC
#endif

View file

@ -38,6 +38,7 @@
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the integer restore area. */
CFI_STARTPROC
HIDDEN_FUNC(_restgpr_14) lwz 14,-72(11) /* restore gp registers */
HIDDEN_FUNC(_restgpr_15) lwz 15,-68(11)
HIDDEN_FUNC(_restgpr_16) lwz 16,-64(11)
@ -75,5 +76,6 @@ FUNC_END(_restgpr_17)
FUNC_END(_restgpr_16)
FUNC_END(_restgpr_15)
FUNC_END(_restgpr_14)
CFI_ENDPROC
#endif

View file

@ -40,27 +40,68 @@
/* In addition to restoring the fp registers, it will return to the caller's */
/* caller */
CFI_STARTPROC
CFI_DEF_CFA_REGISTER (11)
CFI_OFFSET (65, 4)
CFI_OFFSET (46, -144)
CFI_OFFSET (47, -136)
CFI_OFFSET (48, -128)
CFI_OFFSET (49, -120)
CFI_OFFSET (50, -112)
CFI_OFFSET (51, -104)
CFI_OFFSET (52, -96)
CFI_OFFSET (53, -88)
CFI_OFFSET (54, -80)
CFI_OFFSET (55, -72)
CFI_OFFSET (56, -64)
CFI_OFFSET (57, -56)
CFI_OFFSET (58, -48)
CFI_OFFSET (59, -40)
CFI_OFFSET (60, -32)
CFI_OFFSET (61, -24)
CFI_OFFSET (62, -16)
CFI_OFFSET (63, -8)
HIDDEN_FUNC(_restfpr_14_x) lfd 14,-144(11) /* restore fp registers */
CFI_RESTORE (46)
HIDDEN_FUNC(_restfpr_15_x) lfd 15,-136(11)
CFI_RESTORE (47)
HIDDEN_FUNC(_restfpr_16_x) lfd 16,-128(11)
CFI_RESTORE (48)
HIDDEN_FUNC(_restfpr_17_x) lfd 17,-120(11)
CFI_RESTORE (49)
HIDDEN_FUNC(_restfpr_18_x) lfd 18,-112(11)
CFI_RESTORE (50)
HIDDEN_FUNC(_restfpr_19_x) lfd 19,-104(11)
CFI_RESTORE (51)
HIDDEN_FUNC(_restfpr_20_x) lfd 20,-96(11)
CFI_RESTORE (52)
HIDDEN_FUNC(_restfpr_21_x) lfd 21,-88(11)
CFI_RESTORE (53)
HIDDEN_FUNC(_restfpr_22_x) lfd 22,-80(11)
CFI_RESTORE (54)
HIDDEN_FUNC(_restfpr_23_x) lfd 23,-72(11)
CFI_RESTORE (55)
HIDDEN_FUNC(_restfpr_24_x) lfd 24,-64(11)
CFI_RESTORE (56)
HIDDEN_FUNC(_restfpr_25_x) lfd 25,-56(11)
CFI_RESTORE (57)
HIDDEN_FUNC(_restfpr_26_x) lfd 26,-48(11)
CFI_RESTORE (58)
HIDDEN_FUNC(_restfpr_27_x) lfd 27,-40(11)
CFI_RESTORE (59)
HIDDEN_FUNC(_restfpr_28_x) lfd 28,-32(11)
CFI_RESTORE (60)
HIDDEN_FUNC(_restfpr_29_x) lfd 29,-24(11)
CFI_RESTORE (61)
HIDDEN_FUNC(_restfpr_30_x) lfd 30,-16(11)
CFI_RESTORE (62)
HIDDEN_FUNC(_restfpr_31_x) lwz 0,4(11)
lfd 31,-8(11)
CFI_RESTORE (63)
mtlr 0
CFI_RESTORE (65)
mr 1,11
CFI_DEF_CFA_REGISTER (1)
blr
FUNC_END(_restfpr_31_x)
FUNC_END(_restfpr_30_x)
@ -80,5 +121,6 @@ FUNC_END(_restfpr_17_x)
FUNC_END(_restfpr_16_x)
FUNC_END(_restfpr_15_x)
FUNC_END(_restfpr_14_x)
CFI_ENDPROC
#endif

View file

@ -38,27 +38,68 @@
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the integer restore area. */
CFI_STARTPROC
CFI_DEF_CFA_REGISTER (11)
CFI_OFFSET (65, 4)
CFI_OFFSET (14, -72)
CFI_OFFSET (15, -68)
CFI_OFFSET (16, -64)
CFI_OFFSET (17, -60)
CFI_OFFSET (18, -56)
CFI_OFFSET (19, -52)
CFI_OFFSET (20, -48)
CFI_OFFSET (21, -44)
CFI_OFFSET (22, -40)
CFI_OFFSET (23, -36)
CFI_OFFSET (24, -32)
CFI_OFFSET (25, -28)
CFI_OFFSET (26, -24)
CFI_OFFSET (27, -20)
CFI_OFFSET (28, -16)
CFI_OFFSET (29, -12)
CFI_OFFSET (30, -8)
CFI_OFFSET (31, -4)
HIDDEN_FUNC(_restgpr_14_x) lwz 14,-72(11) /* restore gp registers */
CFI_RESTORE (14)
HIDDEN_FUNC(_restgpr_15_x) lwz 15,-68(11)
CFI_RESTORE (15)
HIDDEN_FUNC(_restgpr_16_x) lwz 16,-64(11)
CFI_RESTORE (16)
HIDDEN_FUNC(_restgpr_17_x) lwz 17,-60(11)
CFI_RESTORE (17)
HIDDEN_FUNC(_restgpr_18_x) lwz 18,-56(11)
CFI_RESTORE (18)
HIDDEN_FUNC(_restgpr_19_x) lwz 19,-52(11)
CFI_RESTORE (19)
HIDDEN_FUNC(_restgpr_20_x) lwz 20,-48(11)
CFI_RESTORE (20)
HIDDEN_FUNC(_restgpr_21_x) lwz 21,-44(11)
CFI_RESTORE (21)
HIDDEN_FUNC(_restgpr_22_x) lwz 22,-40(11)
CFI_RESTORE (22)
HIDDEN_FUNC(_restgpr_23_x) lwz 23,-36(11)
CFI_RESTORE (23)
HIDDEN_FUNC(_restgpr_24_x) lwz 24,-32(11)
CFI_RESTORE (24)
HIDDEN_FUNC(_restgpr_25_x) lwz 25,-28(11)
CFI_RESTORE (25)
HIDDEN_FUNC(_restgpr_26_x) lwz 26,-24(11)
CFI_RESTORE (26)
HIDDEN_FUNC(_restgpr_27_x) lwz 27,-20(11)
CFI_RESTORE (27)
HIDDEN_FUNC(_restgpr_28_x) lwz 28,-16(11)
CFI_RESTORE (28)
HIDDEN_FUNC(_restgpr_29_x) lwz 29,-12(11)
CFI_RESTORE (29)
HIDDEN_FUNC(_restgpr_30_x) lwz 30,-8(11)
CFI_RESTORE (30)
HIDDEN_FUNC(_restgpr_31_x) lwz 0,4(11)
lwz 31,-4(11)
CFI_RESTORE (31)
mtlr 0
CFI_RESTORE (65)
mr 1,11
CFI_DEF_CFA_REGISTER (1)
blr
FUNC_END(_restgpr_31_x)
FUNC_END(_restgpr_30_x)
@ -78,5 +119,6 @@ FUNC_END(_restgpr_17_x)
FUNC_END(_restgpr_16_x)
FUNC_END(_restgpr_15_x)
FUNC_END(_restgpr_14_x)
CFI_ENDPROC
#endif

View file

@ -38,6 +38,7 @@
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the floating point save area. */
CFI_STARTPROC
HIDDEN_FUNC(_savefpr_14) stfd 14,-144(11) /* save fp registers */
HIDDEN_FUNC(_savefpr_15) stfd 15,-136(11)
HIDDEN_FUNC(_savefpr_16) stfd 16,-128(11)
@ -75,5 +76,6 @@ FUNC_END(_savefpr_17)
FUNC_END(_savefpr_16)
FUNC_END(_savefpr_15)
FUNC_END(_savefpr_14)
CFI_ENDPROC
#endif

View file

@ -38,6 +38,7 @@
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the integer save area. */
CFI_STARTPROC
HIDDEN_FUNC(_savegpr_14) stw 14,-72(11) /* save gp registers */
HIDDEN_FUNC(_savegpr_15) stw 15,-68(11)
HIDDEN_FUNC(_savegpr_16) stw 16,-64(11)
@ -75,5 +76,6 @@ FUNC_END(_savegpr_17)
FUNC_END(_savegpr_16)
FUNC_END(_savegpr_15)
FUNC_END(_savegpr_14)
CFI_ENDPROC
#endif

View file

@ -1,6 +1,6 @@
/* PowerPC asm definitions for GNU C.
Copyright (C) 2002, 2003, 2008 Free Software Foundation, Inc.
Copyright (C) 2002, 2003, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@ -196,6 +196,23 @@ GLUE(.L,name): \
.size FUNC_NAME(name),GLUE(.L,name)-FUNC_NAME(name)
#endif
/* For HAVE_GAS_CFI_DIRECTIVE. */
#include "auto-host.h"
#ifdef HAVE_GAS_CFI_DIRECTIVE
# define CFI_STARTPROC .cfi_startproc
# define CFI_ENDPROC .cfi_endproc
# define CFI_OFFSET(reg, off) .cfi_offset reg, off
# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
# define CFI_RESTORE(reg) .cfi_restore reg
#else
# define CFI_STARTPROC
# define CFI_ENDPROC
# define CFI_OFFSET(reg, off)
# define CFI_DEF_CFA_REGISTER(reg)
# define CFI_RESTORE(reg)
#endif
#if defined __linux__ && !defined __powerpc64__
.section .note.GNU-stack
.previous

View file

@ -778,7 +778,7 @@ static const char *rs6000_mangle_type (const_tree);
extern const struct attribute_spec rs6000_attribute_table[];
static void rs6000_set_default_type_attributes (tree);
static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
static void rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
enum machine_mode, bool, bool, bool);
static bool rs6000_reg_live_or_pic_offset_p (int);
@ -15892,7 +15892,7 @@ rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, bool gpr, bool exit
stack pointer, but move the base of the frame into r11 for use by
out-of-line register restore routines. */
static void
static rtx
rs6000_emit_stack_reset (rs6000_stack_t *info,
rtx sp_reg_rtx, rtx frame_reg_rtx,
int sp_offset, bool savres)
@ -15908,10 +15908,10 @@ rs6000_emit_stack_reset (rs6000_stack_t *info,
if (frame_reg_rtx != sp_reg_rtx)
{
if (sp_offset != 0)
emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
GEN_INT (sp_offset)));
return emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
GEN_INT (sp_offset)));
else if (!savres)
emit_move_insn (sp_reg_rtx, frame_reg_rtx);
return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
}
else if (sp_offset != 0)
{
@ -15923,12 +15923,12 @@ rs6000_emit_stack_reset (rs6000_stack_t *info,
? gen_rtx_REG (Pmode, 11)
: sp_reg_rtx);
emit_insn (TARGET_32BIT
? gen_addsi3 (dest_reg, sp_reg_rtx,
GEN_INT (sp_offset))
: gen_adddi3 (dest_reg, sp_reg_rtx,
GEN_INT (sp_offset)));
rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
GEN_INT (sp_offset)));
if (!savres)
return insn;
}
return NULL_RTX;
}
/* Construct a parallel rtx describing the effect of a call to an
@ -16838,12 +16838,19 @@ rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
}
}
/* Emit function epilogue as insns.
/* Return true if OFFSET from stack pointer can be clobbered by signals.
V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
below stack pointer not cloberred by signals. */
At present, dwarf2out_frame_debug_expr doesn't understand
register restores, so we don't bother setting RTX_FRAME_RELATED_P
anywhere in the epilogue. Most of the insns below would in any case
need special notes to explain where r11 is in relation to the stack. */
static inline bool
offset_below_red_zone_p (HOST_WIDE_INT offset)
{
return offset < (DEFAULT_ABI == ABI_V4
? 0
: TARGET_32BIT ? -220 : -288);
}
/* Emit function epilogue as insns. */
void
rs6000_emit_epilogue (int sibcall)
@ -16859,6 +16866,8 @@ rs6000_emit_epilogue (int sibcall)
int sp_offset = 0;
rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
rtx frame_reg_rtx = sp_reg_rtx;
rtx cfa_restores = NULL_RTX;
rtx insn;
enum machine_mode reg_mode = Pmode;
int reg_size = TARGET_32BIT ? 4 : 8;
int i;
@ -16999,7 +17008,7 @@ rs6000_emit_epilogue (int sibcall)
&& info->altivec_size != 0
&& (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
|| (DEFAULT_ABI != ABI_V4
&& info->altivec_save_offset < (TARGET_32BIT ? -220 : -288))))
&& offset_below_red_zone_p (info->altivec_save_offset))))
{
int i;
@ -17016,7 +17025,7 @@ rs6000_emit_epilogue (int sibcall)
for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
rtx addr, areg, mem;
rtx addr, areg, mem, reg;
areg = gen_rtx_REG (Pmode, 0);
emit_move_insn
@ -17028,7 +17037,13 @@ rs6000_emit_epilogue (int sibcall)
addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
mem = gen_frame_mem (V4SImode, addr);
emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
reg = gen_rtx_REG (V4SImode, i);
emit_move_insn (reg, mem);
if (offset_below_red_zone_p (info->altivec_save_offset
+ (i - info->first_altivec_reg_save)
* 16))
cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
cfa_restores);
}
}
@ -17038,7 +17053,7 @@ rs6000_emit_epilogue (int sibcall)
&& info->vrsave_mask != 0
&& (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
|| (DEFAULT_ABI != ABI_V4
&& info->vrsave_save_offset < (TARGET_32BIT ? -220 : -288))))
&& offset_below_red_zone_p (info->vrsave_save_offset))))
{
rtx addr, mem, reg;
@ -17064,6 +17079,7 @@ rs6000_emit_epilogue (int sibcall)
emit_insn (generate_set_vrsave (reg, info, 1));
}
insn = NULL_RTX;
/* If we have a large stack frame, restore the old stack pointer
using the backchain. */
if (use_backchain_to_restore_sp)
@ -17075,8 +17091,8 @@ rs6000_emit_epilogue (int sibcall)
if (DEFAULT_ABI == ABI_V4)
frame_reg_rtx = gen_rtx_REG (Pmode, 11);
emit_move_insn (frame_reg_rtx,
gen_rtx_MEM (Pmode, sp_reg_rtx));
insn = emit_move_insn (frame_reg_rtx,
gen_rtx_MEM (Pmode, sp_reg_rtx));
sp_offset = 0;
}
else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
@ -17085,7 +17101,7 @@ rs6000_emit_epilogue (int sibcall)
;
else
{
emit_move_insn (sp_reg_rtx, frame_reg_rtx);
insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
frame_reg_rtx = sp_reg_rtx;
}
}
@ -17097,38 +17113,42 @@ rs6000_emit_epilogue (int sibcall)
if (DEFAULT_ABI == ABI_V4)
frame_reg_rtx = gen_rtx_REG (Pmode, 11);
emit_insn (TARGET_32BIT
? gen_addsi3 (frame_reg_rtx, hard_frame_pointer_rtx,
GEN_INT (info->total_size))
: gen_adddi3 (frame_reg_rtx, hard_frame_pointer_rtx,
GEN_INT (info->total_size)));
insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
GEN_INT (info->total_size)));
sp_offset = 0;
}
else if (info->push_p
&& DEFAULT_ABI != ABI_V4
&& !crtl->calls_eh_return)
{
emit_insn (TARGET_32BIT
? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
GEN_INT (info->total_size))
: gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
GEN_INT (info->total_size)));
insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
GEN_INT (info->total_size)));
sp_offset = 0;
}
if (insn && frame_reg_rtx == sp_reg_rtx)
{
if (cfa_restores)
{
REG_NOTES (insn) = cfa_restores;
cfa_restores = NULL_RTX;
}
add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
}
/* Restore AltiVec registers if we have not done so already. */
if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
&& TARGET_ALTIVEC_ABI
&& info->altivec_size != 0
&& (DEFAULT_ABI == ABI_V4
|| info->altivec_save_offset >= (TARGET_32BIT ? -220 : -288)))
|| !offset_below_red_zone_p (info->altivec_save_offset)))
{
int i;
for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
rtx addr, areg, mem;
rtx addr, areg, mem, reg;
areg = gen_rtx_REG (Pmode, 0);
emit_move_insn
@ -17140,7 +17160,11 @@ rs6000_emit_epilogue (int sibcall)
addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
mem = gen_frame_mem (V4SImode, addr);
emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
reg = gen_rtx_REG (V4SImode, i);
emit_move_insn (reg, mem);
if (DEFAULT_ABI == ABI_V4)
cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
cfa_restores);
}
}
@ -17150,7 +17174,7 @@ rs6000_emit_epilogue (int sibcall)
&& TARGET_ALTIVEC_VRSAVE
&& info->vrsave_mask != 0
&& (DEFAULT_ABI == ABI_V4
|| info->vrsave_save_offset >= (TARGET_32BIT ? -220 : -288)))
|| !offset_below_red_zone_p (info->vrsave_save_offset)))
{
rtx addr, mem, reg;
@ -17183,7 +17207,8 @@ rs6000_emit_epilogue (int sibcall)
emit_move_insn (gen_rtx_REG (SImode, 12), mem);
}
/* Set LR here to try to overlap restores below. */
/* Set LR here to try to overlap restores below. LR is always saved
above incoming stack, so it never needs REG_CFA_RESTORE. */
if (restore_lr)
emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
gen_rtx_REG (Pmode, 0));
@ -17265,7 +17290,7 @@ rs6000_emit_epilogue (int sibcall)
for (i = 0; i < 32 - info->first_gp_reg_save; i++)
if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
{
rtx offset, addr, mem;
rtx offset, addr, mem, reg;
/* We're doing all this to ensure that the immediate offset
fits into the immediate field of 'evldd'. */
@ -17274,9 +17299,24 @@ rs6000_emit_epilogue (int sibcall)
offset = GEN_INT (spe_offset + reg_size * i);
addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
mem = gen_rtx_MEM (V2SImode, addr);
reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
mem);
insn = emit_move_insn (reg, mem);
if (DEFAULT_ABI == ABI_V4)
{
if (frame_pointer_needed
&& info->first_gp_reg_save + i
== HARD_FRAME_POINTER_REGNUM)
{
add_reg_note (insn, REG_CFA_DEF_CFA,
plus_constant (frame_reg_rtx,
sp_offset));
RTX_FRAME_RELATED_P (insn) = 1;
}
cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
cfa_restores);
}
}
}
else
@ -17288,7 +17328,6 @@ rs6000_emit_epilogue (int sibcall)
/*savep=*/false, /*gpr=*/true,
/*exitp=*/true);
emit_jump_insn (par);
/* We don't want anybody else emitting things after we jumped
back. */
return;
@ -17317,8 +17356,15 @@ rs6000_emit_epilogue (int sibcall)
if (can_use_exit)
{
if (info->cr_save_p)
rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12),
using_mtcr_multiple);
{
rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12),
using_mtcr_multiple);
if (DEFAULT_ABI == ABI_V4)
cfa_restores
= alloc_reg_note (REG_CFA_RESTORE,
gen_rtx_REG (SImode, CR2_REGNO),
cfa_restores);
}
emit_jump_insn (par);
@ -17326,8 +17372,22 @@ rs6000_emit_epilogue (int sibcall)
back. */
return;
}
else
emit_insn (par);
insn = emit_insn (par);
if (DEFAULT_ABI == ABI_V4)
{
if (frame_pointer_needed)
{
add_reg_note (insn, REG_CFA_DEF_CFA,
plus_constant (frame_reg_rtx, sp_offset));
RTX_FRAME_RELATED_P (insn) = 1;
}
for (i = info->first_gp_reg_save; i < 32; i++)
cfa_restores
= alloc_reg_note (REG_CFA_RESTORE,
gen_rtx_REG (reg_mode, i), cfa_restores);
}
}
else if (using_load_multiple)
{
@ -17340,13 +17400,20 @@ rs6000_emit_epilogue (int sibcall)
+ sp_offset
+ reg_size * i));
rtx mem = gen_frame_mem (reg_mode, addr);
rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
RTVEC_ELT (p, i) =
gen_rtx_SET (VOIDmode,
gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
mem);
RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
if (DEFAULT_ABI == ABI_V4)
cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
cfa_restores);
}
insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
{
add_reg_note (insn, REG_CFA_DEF_CFA,
plus_constant (frame_reg_rtx, sp_offset));
RTX_FRAME_RELATED_P (insn) = 1;
}
emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
}
else
{
@ -17358,9 +17425,23 @@ rs6000_emit_epilogue (int sibcall)
+ sp_offset
+ reg_size * i));
rtx mem = gen_frame_mem (reg_mode, addr);
rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
emit_move_insn (gen_rtx_REG (reg_mode,
info->first_gp_reg_save + i), mem);
insn = emit_move_insn (reg, mem);
if (DEFAULT_ABI == ABI_V4)
{
if (frame_pointer_needed
&& info->first_gp_reg_save + i
== HARD_FRAME_POINTER_REGNUM)
{
add_reg_note (insn, REG_CFA_DEF_CFA,
plus_constant (frame_reg_rtx, sp_offset));
RTX_FRAME_RELATED_P (insn) = 1;
}
cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
cfa_restores);
}
}
}
@ -17370,36 +17451,52 @@ rs6000_emit_epilogue (int sibcall)
if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
&& ! call_used_regs[info->first_fp_reg_save+i]))
{
rtx addr, mem;
rtx addr, mem, reg;
addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
GEN_INT (info->fp_save_offset
+ sp_offset
+ 8 * i));
mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
? DFmode : SFmode), addr);
reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
? DFmode : SFmode),
info->first_fp_reg_save + i);
emit_move_insn (gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT)
? DFmode : SFmode),
info->first_fp_reg_save + i),
mem);
emit_move_insn (reg, mem);
if (DEFAULT_ABI == ABI_V4)
cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
cfa_restores);
}
/* If we saved cr, restore it here. Just those that were used. */
if (info->cr_save_p)
rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple);
{
rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple);
if (DEFAULT_ABI == ABI_V4)
cfa_restores
= alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
cfa_restores);
}
/* If this is V.4, unwind the stack pointer after all of the loads
have been done. */
rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
sp_offset, !restoring_FPRs_inline);
insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
sp_offset, !restoring_FPRs_inline);
if (insn)
{
if (cfa_restores)
{
REG_NOTES (insn) = cfa_restores;
cfa_restores = NULL_RTX;
}
add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
}
if (crtl->calls_eh_return)
{
rtx sa = EH_RETURN_STACKADJ_RTX;
emit_insn (TARGET_32BIT
? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
: gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
}
if (!sibcall)