OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Oct 2011 17:46:11 +0000 (17:46 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Oct 2011 17:46:11 +0000 (17:46 +0000)
* config/mips/mips.c (mips_frame_barrier): New function.
(mips_expand_prologue): Call it after allocating stack space.
(mips_deallocate_stack): New function.
(mips_expand_epilogue): Call mips_frame_barrier and
mips_deallocate_stack.

gcc/testsuite/
* gcc.target/mips/stack-1.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179432 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/stack-1.c [new file with mode: 0644]

index b8197fa..5a30b57 100644 (file)
@@ -1,5 +1,13 @@
 2011-10-02  Richard Sandiford  <rdsandiford@googlemail.com>
 
+       * config/mips/mips.c (mips_frame_barrier): New function.
+       (mips_expand_prologue): Call it after allocating stack space.
+       (mips_deallocate_stack): New function.
+       (mips_expand_epilogue): Call mips_frame_barrier and
+       mips_deallocate_stack.
+
+2011-10-02  Richard Sandiford  <rdsandiford@googlemail.com>
+
        PR target/49696
        * config/mips/sync.md (sync_<optab>_12): Allow zero operands.
        (sync_old_<optab>_12, sync_new_<optab>_12, sync_nand_12): Likewise.
index d0b6b4c..ff72e28 100644 (file)
@@ -9892,6 +9892,14 @@ mips_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
   mips_end_function_definition (fnname);
 }
 \f
+/* Emit an optimisation barrier for accesses to the current frame.  */
+
+static void
+mips_frame_barrier (void)
+{
+  emit_clobber (gen_frame_mem (BLKmode, stack_pointer_rtx));
+}
+
 /* Save register REG to MEM.  Make the instruction frame-related.  */
 
 static void
@@ -10035,6 +10043,7 @@ mips_expand_prologue (void)
          insn = mips16e_build_save_restore (false, &mask, &offset,
                                             nargs, step1);
          RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
+         mips_frame_barrier ();
          size -= step1;
 
          /* Check if we need to save other registers.  */
@@ -10075,6 +10084,7 @@ mips_expand_prologue (void)
              insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
                                    GEN_INT (-step1));
              RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
+             mips_frame_barrier ();
              size -= step1;
 
              /* Start at the uppermost location for saving.  */
@@ -10135,6 +10145,7 @@ mips_expand_prologue (void)
                                    stack_pointer_rtx,
                                    GEN_INT (-step1));
              RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
+             mips_frame_barrier ();
              size -= step1;
            }
          mips_for_each_saved_acc (size, mips_save_reg);
@@ -10175,6 +10186,7 @@ mips_expand_prologue (void)
            (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
                          plus_constant (stack_pointer_rtx, -size)));
        }
+      mips_frame_barrier ();
     }
 
   /* Set up the frame pointer, if we're using one.  */
@@ -10315,6 +10327,35 @@ mips_restore_reg (rtx reg, rtx mem)
                           mips_epilogue.cfa_restore_sp_offset);
 }
 
+/* Emit code to set the stack pointer to BASE + OFFSET, given that
+   BASE + OFFSET is NEW_FRAME_SIZE bytes below the top of the frame.
+   BASE, if not the stack pointer, is available as a temporary.  */
+
+static void
+mips_deallocate_stack (rtx base, rtx offset, HOST_WIDE_INT new_frame_size)
+{
+  if (base == stack_pointer_rtx && offset == const0_rtx)
+    return;
+
+  mips_frame_barrier ();
+  if (offset == const0_rtx)
+    {
+      emit_move_insn (stack_pointer_rtx, base);
+      mips_epilogue_set_cfa (stack_pointer_rtx, new_frame_size);
+    }
+  else if (TARGET_MIPS16 && base != stack_pointer_rtx)
+    {
+      emit_insn (gen_add3_insn (base, base, offset));
+      mips_epilogue_set_cfa (base, new_frame_size);
+      emit_move_insn (stack_pointer_rtx, base);
+    }
+  else
+    {
+      emit_insn (gen_add3_insn (stack_pointer_rtx, base, offset));
+      mips_epilogue_set_cfa (stack_pointer_rtx, new_frame_size);
+    }
+}
+
 /* Emit any instructions needed before a return.  */
 
 void
