diff options
author | Kazu Hirata <kazu@cs.umass.edu> | 2004-01-28 22:00:26 +0000 |
---|---|---|
committer | Kazu Hirata <kazu@gcc.gnu.org> | 2004-01-28 22:00:26 +0000 |
commit | 1807b72620dcd77c6542552e83b26683a177199d (patch) | |
tree | 309cd2856bd6e42ad5ca2b6bab7846f65052369d /gcc | |
parent | ff4cf05b3d1cbab6af68db369f277bafa58ce139 (diff) | |
download | gcc-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/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.c | 89 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.h | 20 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.md | 5 |
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 |