From 29c4d304fd99684f08863ecd1705ddead325a312 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 18 Oct 2007 19:37:51 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 9 +++++++ gcc/config/mips/mips-protos.h | 1 + gcc/config/mips/mips.c | 24 +++++++++++++++++++ gcc/config/mips/mips.h | 22 ++++------------- gcc/testsuite/ChangeLog | 4 ++++ .../gcc.target/mips/save-restore-3.c | 2 +- 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bf29a081db8..d54f375d74a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2007-10-18 Richard Sandiford + + * 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 * config/mips/mips.c (mips_frame_info): Add arg_pointer_offset diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 371fd93447e..4822f382cb3 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 ff4eb9af943..c5b30f7ad9b 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 ac4320a763e..46356fe7315 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)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cbda26de31e..22586ef1371 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-10-18 Richard Sandiford + + * gcc.target/mips/save-restore-3.c: Don't clobber $17. + 2007-10-18 Paul Thomas PR fortran/33233 diff --git a/gcc/testsuite/gcc.target/mips/save-restore-3.c b/gcc/testsuite/gcc.target/mips/save-restore-3.c index 674072dd7b0..a73e83b9fff 100644 --- a/gcc/testsuite/gcc.target/mips/save-restore-3.c +++ b/gcc/testsuite/gcc.target/mips/save-restore-3.c @@ -12,7 +12,7 @@ foo (int *a, int b, int c) 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; -- 2.30.2