mips-protos.h (mips_frame_pointer_required): Declare.
authorRichard Sandiford <rsandifo@nildram.co.uk>
Thu, 18 Oct 2007 19:37:51 +0000 (19:37 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 18 Oct 2007 19:37:51 +0000 (19:37 +0000)
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
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/save-restore-3.c

index bf29a081db87fd6bbc37bfe5e8fd8284b1653512..d54f375d74a2fa2bcb02eb91e174af8b29215267 100644 (file)
@@ -1,3 +1,12 @@
+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
index 371fd93447e31ae32be54d635462f6dea8ef5108..4822f382cb354865eff4e31f587e89d3d25a8b2e 100644 (file)
@@ -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);
index ff4eb9af943d47a575585f11a31b7e15185c01ab..c5b30f7ad9bd8545e7b9d7b247c059be6e078353 100644 (file)
@@ -8030,6 +8030,30 @@ mips_current_loadgp_style (void)
   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.  */
index ac4320a763e4df021631b62a630e05ea75e4b0e9..46356fe73151152e4802c4e6c451f3a14dedb5c0 100644 (file)
@@ -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))
index cbda26de31e884f71f4fcaf00a68ec7ad02a8476..22586ef1371765257abddffddd43edb59dd305d7 100644 (file)
@@ -1,3 +1,7 @@
+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
index 674072dd7b0253104a3ace4984238e6bf50c5eee..a73e83b9fffd3be109d0e7ba70a91f39974e0d3a 100644 (file)
@@ -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;