* config/mips/mips-protos.h (mips_frame_pointer_required): Declare.
* config/mips/mips.h (FRAME_POINTER_REQUIRED): Use
mips_hard_frame_pointer_required.
(CAN_ELIMINATE): Rely on FRAME_POINTER_REQUIRED to check for
large MIPS16 frames.
* config/mips/mips.c (mips_frame_pointer_required): New function.
gcc/testsuite/
* gcc.target/mips/save-restore-3.c: Don't clobber $17.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129459
138bc75d-0d04-0410-961f-
82ee72b054a4
2007-10-18 Richard Sandiford <rsandifo@nildram.co.uk>
+ * config/mips/mips-protos.h (mips_frame_pointer_required): Declare.
+ * config/mips/mips.h (FRAME_POINTER_REQUIRED): Use
+ mips_hard_frame_pointer_required.
+ (CAN_ELIMINATE): Rely on FRAME_POINTER_REQUIRED to check for
+ large MIPS16 frames.
+ * config/mips/mips.c (mips_frame_pointer_required): New function.
+
+2007-10-18 Richard Sandiford <rsandifo@nildram.co.uk>
+
* config/mips/mips.c (mips_frame_info): Add arg_pointer_offset
and hard_frame_pointer_offset.
(mips_debugger_offset): Use hard_frame_pointer_offset.
extern bool mips_small_data_pattern_p (rtx);
extern rtx mips_rewrite_small_data (rtx);
+extern bool mips_frame_pointer_required (void);
extern HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT);
extern HOST_WIDE_INT mips_initial_elimination_offset (int, int);
extern rtx mips_return_addr (int, rtx);
return TARGET_NEWABI ? LOADGP_NEWABI : LOADGP_OLDABI;
}
\f
+/* Implement FRAME_POINTER_REQUIRED. */
+
+bool
+mips_frame_pointer_required (void)
+{
+ /* If the function contains dynamic stack allocations, we need to
+ use the frame pointer to access the static parts of the frame. */
+ if (current_function_calls_alloca)
+ return true;
+
+ /* In MIPS16 mode, we need a frame pointer for a large frame; otherwise,
+ reload may be unable to compute the address of a local variable,
+ since there is no way to add a large constant to the stack pointer
+ without using a second temporary register. */
+ if (TARGET_MIPS16)
+ {
+ compute_frame_size (get_frame_size ());
+ if (!SMALL_OPERAND (cfun->machine->frame.total_size))
+ return true;
+ }
+
+ return false;
+}
+
/* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame
pointer or argument pointer. TO is either the stack pointer or
hard frame pointer. */
#define HARD_FRAME_POINTER_REGNUM \
(TARGET_MIPS16 ? GP_REG_FIRST + 17 : GP_REG_FIRST + 30)
-/* Value should be nonzero if functions must have frame pointers.
- Zero means the frame pointer need not be set up (and parms
- may be accessed via the stack pointer) in functions that seem suitable.
- This is computed in `reload', in reload1.c. */
-#define FRAME_POINTER_REQUIRED (current_function_calls_alloca)
+#define FRAME_POINTER_REQUIRED (mips_frame_pointer_required ())
/* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM (GP_REG_FIRST + 2)
{ FRAME_POINTER_REGNUM, GP_REG_FIRST + 30}, \
{ FRAME_POINTER_REGNUM, GP_REG_FIRST + 17}}
-/* We can always eliminate to the hard frame pointer. We can eliminate
- to the stack pointer unless a frame pointer is needed.
-
- In mips16 mode, we need a frame pointer for a large frame; otherwise,
- reload may be unable to compute the address of a local variable,
- since there is no way to add a large constant to the stack pointer
- without using a temporary register. */
-#define CAN_ELIMINATE(FROM, TO) \
- ((TO) == HARD_FRAME_POINTER_REGNUM \
- || ((TO) == STACK_POINTER_REGNUM && !frame_pointer_needed \
- && (!TARGET_MIPS16 \
- || compute_frame_size (get_frame_size ()) < 32768)))
+/* Make sure that we're not trying to eliminate to the wrong hard frame
+ pointer. */
+#define CAN_ELIMINATE(FROM, TO) \
+ ((TO) == HARD_FRAME_POINTER_REGNUM || (TO) == STACK_POINTER_REGNUM)
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
(OFFSET) = mips_initial_elimination_offset ((FROM), (TO))
+2007-10-18 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * gcc.target/mips/save-restore-3.c: Don't clobber $17.
+
2007-10-18 Paul Thomas <pault@gcc.gnu.org>
PR fortran/33233
int x[0x4000];
asm volatile ("" ::: "$2", "$3", "$4", "$5", "$6", "$7", "$8",
"$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16",
- "$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24",
+ "$18", "$19", "$20", "$21", "$22", "$23", "$24",
"$25", "$30", "memory");
bar (x);
a[b] = 1;