aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@nildram.co.uk>2007-10-18 19:37:51 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2007-10-18 19:37:51 +0000
commit29c4d304fd99684f08863ecd1705ddead325a312 (patch)
treef849d99a9b6e50ea598779a4aafdca46225d4631 /gcc/config/mips
parentf374e413a7bf93f07c5a9ddde89138e5c3442306 (diff)
downloadgcc-29c4d304fd99684f08863ecd1705ddead325a312.zip
gcc-29c4d304fd99684f08863ecd1705ddead325a312.tar.gz
gcc-29c4d304fd99684f08863ecd1705ddead325a312.tar.bz2
mips-protos.h (mips_frame_pointer_required): Declare.
gcc/ * 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. From-SVN: r129459
Diffstat (limited to 'gcc/config/mips')
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.c24
-rw-r--r--gcc/config/mips/mips.h22
3 files changed, 30 insertions, 17 deletions
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 371fd93..4822f38 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -255,6 +255,7 @@ extern void mips_finish_declare_object (FILE *, tree, int, int);
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);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index ff4eb9a..c5b30f7 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -8030,6 +8030,30 @@ mips_current_loadgp_style (void)
return TARGET_NEWABI ? LOADGP_NEWABI : LOADGP_OLDABI;
}
+/* 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. */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index ac4320a..46356fe 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1585,11 +1585,7 @@ enum mips_code_readable_setting {
#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)
@@ -1916,18 +1912,10 @@ enum reg_class
{ 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))