@@ -10341,7 +10382,7 @@ mips_expand_epilogue (bool sibcall_p)
 {
   const struct mips_frame_info *frame;
   HOST_WIDE_INT step1, step2;
-  rtx base, target, insn;
+  rtx base, adjust, insn;
 
   if (!sibcall_p && mips_can_use_return_insn ())
     {
@@ -10384,31 +10425,14 @@ mips_expand_epilogue (bool sibcall_p)
       step1 -= step2;
     }
 
-  /* Set TARGET to BASE + STEP1.  */
-  target = base;
-  if (step1 > 0)
+  /* Get an rtx for STEP1 that we can add to BASE.  */
+  adjust = GEN_INT (step1);
+  if (!SMALL_OPERAND (step1))
     {
-      rtx adjust;
-
-      /* Get an rtx for STEP1 that we can add to BASE.  */
-      adjust = GEN_INT (step1);
-      if (!SMALL_OPERAND (step1))
-       {
-         mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode), adjust);
-         adjust = MIPS_EPILOGUE_TEMP (Pmode);
-       }
-
-      /* Normal mode code can copy the result straight into $sp.  */
-      if (!TARGET_MIPS16)
-       target = stack_pointer_rtx;
-
-      emit_insn (gen_add3_insn (target, base, adjust));
-      mips_epilogue_set_cfa (target, step2);
+      mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode), adjust);
+      adjust = MIPS_EPILOGUE_TEMP (Pmode);
     }
-
-  /* Copy TARGET into the stack pointer.  */
-  if (target != stack_pointer_rtx)
-    mips_emit_move (stack_pointer_rtx, target);
+  mips_deallocate_stack (base, adjust, step2);
 
   /* If we're using addressing macros, $gp is implicitly used by all
      SYMBOL_REFs.  We must emit a blockage insn before restoring $gp
@@ -10437,6 +10461,7 @@ mips_expand_epilogue (bool sibcall_p)
 
       /* Restore the remaining registers and deallocate the final bit
         of the frame.  */
+      mips_frame_barrier ();
       emit_insn (restore);
       mips_epilogue_set_cfa (stack_pointer_rtx, 0);
     }
@@ -10473,13 +10498,8 @@ mips_expand_epilogue (bool sibcall_p)
          offset -= UNITS_PER_WORD;
 
          /* If we don't use shoadow register set, we need to update SP.  */
-         if (!cfun->machine->use_shadow_register_set_p && step2 > 0)
-           {
-             emit_insn (gen_add3_insn (stack_pointer_rtx,
-                                       stack_pointer_rtx,
-                                       GEN_INT (step2)));
-             mips_epilogue_set_cfa (stack_pointer_rtx, 0);
-           }
+         if (!cfun->machine->use_shadow_register_set_p)
+           mips_deallocate_stack (stack_pointer_rtx, GEN_INT (step2), 0);
          else
            /* The choice of position is somewhat arbitrary in this case.  */
            mips_epilogue_emit_cfa_restores ();
@@ -10489,16 +10509,8 @@ mips_expand_epilogue (bool sibcall_p)
                                    gen_rtx_REG (SImode, K0_REG_NUM)));
        }
       else
-       {
-         /* Deallocate the final bit of the frame.  */
-         if (step2 > 0)
-           {
-             emit_insn (gen_add3_insn (stack_pointer_rtx,
-                                       stack_pointer_rtx,
-                                       GEN_INT (step2)));
-             mips_epilogue_set_cfa (stack_pointer_rtx, 0);
-           }
-       }
+       /* Deallocate the final bit of the frame.  */
+       mips_deallocate_stack (stack_pointer_rtx, GEN_INT (step2), 0);
     }
   gcc_assert (!mips_epilogue.cfa_restores);
 
index 56a9cc1..f6829f0 100644 (file)
@@ -1,5 +1,9 @@
 2011-10-02  Richard Sandiford  <rdsandiford@googlemail.com>
 
+       * gcc.target/mips/stack-1.c: New test.
+
+2011-10-02  Richard Sandiford  <rdsandiford@googlemail.com>
+
        * gcc.dg/pr49696.c: New test.
 
 2011-10-02  Jan Hubicka  <jh@suse.cz>
diff --git a/gcc/testsuite/gcc.target/mips/stack-1.c b/gcc/testsuite/gcc.target/mips/stack-1.c
new file mode 100644 (file)
index 0000000..3d49545
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "addiu\t(\\\$sp,)?\\\$sp,\[1-9\]" } } */
+/* { dg-final { scan-assembler "\tlw\t" } } */
+/* { dg-final { scan-assembler-not "addiu\t(\\\$sp,)?\\\$sp,\[1-9\].*\tlw\t" } } */
+
+int foo (int y)
+{
+  volatile int a = y;
+  volatile int *volatile b = &a;
+  return *b;
+}