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:
parent
679f33542d
commit
ff35822bca
9 changed files with 287 additions and 65 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue