2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-03-21 23:51:18 +08:00

mips.c (mips_frame_info): Add arg_pointer_offset and hard_frame_pointer_offset.

gcc/
	* config/mips/mips.c (mips_frame_info): Add arg_pointer_offset
	and hard_frame_pointer_offset.
	(mips_debugger_offset): Use hard_frame_pointer_offset.
	(mips16e_collect_argument_save_p): Likewise.
	(compute_frame_size): Initialize arg_pointer_offset and
	hard_frame_pointer_offset.
	(mips_initial_elimination_offset): Use them.
	(mips_output_function_prologue): Use hard_frame_pointer_offset.
	(mips_expand_prologue, mips_expand_epilogue): Likewise.

From-SVN: r129458
This commit is contained in:
Richard Sandiford 2007-10-18 19:33:46 +00:00 committed by Richard Sandiford
parent 67202da49d
commit f374e413a7
2 changed files with 62 additions and 48 deletions
gcc
ChangeLog
config/mips

@ -1,3 +1,15 @@
2007-10-18 Richard Sandiford <rsandifo@nildram.co.uk>
* config/mips/mips.c (mips_frame_info): Add arg_pointer_offset
and hard_frame_pointer_offset.
(mips_debugger_offset): Use hard_frame_pointer_offset.
(mips16e_collect_argument_save_p): Likewise.
(compute_frame_size): Initialize arg_pointer_offset and
hard_frame_pointer_offset.
(mips_initial_elimination_offset): Use them.
(mips_output_function_prologue): Use hard_frame_pointer_offset.
(mips_expand_prologue, mips_expand_epilogue): Likewise.
2007-10-18 Richard Sandiford <rsandifo@nildram.co.uk>
* config/mips/mips.h (STARTING_FRAME_OFFSET): Remove rtl

