summaryrefslogtreecommitdiff
path: root/gcc/config/pdp11/pdp11.c
diff options
context:
space:
mode:
authorpkoning <pkoning@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-20 19:11:32 +0000
committerpkoning <pkoning@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-20 19:11:32 +0000
commit968a05f9d449cf7f05c752704dfac263a7b37d69 (patch)
tree5438898281b6802861fe1345022684ff79a3694d /gcc/config/pdp11/pdp11.c
parenta9ffdd35be0418ab7365af96db0ee687266009d4 (diff)
downloadgcc-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.c69
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