This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Patch to rework the mips prologue/epilogue code
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 08 Oct 2003 08:35:32 +0100
- Subject: Re: Patch to rework the mips prologue/epilogue code
- References: <wvnd6daxow4.fsf@talisman.cambridge.redhat.com>
Richard Sandiford <rsandifo@redhat.com> writes:
> Tested on the same targets as before. No regressions, although
> there are still some (unrelated) problems with the $fp offset in
> mips16 frames.
Namely, there's a bad interaction between two optimisations:
1. When laying out the stack frame, we try to reclaim the o32/o64 regparm
space if there's no use for it.
2. In mips16 code, we offset the frame pointer from the stack pointer by
current_function_outgoing_args_size.
If (1) is done, c_f_o_a_s is not the right value to use, since it
contains the original regparm space. This patch changes it to use
the args_size field of the mips frame structure.
"args_size" is really a misnomer: it contains both the arguments and
the cprestore slot. We only want the former in the mips16 case.[*]
So the patch splits it up.
Tested on the same targets as before, fixes many mips16 C++ failures.
OK to install?
Richard
[*] Well, OK, we don't really support mips16 abicalls, but if we did,
we'd want the frame pointer to point the cprestore slot, not to
the slot above it.
* config/mips/mips.c (mips_frame_info): Add cprestore_size field.
(compute_frame_size): Initialize it. Remove the .cprestore slot
from args_size.
(mips_output_function_prologue): Simplify accordingly.
(mips_debugger_offset): Change the mips16 frame pointer offset from
current_function_outgoing_args to cfun->machine->frame.args_size.
(mips_initial_elimination_offset): Likewise.
(mips_expand_prologue): Likewise.
(mips_expand_epilogue): Likewise.
diff -udpr config/mips.prologue/mips.c config/mips/mips.c
--- config/mips.prologue/mips.c Mon Oct 6 19:54:23 2003
+++ config/mips/mips.c Mon Oct 6 20:00:15 2003
@@ -298,6 +298,7 @@ struct mips_frame_info GTY(())
long total_size; /* # bytes that the entire frame takes up */
long var_size; /* # bytes that variables take up */
long args_size; /* # bytes that outgoing arguments take up */
+ long cprestore_size; /* # bytes that the .cprestore slot takes up */
int gp_reg_size; /* # bytes needed to store gp regs */
int fp_reg_size; /* # bytes needed to store fp regs */
long mask; /* mask of saved gp registers */
@@ -5108,7 +5109,7 @@ mips_debugger_offset (rtx addr, HOST_WID
/* MIPS16 frame is smaller */
if (frame_pointer_needed && TARGET_MIPS16)
- frame_size -= current_function_outgoing_args_size;
+ frame_size -= cfun->machine->frame.args_size;
offset = offset - frame_size;
}
@@ -6103,6 +6104,7 @@ compute_frame_size (HOST_WIDE_INT size)
HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up */
HOST_WIDE_INT var_size; /* # bytes that variables take up */
HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up */
+ HOST_WIDE_INT cprestore_size; /* # bytes that the cprestore slot takes up */
HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding */
HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs */
HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs */
@@ -6116,13 +6118,14 @@ compute_frame_size (HOST_WIDE_INT size)
mask = 0;
fmask = 0;
var_size = MIPS_STACK_ALIGN (size);
- args_size = MIPS_STACK_ALIGN (STARTING_FRAME_OFFSET);
+ args_size = current_function_outgoing_args_size;
+ cprestore_size = MIPS_STACK_ALIGN (STARTING_FRAME_OFFSET) - args_size;
/* The space set aside by STARTING_FRAME_OFFSET isn't needed in leaf
functions. If the function has local variables, we're committed
to allocating it anyway. Otherwise reclaim it here. */
if (var_size == 0 && current_function_is_leaf)
- args_size = 0;
+ cprestore_size = args_size = 0;
/* The MIPS 3.0 linker does not like functions that dynamically
allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
@@ -6132,7 +6135,7 @@ compute_frame_size (HOST_WIDE_INT size)
if (args_size == 0 && current_function_calls_alloca)
args_size = 4 * UNITS_PER_WORD;
- total_size = var_size + args_size;
+ total_size = var_size + args_size + cprestore_size;
/* Calculate space needed for gp registers. */
for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
@@ -6181,6 +6184,7 @@ compute_frame_size (HOST_WIDE_INT size)
cfun->machine->frame.total_size = total_size;
cfun->machine->frame.var_size = var_size;
cfun->machine->frame.args_size = args_size;
+ cfun->machine->frame.cprestore_size = cprestore_size;
cfun->machine->frame.gp_reg_size = gp_reg_size;
cfun->machine->frame.fp_reg_size = fp_reg_size;
cfun->machine->frame.mask = mask;
@@ -6193,7 +6197,8 @@ compute_frame_size (HOST_WIDE_INT size)
{
unsigned long offset;
- offset = args_size + var_size + gp_reg_size - GET_MODE_SIZE (gpr_mode);
+ offset = (args_size + cprestore_size + var_size
+ + gp_reg_size - GET_MODE_SIZE (gpr_mode));
cfun->machine->frame.gp_sp_offset = offset;
cfun->machine->frame.gp_save_offset = offset - total_size;
}
@@ -6205,7 +6210,7 @@ compute_frame_size (HOST_WIDE_INT size)
if (fmask)
{
- unsigned long offset = (args_size + var_size
+ unsigned long offset = (args_size + cprestore_size + var_size
+ gp_reg_rounded + fp_reg_size
- FP_INC * UNITS_PER_FPREG);
cfun->machine->frame.fp_sp_offset = offset;
@@ -6230,6 +6235,8 @@ mips_initial_elimination_offset (int fro
{
int offset;
+ compute_frame_size (get_frame_size ());
+
/* Set OFFSET to the offset from the stack pointer. */
switch (from)
{
@@ -6238,7 +6245,6 @@ mips_initial_elimination_offset (int fro
break;
case ARG_POINTER_REGNUM:
- compute_frame_size (get_frame_size ());
offset = cfun->machine->frame.total_size;
if (mips_abi == ABI_N32 || mips_abi == ABI_64)
offset -= current_function_pretend_args_size;
@@ -6249,7 +6255,7 @@ mips_initial_elimination_offset (int fro
}
if (TARGET_MIPS16 && to == HARD_FRAME_POINTER_REGNUM)
- offset -= current_function_outgoing_args_size;
+ offset -= cfun->machine->frame.args_size;
return offset;
}
@@ -6373,19 +6379,18 @@ mips_output_function_prologue (FILE *fil
{
/* .frame FRAMEREG, FRAMESIZE, RETREG */
fprintf (file,
- "\t.frame\t%s,%ld,%s\t\t# vars= %ld, regs= %d/%d, args= %d, gp= %ld\n",
+ "\t.frame\t%s,%ld,%s\t\t# vars= %ld, regs= %d/%d, args= %ld, gp= %ld\n",
(reg_names[(frame_pointer_needed)
? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM]),
((frame_pointer_needed && TARGET_MIPS16)
- ? ((long) tsize - current_function_outgoing_args_size)
+ ? ((long) tsize - cfun->machine->frame.args_size)
: (long) tsize),
reg_names[GP_REG_FIRST + 31],
cfun->machine->frame.var_size,
cfun->machine->frame.num_gp,
cfun->machine->frame.num_fp,
- current_function_outgoing_args_size,
- cfun->machine->frame.args_size
- - current_function_outgoing_args_size);
+ cfun->machine->frame.args_size,
+ cfun->machine->frame.cprestore_size);
/* .mask MASK, GPOFFSET; .fmask FPOFFSET */
fprintf (file, "\t.mask\t0x%08lx,%ld\n\t.fmask\t0x%08lx,%ld\n",
@@ -6563,9 +6568,9 @@ mips_expand_prologue (void)
acceesed with unextended instructions. */
if (frame_pointer_needed)
{
- if (TARGET_MIPS16 && current_function_outgoing_args_size != 0)
+ if (TARGET_MIPS16 && cfun->machine->frame.args_size != 0)
{
- rtx offset = GEN_INT (current_function_outgoing_args_size);
+ rtx offset = GEN_INT (cfun->machine->frame.args_size);
RTX_FRAME_RELATED_P
(emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
stack_pointer_rtx,
@@ -6719,7 +6724,7 @@ mips_expand_epilogue (int sibcall_p)
{
base = hard_frame_pointer_rtx;
if (TARGET_MIPS16)
- step1 -= current_function_outgoing_args_size;
+ step1 -= cfun->machine->frame.args_size;
}
/* If we need to restore registers, deallocate as much stack as