summaryrefslogtreecommitdiff
path: root/gcc/config/sparc/sparc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/sparc/sparc.c')
-rw-r--r--gcc/config/sparc/sparc.c54
1 files changed, 10 insertions, 44 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 3560ed988ba..2ab08fde5d6 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -318,8 +318,7 @@ static int set_extends (rtx);
static void emit_pic_helper (void);
static void load_pic_register (bool);
static int save_or_restore_regs (int, int, rtx, int, int);
-static void emit_save_regs (void);
-static void emit_restore_regs (void);
+static void emit_save_or_restore_regs (int);
static void sparc_asm_function_prologue (FILE *, HOST_WIDE_INT);
static void sparc_asm_function_epilogue (FILE *, HOST_WIDE_INT);
#ifdef OBJECT_FORMAT_ELF
@@ -3508,10 +3507,9 @@ sparc_compute_frame_size (HOST_WIDE_INT size, int leaf_function_p)
/* Make sure nothing can clobber our register windows.
If a SAVE must be done, or there is a stack-local variable,
- the register window area must be allocated.
- ??? For v8 we apparently need an additional 8 bytes of reserved space. */
+ the register window area must be allocated. */
if (! leaf_function_p || size > 0)
- actual_fsize += (16 * UNITS_PER_WORD) + (TARGET_ARCH64 ? 0 : 8);
+ actual_fsize += FIRST_PARM_OFFSET (current_function_decl);
return SPARC_STACK_ALIGN (actual_fsize);
}
@@ -3623,14 +3621,14 @@ save_or_restore_regs (int low, int high, rtx base, int offset, int action)
/* Emit code to save call-saved registers. */
static void
-emit_save_regs (void)
+emit_save_or_restore_regs (int action)
{
HOST_WIDE_INT offset;
rtx base;
offset = frame_base_offset - apparent_fsize;
- if (offset < -4096 || offset + num_gfregs * 4 > 4096)
+ if (offset < -4096 || offset + num_gfregs * 4 > 4095)
{
/* ??? This might be optimized a little as %g1 might already have a
value close enough that a single add insn will do. */
@@ -3648,34 +3646,8 @@ emit_save_regs (void)
else
base = frame_base_reg;
- offset = save_or_restore_regs (0, 8, base, offset, SORR_SAVE);
- save_or_restore_regs (32, TARGET_V9 ? 96 : 64, base, offset, SORR_SAVE);
-}
-
-/* Emit code to restore call-saved registers. */
-
-static void
-emit_restore_regs (void)
-{
- HOST_WIDE_INT offset;
- rtx base;
-
- offset = frame_base_offset - apparent_fsize;
-
- if (offset < -4096 || offset + num_gfregs * 4 > 4096 - 8 /*double*/)
- {
- base = gen_rtx_REG (Pmode, 1);
- emit_move_insn (base, GEN_INT (offset));
- emit_insn (gen_rtx_SET (VOIDmode,
- base,
- gen_rtx_PLUS (Pmode, frame_base_reg, base)));
- offset = 0;
- }
- else
- base = frame_base_reg;
-
- offset = save_or_restore_regs (0, 8, base, offset, SORR_RESTORE);
- save_or_restore_regs (32, TARGET_V9 ? 96 : 64, base, offset, SORR_RESTORE);
+ offset = save_or_restore_regs (0, 8, base, offset, action);
+ save_or_restore_regs (32, TARGET_V9 ? 96 : 64, base, offset, action);
}
/* Generate a save_register_window insn. */
@@ -3814,9 +3786,8 @@ sparc_expand_prologue (void)
RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, i)) = 1;
}
- /* Call-saved registers are saved just above the outgoing argument area. */
if (num_gfregs)
- emit_save_regs ();
+ emit_save_or_restore_regs (SORR_SAVE);
/* Load the PIC register if needed. */
if (flag_pic && current_function_uses_pic_offset_table)
@@ -3824,12 +3795,7 @@ sparc_expand_prologue (void)
}
/* This function generates the assembly code for function entry, which boils
- down to emitting the necessary .register directives.
-
- ??? Historical cruft: "On SPARC, move-double insns between fpu and cpu need
- an 8-byte block of memory. If any fpu reg is used in the function, we
- allocate such a block here, at the bottom of the frame, just in case it's
- needed." Could this explain the -8 in emit_restore_regs? */
+ down to emitting the necessary .register directives. */
static void
sparc_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
@@ -3847,7 +3813,7 @@ void
sparc_expand_epilogue (void)
{
if (num_gfregs)
- emit_restore_regs ();
+ emit_save_or_restore_regs (SORR_RESTORE);
if (actual_fsize == 0)
/* do nothing. */ ;