h8300.c (WORD_REG_USED): Use HARD_FRAME_POINTER_REGNUM instead of FRAME_POINTER_REGNUM.

* config/h8300/h8300.c (WORD_REG_USED): Use
	HARD_FRAME_POINTER_REGNUM instead of FRAME_POINTER_REGNUM.
	(compute_saved_regs): Likewise.
	(h8300_expand_prologue): Likewise.  Allocate locals after
	saving registers.
	(h8300_expand_epilogue): Use HARD_FRAME_POINTER_REGNUM instead
	of FRAME_POINTER_REGNUM.  Deallocate locals before saving
	registers.
	(h8300_initial_elimination_offset): Adjust for the new frame
	layout, which swaps flips the order of locals and saved
	registers.
	* config/h8300/h8300.h (FIRST_PSEUDO_REGISTER): Change to 12.
	(HARD_FRAME_POINTER_REGNUM): New.
	(ELIMINABLE_REGS): Add an elimination rule from
	FRAME_POINTER_REGNUM to HARD_FRAME_POINTER_REGNUM.
	(REGISTER_NAMES): Add fp.
	* config/h8300/h8300.md (FP_REG): Change to 11.
	(HFP_REG): New.

From-SVN: r76811
This commit is contained in:
Kazu Hirata 2004-01-28 22:00:26 +00:00 committed by Kazu Hirata
parent ff4cf05b3d
commit 1807b72620
4 changed files with 97 additions and 44 deletions

View File

@ -1,3 +1,24 @@
2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
* config/h8300/h8300.c (WORD_REG_USED): Use
HARD_FRAME_POINTER_REGNUM instead of FRAME_POINTER_REGNUM.
(compute_saved_regs): Likewise.
(h8300_expand_prologue): Likewise. Allocate locals after
saving registers.
(h8300_expand_epilogue): Use HARD_FRAME_POINTER_REGNUM instead
of FRAME_POINTER_REGNUM. Deallocate locals before saving
registers.
(h8300_initial_elimination_offset): Adjust for the new frame
layout, which swaps flips the order of locals and saved
registers.
* config/h8300/h8300.h (FIRST_PSEUDO_REGISTER): Change to 12.
(HARD_FRAME_POINTER_REGNUM): New.
(ELIMINABLE_REGS): Add an elimination rule from
FRAME_POINTER_REGNUM to HARD_FRAME_POINTER_REGNUM.
(REGISTER_NAMES): Add fp.
* config/h8300/h8300.md (FP_REG): Change to 11.
(HFP_REG): New.
2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
* genrecog.c (write_node): Remove a useless local variable.

View File

