diff options
author | pkoning <pkoning@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-20 19:11:32 +0000 |
---|---|---|
committer | pkoning <pkoning@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-20 19:11:32 +0000 |
commit | 968a05f9d449cf7f05c752704dfac263a7b37d69 (patch) | |
tree | 5438898281b6802861fe1345022684ff79a3694d /gcc/config/pdp11/pdp11.c | |
parent | a9ffdd35be0418ab7365af96db0ee687266009d4 (diff) | |
download | gcc-968a05f9d449cf7f05c752704dfac263a7b37d69.tar.gz |
* config/pdp11/pdp11-protos.h (pdp11_initial_elimination_offset,
pdp11_regno_reg_class): New functions.
* config/pdp11/pdp11.md (define_constants): Add register numbers.
* config/pdp11/pdp11.c (pdp11_regno_reg_class,
pdp11_sp_frame_offset, pdp11_initial_elimination_offset): New
functions.
* config/pdp11/pdp11.h (FIXED_REGISTERS, CALL_USED_REGISTERS): Add
frame pointer and argument pointer pseudo-registers.
(ARG_POINTER_REGNUM): Define.
(REG_CLASS_CONTENTS, REGNO_REG_CLASS): Add frame pointer and
argument pointer.
(FIRST_PARM_OFFSET): Update for argument pointer.
(INITIAL_FRAME_POINTER_OFFSET): Delete.
(ELIMINABLE_REGS, INITIAL_ELIMINATION_OFFSET): New macros.
(REGNO_OK_FOR_BASE_P, REGNO_OK_FOR_INDEX_P, REGISTER_NAMES): Add
frame pointer and argument pointer.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166978 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/pdp11/pdp11.c')
-rw-r--r-- | gcc/config/pdp11/pdp11.c | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index 760026df7d2..617a7f56080 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -300,7 +300,7 @@ pdp11_output_function_prologue (FILE *stream, HOST_WIDE_INT size) asm_fprintf (stream, "\tsub $%#wo, sp\n", fsize); /* save CPU registers */ - for (regno = 0; regno <= PC_REGNUM; regno++) + for (regno = R0_REGNUM; regno <= PC_REGNUM; regno++) if (df_regs_ever_live_p (regno) && ! call_used_regs[regno]) if (! ((regno == FRAME_POINTER_REGNUM) && frame_pointer_needed)) @@ -379,7 +379,7 @@ pdp11_output_function_epilogue (FILE *stream, HOST_WIDE_INT size) k = 2*j; /* change fp -> r5 due to the compile error on libgcc2.c */ - for (i = PC_REGNUM ; i >= 0 ; i--) + for (i = PC_REGNUM ; i >= R0_REGNUM ; i--) if (df_regs_ever_live_p (i) && ! call_used_regs[i]) fprintf(stream, "\tmov %#" HOST_WIDE_INT_PRINT "o(r5), %s\n", (-fsize-2*j--)&0xffff, reg_names[i]); @@ -1706,6 +1706,71 @@ pdp11_secondary_memory_needed (reg_class_t c1, reg_class_t c2, return (fromfloat != tofloat); } +/* Return the class number of the smallest class containing + reg number REGNO. */ +enum reg_class +pdp11_regno_reg_class (int regno) +{ + if (regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM) + return GENERAL_REGS; + else if (regno > AC3_REGNUM) + return NO_LOAD_FPU_REGS; + else if (regno >= AC0_REGNUM) + return LOAD_FPU_REGS; + else if (regno & 1) + return MUL_REGS; + else + return GENERAL_REGS; +} + + +static int +pdp11_sp_frame_offset (void) +{ + int offset = 0, regno; + offset = get_frame_size(); + for (regno = 0; regno <= PC_REGNUM; regno++) + if (df_regs_ever_live_p (regno) && ! call_used_regs[regno]) + offset += 2; + for (regno = AC0_REGNUM; regno <= AC5_REGNUM; regno++) + if (df_regs_ever_live_p (regno) && ! call_used_regs[regno]) + offset += 8; + + return offset; +} + +/* Return the offset between two registers, one to be eliminated, and the other + its replacement, at the start of a routine. */ + +int +pdp11_initial_elimination_offset (int from, int to) +{ + int spoff; + + if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) + return 4; + else if (from == FRAME_POINTER_REGNUM + && to == HARD_FRAME_POINTER_REGNUM) + return 0; + else + { + gcc_assert (to == STACK_POINTER_REGNUM); + + /* Get the size of the register save area. */ + spoff = pdp11_sp_frame_offset (); + if (from == FRAME_POINTER_REGNUM) + return spoff; + + gcc_assert (from == ARG_POINTER_REGNUM); + + /* If there is a frame pointer, that is saved too. */ + if (frame_pointer_needed) + spoff += 2; + + /* Account for the saved PC in the function call. */ + return spoff + 2; + } +} /* A copy of output_addr_const modified for pdp11 expression syntax. output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't |