aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1995-12-19 15:30:21 -0800
committerJim Wilson <wilson@gcc.gnu.org>1995-12-19 15:30:21 -0800
commit39dffea3c7e295b6e847f6709605de5ff2aff038 (patch)
tree769ec9ff546ec6c0bf9b25c61cd91394b099e593
parentb987661c069eddeab42d9df123f515bdc53bb5a0 (diff)
downloadgcc-39dffea3c7e295b6e847f6709605de5ff2aff038.zip
gcc-39dffea3c7e295b6e847f6709605de5ff2aff038.tar.gz
gcc-39dffea3c7e295b6e847f6709605de5ff2aff038.tar.bz2
(FIRST_PSEUDO_REGISTER): Increment.
(FIXED_REGISTERS, CALL_USED_REGISTERS, REGISTER_NAMES, DEBUG_REGISTER_NAMES): Add entry for new RAP reg. (RAP_REG_NUM, RETURN_ADDRESS_POINTER_REGNUM): New macros. (RETURN_ADDR_RTX): Define. (ELIMINABLE_REGS, CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): Add RETURN_ADDRESS_POINTER_REGNUM support. From-SVN: r10819
-rw-r--r--gcc/config/mips/mips.h51
1 files changed, 43 insertions, 8 deletions
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index a6a469f..bfb516f 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1173,12 +1173,14 @@ do { \
even those that are not normally considered general registers.
On the Mips, we have 32 integer registers, 32 floating point
- registers and the special registers hi, lo, hilo, and fp status.
+ registers and the special registers hi, lo, hilo, fp status, and rap.
The hilo register is only used in 64 bit mode. It represents a 64
bit value stored as two 32 bit values in the hi and lo registers;
- this is the result of the mult instruction. */
+ this is the result of the mult instruction. rap is a pointer to the
+ stack where the return address reg ($31) was stored. This is needed
+ for C++ exception handling. */
-#define FIRST_PSEUDO_REGISTER 68
+#define FIRST_PSEUDO_REGISTER 69
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
@@ -1191,7 +1193,7 @@ do { \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 1 \
+ 0, 0, 0, 1, 1 \
}
@@ -1208,7 +1210,7 @@ do { \
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 1, 1, 1, 1 \
+ 1, 1, 1, 1, 1 \
}
@@ -1234,6 +1236,8 @@ do { \
#define ST_REG_LAST 67
#define ST_REG_NUM (ST_REG_LAST - ST_REG_FIRST + 1)
+#define RAP_REG_NUM 68
+
#define AT_REGNUM (GP_REG_FIRST + 1)
#define HI_REGNUM (MD_REG_FIRST + 0)
#define LO_REGNUM (MD_REG_FIRST + 1)
@@ -1306,6 +1310,10 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
/* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM GP_REG_FIRST
+/* Fake register that holds the address on the stack of the
+ current function's return address. */
+#define RETURN_ADDRESS_POINTER_REGNUM RAP_REG_NUM
+
/* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM (GP_REG_FIRST + 2)
@@ -1675,6 +1683,25 @@ extern enum reg_class mips_secondary_reload_class ();
: current_function_outgoing_args_size)
#endif
+/* The return address for the current frame is in r31 is this is a leaf
+ function. Otherwise, it is on the stack. It is at a variable offset
+ from sp/fp/ap, so we define a fake hard register rap which is a
+ poiner to the return address on the stack. This always gets eliminated
+ during reload to be either the frame pointer or the stack pointer plus
+ an offset. */
+
+/* ??? This definition fails for leaf functions. There is currently no
+ general solution for this problem. */
+
+/* ??? There appears to be no way to get the return address of any previous
+ frame except by disassembling instructions in the prologue/epilogue.
+ So currently we support only the current frame. */
+
+#define RETURN_ADDR_RTX(count, frame) \
+ ((count == 0) \
+ ? gen_rtx (MEM, Pmode, gen_rtx (REG, Pmode, RETURN_ADDRESS_POINTER_REGNUM))\
+ : (fatal ("RETURN_ADDR_RTX not supported for count != 0"), (rtx) 0))
+
/* Structure to be filled in by compute_frame_size with register
save masks, and offsets for the current function. */
@@ -1736,9 +1763,10 @@ extern struct mips_frame_info current_frame_info;
#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}}
-
/* A C expression that returns non-zero if the compiler is allowed to
try to replace register number FROM-REG with register number
TO-REG. This macro need only be defined if `ELIMINABLE_REGS' is
@@ -1748,7 +1776,9 @@ extern struct mips_frame_info current_frame_info;
#define CAN_ELIMINATE(FROM, TO) \
(!frame_pointer_needed \
- || ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM))
+ || ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \
+ || ((FROM) == RETURN_ADDRESS_POINTER_REGNUM \
+ && (TO) == FRAME_POINTER_REGNUM))
/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It
specifies the initial difference between the specified pair of
@@ -1766,6 +1796,10 @@ extern struct mips_frame_info current_frame_info;
- (ABI_64BIT && mips_isa >= 3 \
? current_function_pretend_args_size \
: 0)); \
+ else if ((FROM) == RETURN_ADDRESS_POINTER_REGNUM \
+ && ((TO) == FRAME_POINTER_REGNUM \
+ || (TO) == STACK_POINTER_REGNUM)) \
+ (OFFSET) = current_frame_info.gp_sp_offset; \
else \
abort (); \
}
@@ -3135,6 +3169,7 @@ while (0)
&mips_reg_names[65][0], \
&mips_reg_names[66][0], \
&mips_reg_names[67][0], \
+ &mips_reg_names[68][0], \
}
/* print-rtl.c can't use REGISTER_NAMES, since it depends on mips.c.
@@ -3149,7 +3184,7 @@ while (0)
"$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", \
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", \
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", \
- "hi", "lo", "accum","$fcr31" \
+ "hi", "lo", "accum","$fcr31","$rap" \
}
/* If defined, a C initializer for an array of structures