@ -351,7 +351,7 @@ byte_reg (rtx x, int b)
/* Save any call saved register that was used. */ \
|| (regs_ever_live[regno] && !call_used_regs[regno]) \
/* Save the frame pointer if it was used. */ \
|| (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
|| (regno == HARD_FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
/* Save any register used in an interrupt handler. */ \
|| (h8300_current_function_interrupt_function_p () \
&& regs_ever_live[regno]) \
@ -411,7 +411,7 @@ compute_saved_regs (void)
int regno;
/* Construct a bit vector of registers to be pushed/popped. */
for (regno = 0; regno <= FRAME_POINTER_REGNUM; regno++)
for (regno = 0; regno <= HARD_FRAME_POINTER_REGNUM; regno++)
{
if (WORD_REG_USED (regno))
saved_regs |= 1 << regno;
@ -419,7 +419,7 @@ compute_saved_regs (void)
/* Don't push/pop the frame pointer as it is treated separately. */
if (frame_pointer_needed)
saved_regs &= ~(1 << FRAME_POINTER_REGNUM);
saved_regs &= ~(1 << HARD_FRAME_POINTER_REGNUM);
return saved_regs;
}
@ -501,13 +501,11 @@ h8300_expand_prologue (void)
if (frame_pointer_needed)
{
/* Push fp. */
push (FRAME_POINTER_REGNUM);
emit_insn (gen_rtx_SET (Pmode, frame_pointer_rtx, stack_pointer_rtx));
push (HARD_FRAME_POINTER_REGNUM);
emit_insn (gen_rtx_SET (Pmode, hard_frame_pointer_rtx,
stack_pointer_rtx));
}
/* Leave room for locals. */
h8300_emit_stack_adjustment (-1, round_frame_size (get_frame_size ()));
/* Push the rest of the registers in ascending order. */
saved_regs = compute_saved_regs ();
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno += n_regs)
@ -556,6 +554,9 @@ h8300_expand_prologue (void)
}
}
}
/* Leave room for locals. */
h8300_emit_stack_adjustment (-1, round_frame_size (get_frame_size ()));
}
int
@ -581,6 +582,9 @@ h8300_expand_epilogue (void)
rts instruction. */
return;
/* Deallocate locals. */
h8300_emit_stack_adjustment (1, round_frame_size (get_frame_size ()));
/* Pop the saved registers in descending order. */
saved_regs = compute_saved_regs ();
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno -= n_regs)
@ -630,12 +634,9 @@ h8300_expand_epilogue (void)
}
}
/* Deallocate locals. */
h8300_emit_stack_adjustment (1, round_frame_size (get_frame_size ()));
/* Pop frame pointer if we had one. */
if (frame_pointer_needed)
pop (FRAME_POINTER_REGNUM);
pop (HARD_FRAME_POINTER_REGNUM);
}
/* Return nonzero if the current function is an interrupt
@ -1579,33 +1580,59 @@ h8300_expand_movsi (rtx operands[])
int
h8300_initial_elimination_offset (int from, int to)
{
int offset = 0;
/* The number of bytes that the return address takes on the stack. */
int pc_size = POINTER_SIZE / BITS_PER_UNIT;
if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
offset = pc_size + frame_pointer_needed * UNITS_PER_WORD;
else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
offset = frame_pointer_needed * UNITS_PER_WORD;
else
/* The number of bytes that the saved frame pointer takes on the stack. */
int fp_size = frame_pointer_needed * UNITS_PER_WORD;
/* The number of bytes that the saved registers, excluding the frame
pointer, take on the stack. */
int saved_regs_size = 0;
/* The number of bytes that the locals takes on the stack. */
int frame_size = round_frame_size (get_frame_size ());
int regno;
for (regno = 0; regno <= HARD_FRAME_POINTER_REGNUM; regno++)
if (WORD_REG_USED (regno))
saved_regs_size += UNITS_PER_WORD;
/* Adjust saved_regs_size because the above loop took the frame
pointer int account. */
saved_regs_size -= fp_size;
if (to == HARD_FRAME_POINTER_REGNUM)
{
int regno;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (WORD_REG_USED (regno))
offset += UNITS_PER_WORD;
/* See the comments for get_frame_size. We need to round it up to
STACK_BOUNDARY. */
offset += round_frame_size (get_frame_size ());
if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
/* Skip saved PC. */
offset += pc_size;
switch (from)
{
case ARG_POINTER_REGNUM:
return pc_size + fp_size;
case RETURN_ADDRESS_POINTER_REGNUM:
return fp_size;
case FRAME_POINTER_REGNUM:
return -saved_regs_size;
default:
abort ();
}
}
return offset;
else if (to == STACK_POINTER_REGNUM)
{
switch (from)
{
case ARG_POINTER_REGNUM:
return pc_size + saved_regs_size + frame_size;
case RETURN_ADDRESS_POINTER_REGNUM:
return saved_regs_size + frame_size;
case FRAME_POINTER_REGNUM:
return frame_size;
default:
abort ();
}
}
else
abort ();
}
rtx

View File

@ -283,7 +283,7 @@ extern int target_flags;
eliminated during reloading in favor of either the stack or frame
pointer. */
#define FIRST_PSEUDO_REGISTER 11
#define FIRST_PSEUDO_REGISTER 12
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator. */
@ -364,6 +364,9 @@ extern int target_flags;
/* Register to use for pushing function arguments. */
#define STACK_POINTER_REGNUM SP_REG
/* Base register for access to local variables of the function. */
#define HARD_FRAME_POINTER_REGNUM HFP_REG
/* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM FP_REG
@ -575,12 +578,13 @@ enum reg_class {
eliminated; they are replaced with either the stack or frame
pointer. */
#define ELIMINABLE_REGS \
{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
{ RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM},\
{ RETURN_ADDRESS_POINTER_REGNUM, FRAME_POINTER_REGNUM},\
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
#define ELIMINABLE_REGS \
{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
{ RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
/* Given FROM and TO register numbers, say whether this elimination is allowed.
Frame pointer elimination is automatically handled.
@ -1059,7 +1063,7 @@ struct cum_arg
This sequence is indexed by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp", "mac", "ap", "rap" }
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp", "mac", "ap", "rap", "fp" }
#define ADDITIONAL_REGISTER_NAMES \
{ {"er0", 0}, {"er1", 1}, {"er2", 2}, {"er3", 3}, {"er4", 4}, \

View File

@ -55,11 +55,12 @@
(define_constants
[(R0_REG 0)
(SC_REG 3)
(FP_REG 6)
(HFP_REG 6)
(SP_REG 7)
(MAC_REG 8)
(AP_REG 9)
(RAP_REG 10)])
(RAP_REG 10)
(FP_REG 11)])
;; ----------------------------------------------------------------------
;; ATTRIBUTES