diff options
author | Richard Sandiford <rsandifo@nildram.co.uk> | 2007-10-18 19:37:51 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-10-18 19:37:51 +0000 |
commit | 29c4d304fd99684f08863ecd1705ddead325a312 (patch) | |
tree | f849d99a9b6e50ea598779a4aafdca46225d4631 /gcc/config/mips | |
parent | f374e413a7bf93f07c5a9ddde89138e5c3442306 (diff) | |
download | gcc-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.h | 1 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 24 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 22 |
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)) |