aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r--gcc/config/rs6000/rs6000.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 5e6f30183a9..05d03823b2d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -759,7 +759,6 @@ static bool spe_func_has_64bit_regs_p (void);
static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
int, HOST_WIDE_INT);
static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
-static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
static unsigned rs6000_hash_constant (rtx);
static unsigned toc_hash_function (const void *);
static int toc_hash_eq (const void *, const void *);
@@ -15548,13 +15547,11 @@ rs6000_emit_stack_tie (void)
}
/* Emit the correct code for allocating stack space, as insns.
- If COPY_R12, make sure a copy of the old frame is left in r12.
- If COPY_R11, make sure a copy of the old frame is left in r11,
- in preference to r12 if COPY_R12.
+ If COPY_REG, make sure a copy of the old frame is left there.
The generated code may use hard register 0 as a temporary. */
static void
-rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
+rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
{
rtx insn;
rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
@@ -15604,11 +15601,8 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
warning (0, "stack limit expression is not supported");
}
- if (copy_r12 || copy_r11)
- emit_move_insn (copy_r11
- ? gen_rtx_REG (Pmode, 11)
- : gen_rtx_REG (Pmode, 12),
- stack_reg);
+ if (copy_reg)
+ emit_move_insn (copy_reg, stack_reg);
if (size > 32767)
{
@@ -16180,20 +16174,33 @@ rs6000_emit_prologue (void)
? (!saving_GPRs_inline
&& info->spe_64bit_regs_used == 0)
: (!saving_FPRs_inline || !saving_GPRs_inline));
+ rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
+
if (info->total_size < 32767)
sp_offset = info->total_size;
+ else if (need_r11)
+ frame_reg_rtx = copy_reg;
+ else if (info->cr_save_p
+ || info->lr_save_p
+ || info->first_fp_reg_save < 64
+ || info->first_gp_reg_save < 32
+ || info->altivec_size != 0
+ || info->vrsave_mask != 0
+ || crtl->calls_eh_return)
+ {
+ copy_reg = frame_ptr_rtx;
+ frame_reg_rtx = copy_reg;
+ }
else
- frame_reg_rtx = (need_r11
- ? gen_rtx_REG (Pmode, 11)
- : frame_ptr_rtx);
- rs6000_emit_allocate_stack (info->total_size,
- (frame_reg_rtx != sp_reg_rtx
- && (info->cr_save_p
- || info->lr_save_p
- || info->first_fp_reg_save < 64
- || info->first_gp_reg_save < 32
- )),
- need_r11);
+ {
+ /* The prologue won't be saving any regs so there is no need
+ to set up a frame register to access any frame save area.
+ We also won't be using sp_offset anywhere below, but set
+ the correct value anyway to protect against future
+ changes to this function. */
+ sp_offset = info->total_size;
+ }
+ rs6000_emit_allocate_stack (info->total_size, copy_reg);
if (frame_reg_rtx != sp_reg_rtx)
rs6000_emit_stack_tie ();
}
@@ -16627,16 +16634,19 @@ rs6000_emit_prologue (void)
if (!WORLD_SAVE_P (info) && info->push_p
&& !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
{
+ rtx copy_reg = NULL;
+
if (info->total_size < 32767)
- sp_offset = info->total_size;
+ sp_offset = info->total_size;
+ else if (info->altivec_size != 0
+ || info->vrsave_mask != 0)
+ {
+ copy_reg = frame_ptr_rtx;
+ frame_reg_rtx = copy_reg;
+ }
else
- frame_reg_rtx = frame_ptr_rtx;
- rs6000_emit_allocate_stack (info->total_size,
- (frame_reg_rtx != sp_reg_rtx
- && ((info->altivec_size != 0)
- || (info->vrsave_mask != 0)
- )),
- FALSE);
+ sp_offset = info->total_size;
+ rs6000_emit_allocate_stack (info->total_size, copy_reg);
if (frame_reg_rtx != sp_reg_rtx)
rs6000_emit_stack_tie ();
}