mips.c (mips16e_save_restore_pattern_p): Check that the topmost argument register...
authorRichard Sandiford <richard@codesourcery.com>
Fri, 6 Jul 2007 09:20:46 +0000 (09:20 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 6 Jul 2007 09:20:46 +0000 (09:20 +0000)
gcc/
* config/mips/mips.c (mips16e_save_restore_pattern_p): Check that
the topmost argument register is not also included in the save mask.
(mips16e_collect_argument_save_p): Take a pointer to the argument
register, rather than a pointer to the number of arguments.
(mips16e_collect_argument_saves): Only include argument saves
that aren't in the register mask.

gcc/testsuite/
* gcc.target/mips/save-restore-5.c: New test.

From-SVN: r126404

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/save-restore-5.c [new file with mode: 0644]

index b36c38034916e69a3a70f25578385fff7abe7164..240d5e783ab8b66406e43ea083a64850107c7cca 100644 (file)
@@ -1,3 +1,12 @@
+2007-07-06  Richard Sandiford  <richard@codesourcery.com>
+
+       * config/mips/mips.c (mips16e_save_restore_pattern_p): Check that
+       the topmost argument register is not also included in the save mask.
+       (mips16e_collect_argument_save_p): Take a pointer to the argument
+       register, rather than a pointer to the number of arguments.
+       (mips16e_collect_argument_saves): Only include argument saves
+       that aren't in the register mask.
+
 2007-07-06  Uros Bizjak  <ubizjak@gmail.com>
 
        PR rtl_optimization/32450
index 783ff034296db2e314e0905c89047d8ffba81952..8c7b70c2485f8c4a3156e90dba30d066a57b94ba 100644 (file)
@@ -7334,6 +7334,12 @@ mips16e_save_restore_pattern_p (rtx pattern, HOST_WIDE_INT adjust,
   if (extra != 0)
     return false;
 
+  /* Make sure that the topmost argument register is not saved twice.
+     The checks above ensure that the same is then true for the other
+     argument registers.  */
+  if (nargs > 0 && BITSET_P (mask, GP_ARG_FIRST + nargs - 1))
+    return false;
+
   /* Pass back information, if requested.  */
   if (info)
     {
@@ -7458,14 +7464,13 @@ mips16e_collect_propagate_value (rtx x, rtx *reg_values)
 }
 
 /* Return true if (set DEST SRC) stores an argument register into its
-   caller-allocated save slot.  If the register is not included in
-   [GP_ARG_FIRST, GP_ARG_LAST + *NARGS_PTR), destructively modify
-   *NARGS_PTR such that this condition holds.  REG_VALUES is as for
+   caller-allocated save slot, storing the number of that argument
+   register in *REGNO_PTR if so.  REG_VALUES is as for
    mips16e_collect_propagate_value.  */
 
 static bool
-mips16e_collect_argument_save (rtx dest, rtx src, rtx *reg_values,
-                              unsigned int *nargs_ptr)
+mips16e_collect_argument_save_p (rtx dest, rtx src, rtx *reg_values,
+                                unsigned int *regno_ptr)
 {
   unsigned int argno, regno;
   HOST_WIDE_INT offset, required_offset;
@@ -7495,10 +7500,7 @@ mips16e_collect_argument_save (rtx dest, rtx src, rtx *reg_values,
   if (offset != required_offset)
     return false;
 
-  /* Make sure that *NARGS_PTR is big enough.  */
-  if (*nargs_ptr <= argno)
-    *nargs_ptr = argno + 1;
-
+  *regno_ptr = regno;
   return true;
 }
 
@@ -7514,7 +7516,7 @@ mips16e_collect_argument_saves (void)
 {
   rtx reg_values[FIRST_PSEUDO_REGISTER];
   rtx insn, next, set, dest, src;
-  unsigned int nargs;
+  unsigned int nargs, regno;
 
   push_topmost_sequence ();
   nargs = 0;
@@ -7534,8 +7536,14 @@ mips16e_collect_argument_saves (void)
 
       dest = SET_DEST (set);
       src = SET_SRC (set);
-      if (mips16e_collect_argument_save (dest, src, reg_values, &nargs))
-       delete_insn (insn);
+      if (mips16e_collect_argument_save_p (dest, src, reg_values, &regno))
+       {
+         if (!BITSET_P (cfun->machine->frame.mask, regno))
+           {
+             delete_insn (insn);
+             nargs = MAX (nargs, (regno - GP_ARG_FIRST) + 1);
+           }
+       }
       else if (REG_P (dest) && GET_MODE (dest) == word_mode)
        reg_values[REGNO (dest)]
          = mips16e_collect_propagate_value (src, reg_values);
index 3772aff6f9c716f7bd3d47a1e1fa14619d99bb8d..a630290063c0b225e05686a27e9dd1f768124c55 100644 (file)
@@ -1,3 +1,7 @@
+2007-07-06  Richard Sandiford  <richard@codesourcery.com>
+
+       * gcc.target/mips/save-restore-5.c: New test.
+
 2007-07-06  Uros Bizjak  <ubizjak@gmail.com>
 
        PR rtl_optimization/32450
diff --git a/gcc/testsuite/gcc.target/mips/save-restore-5.c b/gcc/testsuite/gcc.target/mips/save-restore-5.c
new file mode 100644 (file)
index 0000000..6c2f37c
--- /dev/null
@@ -0,0 +1,16 @@
+/* Check that we don't try to save the same register twice.  */
+/* { dg-mips-options "-mips32r2 -mgp32 -mips16 -O2" } */
+/* { dg-do assemble } */
+
+int bar (int, int, int, int);
+void frob (void);
+
+void
+foo (int a1, int a2, int a3, int a4)
+{
+  asm volatile ("" ::: "$2", "$3", "$4", "$5", "$6", "$7", "$8",
+               "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16",
+               "$18", "$19", "$20", "$21", "$22", "$23", "$24",
+               "$25", "$30", "$31", "memory");
+  __builtin_eh_return (bar (a1, a2, a3, a4), frob);
+}