@ -275,6 +275,12 @@ struct mips_frame_info GTY(())
HOST_WIDE_INT gp_sp_offset;
HOST_WIDE_INT fp_sp_offset;
/* The offset of arg_pointer_rtx from frame_pointer_rtx. */
HOST_WIDE_INT arg_pointer_offset;
/* The offset of hard_frame_pointer_rtx from frame_pointer_rtx. */
HOST_WIDE_INT hard_frame_pointer_offset;
/* True if this structure has been initialized after reload. */
bool initialized;
};
@ -6804,15 +6810,9 @@ mips_debugger_offset (rtx addr, HOST_WIDE_INT offset)
if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
|| reg == hard_frame_pointer_rtx)
{
HOST_WIDE_INT frame_size = (!cfun->machine->frame.initialized)
? compute_frame_size (get_frame_size ())
: cfun->machine->frame.total_size;
/* MIPS16 frame is smaller */
if (frame_pointer_needed && TARGET_MIPS16)
frame_size -= cfun->machine->frame.args_size;
offset = offset - frame_size;
offset -= cfun->machine->frame.total_size;
if (reg == hard_frame_pointer_rtx)
offset += cfun->machine->frame.hard_frame_pointer_offset;
}
/* sdbout_parms does not want this to crash for unrecognized cases. */
@ -7352,13 +7352,12 @@ mips16e_collect_argument_save_p (rtx dest, rtx src, rtx *reg_values,
argno = regno - GP_ARG_FIRST;
/* Check whether the address is an appropriate stack pointer or
frame pointer access. The frame pointer is offset from the
stack pointer by the size of the outgoing arguments. */
frame pointer access. */
addr = mips16e_collect_propagate_value (XEXP (dest, 0), reg_values);
mips_split_plus (addr, &base, &offset);
required_offset = cfun->machine->frame.total_size + argno * UNITS_PER_WORD;
if (base == hard_frame_pointer_rtx)
required_offset -= cfun->machine->frame.args_size;
required_offset -= cfun->machine->frame.hard_frame_pointer_offset;
else if (base != stack_pointer_rtx)
return false;
if (offset != required_offset)
@ -7991,6 +7990,7 @@ compute_frame_size (HOST_WIDE_INT size)
/* Move above the callee-allocated varargs save area. */
offset += MIPS_STACK_ALIGN (cfun->machine->varargs_size);
frame->arg_pointer_offset = offset;
/* Move above the callee-allocated area for pretend stack arguments. */
offset += current_function_pretend_args_size;
@ -8002,6 +8002,12 @@ compute_frame_size (HOST_WIDE_INT size)
if (frame->fp_sp_offset > 0)
frame->fp_save_offset = frame->fp_sp_offset - offset;
/* MIPS16 code offsets the frame pointer by the size of the outgoing
arguments. This tends to increase the chances of using unextended
instructions for local variables and incoming arguments. */
if (TARGET_MIPS16)
frame->hard_frame_pointer_offset = frame->args_size;
frame->initialized = reload_completed;
return frame->total_size;
}
@ -8035,7 +8041,8 @@ mips_initial_elimination_offset (int from, int to)
compute_frame_size (get_frame_size ());
/* Set OFFSET to the offset from the stack pointer. */
/* Set OFFSET to the offset from the soft frame pointer, which is also
the offset from the end-of-prologue stack pointer. */
switch (from)
{
case FRAME_POINTER_REGNUM:
@ -8043,16 +8050,15 @@ mips_initial_elimination_offset (int from, int to)
break;
case ARG_POINTER_REGNUM:
offset = (cfun->machine->frame.total_size
- current_function_pretend_args_size);
offset = cfun->machine->frame.arg_pointer_offset;
break;
default:
gcc_unreachable ();
}
if (TARGET_MIPS16 && to == HARD_FRAME_POINTER_REGNUM)
offset -= cfun->machine->frame.args_size;
if (to == HARD_FRAME_POINTER_REGNUM)
offset -= cfun->machine->frame.hard_frame_pointer_offset;
return offset;
}
@ -8248,8 +8254,8 @@ mips_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
", gp= " HOST_WIDE_INT_PRINT_DEC "\n",
(reg_names[(frame_pointer_needed)
? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM]),
((frame_pointer_needed && TARGET_MIPS16)
? tsize - cfun->machine->frame.args_size
(frame_pointer_needed
? tsize - cfun->machine->frame.hard_frame_pointer_offset
: tsize),
reg_names[GP_REG_FIRST + 31],
cfun->machine->frame.var_size,
@ -8497,36 +8503,34 @@ mips_expand_prologue (void)
}
}
/* Set up the frame pointer, if we're using one. In mips16 code,
we point the frame pointer ahead of the outgoing argument area.
This should allow more variables & incoming arguments to be
accessed with unextended instructions. */
/* Set up the frame pointer, if we're using one. */
if (frame_pointer_needed)
{
if (TARGET_MIPS16 && cfun->machine->frame.args_size != 0)
HOST_WIDE_INT offset;
offset = cfun->machine->frame.hard_frame_pointer_offset;
if (offset == 0)
{
rtx offset = GEN_INT (cfun->machine->frame.args_size);
if (SMALL_OPERAND (cfun->machine->frame.args_size))
RTX_FRAME_RELATED_P
(emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
stack_pointer_rtx,
offset))) = 1;
else
{
mips_emit_move (MIPS_PROLOGUE_TEMP (Pmode), offset);
mips_emit_move (hard_frame_pointer_rtx, stack_pointer_rtx);
emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
hard_frame_pointer_rtx,
MIPS_PROLOGUE_TEMP (Pmode)));
mips_set_frame_expr
(gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx,
plus_constant (stack_pointer_rtx,
cfun->machine->frame.args_size)));
}
insn = mips_emit_move (hard_frame_pointer_rtx, stack_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
}
else if (SMALL_OPERAND (offset))
{
insn = gen_add3_insn (hard_frame_pointer_rtx,
stack_pointer_rtx, GEN_INT (offset));
RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
}
else
RTX_FRAME_RELATED_P (mips_emit_move (hard_frame_pointer_rtx,
stack_pointer_rtx)) = 1;
{
mips_emit_move (MIPS_PROLOGUE_TEMP (Pmode), GEN_INT (offset));
mips_emit_move (hard_frame_pointer_rtx, stack_pointer_rtx);
emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
hard_frame_pointer_rtx,
MIPS_PROLOGUE_TEMP (Pmode)));
mips_set_frame_expr
(gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx,
plus_constant (stack_pointer_rtx, offset)));
}
}
mips_emit_loadgp ();
@ -8614,15 +8618,13 @@ mips_expand_epilogue (int sibcall_p)
step1 = cfun->machine->frame.total_size;
step2 = 0;
/* Work out which register holds the frame address. Account for the
frame pointer offset used by mips16 code. */
/* Work out which register holds the frame address. */
if (!frame_pointer_needed)
base = stack_pointer_rtx;
else
{
base = hard_frame_pointer_rtx;
if (TARGET_MIPS16)
step1 -= cfun->machine->frame.args_size;
step1 -= cfun->machine->frame.hard_frame_pointer_offset;
}
/* If we need to restore registers, deallocate as much stack as