aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKazu Hirata <kazu@cs.umass.edu>2004-01-28 22:00:26 +0000
committerKazu Hirata <kazu@gcc.gnu.org>2004-01-28 22:00:26 +0000
commit1807b72620dcd77c6542552e83b26683a177199d (patch)
tree309cd2856bd6e42ad5ca2b6bab7846f65052369d /gcc
parentff4cf05b3d1cbab6af68db369f277bafa58ce139 (diff)
downloadgcc-1807b72620dcd77c6542552e83b26683a177199d.zip
gcc-1807b72620dcd77c6542552e83b26683a177199d.tar.gz
gcc-1807b72620dcd77c6542552e83b26683a177199d.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/h8300/h8300.c89
-rw-r--r--gcc/config/h8300/h8300.h20
-rw-r--r--gcc/config/h8300/h8300.md5
4 files changed, 94 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 594c802..a1a8961 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,26 @@
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.
2004-01-28 Ian Lance Taylor <ian@wasabisystems.com>
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 7f027b2..1773616 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -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
- {
- int regno;
+ /* The number of bytes that the saved frame pointer takes on the stack. */
+ int fp_size = frame_pointer_needed * UNITS_PER_WORD;
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (WORD_REG_USED (regno))
- offset += UNITS_PER_WORD;
+ /* The number of bytes that the saved registers, excluding the frame
+ pointer, take on the stack. */
+ int saved_regs_size = 0;
- /* See the comments for get_frame_size. We need to round it up to
- STACK_BOUNDARY. */
+ /* The number of bytes that the locals takes on the stack. */
+ int frame_size = round_frame_size (get_frame_size ());
- offset += round_frame_size (get_frame_size ());
+ int regno;
- if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
- /* Skip saved PC. */
- offset += pc_size;
- }
+ for (regno = 0; regno <= HARD_FRAME_POINTER_REGNUM; regno++)
+ if (WORD_REG_USED (regno))
+ saved_regs_size += UNITS_PER_WORD;
- return offset;
+ /* 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)
+ {
+ 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 ();
+ }
+ }
+ 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
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index 3967d67..ffcc04a 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -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. */
@@ -365,6 +365,9 @@ extern int target_flags;
#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
/* Value should be nonzero if functions must have frame pointers.
@@ -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}, \
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index fe21997..b8c0c92 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -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