rs6000.md (allocate_stack): Always use an update form instruction to update the stack...
authorBen Elliston <bje@au.ibm.com>
Tue, 10 Feb 2009 00:13:34 +0000 (00:13 +0000)
committerBen Elliston <bje@gcc.gnu.org>
Tue, 10 Feb 2009 00:13:34 +0000 (11:13 +1100)
* config/rs6000/rs6000.md (allocate_stack): Always use an update
form instruction to update the stack back chain word, even if the
user has disabled the generation of update instructions.
(movdi_<mode>_update_stack): New.
(movsi_update_stack): Likewise.
* config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Likewise,
always use an update form instruction to update the stack back
chain word.

From-SVN: r144047

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md

index 898448a..47e8199 100644 (file)
@@ -1,3 +1,14 @@
+2009-02-10  Ben Elliston  <bje@au.ibm.com>
+
+       * config/rs6000/rs6000.md (allocate_stack): Always use an update
+       form instruction to update the stack back chain word, even if the
+       user has disabled the generation of update instructions.
+       (movdi_<mode>_update_stack): New.
+       (movsi_update_stack): Likewise.
+       * config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Likewise,
+       always use an update form instruction to update the stack back
+       chain word.
+
 2009-02-09  Sebastian Pop  <sebastian.pop@amd.com>
 
        PR middle-end/38953
index d2ebf62..966a0f7 100644 (file)
@@ -15542,6 +15542,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
   rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
   rtx tmp_reg = gen_rtx_REG (Pmode, 0);
   rtx todec = gen_int_mode (-size, Pmode);
+  rtx par, set, mem;
 
   if (INTVAL (todec) != -size)
     {
@@ -15585,54 +15586,39 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
        warning (0, "stack limit expression is not supported");
     }
 
-  if (copy_r12 || copy_r11 || ! TARGET_UPDATE)
+  if (copy_r12 || copy_r11)
     emit_move_insn (copy_r11
                     ? gen_rtx_REG (Pmode, 11)
                     : gen_rtx_REG (Pmode, 12),
                     stack_reg);
 
-  if (TARGET_UPDATE)
-    {
-      rtx par, set, mem;
-
-      if (size > 32767)
-       {
-         /* Need a note here so that try_split doesn't get confused.  */
-         if (get_last_insn () == NULL_RTX)
-           emit_note (NOTE_INSN_DELETED);
-         insn = emit_move_insn (tmp_reg, todec);
-         try_split (PATTERN (insn), insn, 0);
-         todec = tmp_reg;
-       }
-
-      insn = emit_insn (TARGET_32BIT
-                       ? gen_movsi_update (stack_reg, stack_reg,
-                                           todec, stack_reg)
-                       : gen_movdi_di_update (stack_reg, stack_reg,
-                                           todec, stack_reg));
-      /* Since we didn't use gen_frame_mem to generate the MEM, grab
-        it now and set the alias set/attributes. The above gen_*_update
-        calls will generate a PARALLEL with the MEM set being the first
-        operation. */
-      par = PATTERN (insn);
-      gcc_assert (GET_CODE (par) == PARALLEL);
-      set = XVECEXP (par, 0, 0);
-      gcc_assert (GET_CODE (set) == SET);
-      mem = SET_DEST (set);
-      gcc_assert (MEM_P (mem));
-      MEM_NOTRAP_P (mem) = 1;
-      set_mem_alias_set (mem, get_frame_alias_set ());
-    }
-  else
+  if (size > 32767)
     {
-      insn = emit_insn (TARGET_32BIT
-                       ? gen_addsi3 (stack_reg, stack_reg, todec)
-                       : gen_adddi3 (stack_reg, stack_reg, todec));
-      emit_move_insn (gen_frame_mem (Pmode, stack_reg),
-                     copy_r11
-                      ? gen_rtx_REG (Pmode, 11)
-                      : gen_rtx_REG (Pmode, 12));
+      /* Need a note here so that try_split doesn't get confused.  */
+      if (get_last_insn () == NULL_RTX)
+       emit_note (NOTE_INSN_DELETED);
+      insn = emit_move_insn (tmp_reg, todec);
+      try_split (PATTERN (insn), insn, 0);
+      todec = tmp_reg;
     }
+  
+  insn = emit_insn (TARGET_32BIT
+                   ? gen_movsi_update_stack (stack_reg, stack_reg,
+                                       todec, stack_reg)
+                   : gen_movdi_di_update_stack (stack_reg, stack_reg,
+                                          todec, stack_reg));
+  /* Since we didn't use gen_frame_mem to generate the MEM, grab
+     it now and set the alias set/attributes. The above gen_*_update
+     calls will generate a PARALLEL with the MEM set being the first
+     operation. */
+  par = PATTERN (insn);
+  gcc_assert (GET_CODE (par) == PARALLEL);
+  set = XVECEXP (par, 0, 0);
+  gcc_assert (GET_CODE (set) == SET);
+  mem = SET_DEST (set);
+  gcc_assert (MEM_P (mem));
+  MEM_NOTRAP_P (mem) = 1;
+  set_mem_alias_set (mem, get_frame_alias_set ());
 
   RTX_FRAME_RELATED_P (insn) = 1;
   REG_NOTES (insn) =
index b6f4181..ffbc8ad 100644 (file)
    stdu %3,%2(%0)"
   [(set_attr "type" "store_ux,store_u")])
 
+;; This pattern is only conditional on TARGET_POWERPC64, as it is
+;; needed for stack allocation, even if the user passes -mno-update.
+(define_insn "movdi_<mode>_update_stack"
+  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
+                        (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
+       (match_operand:DI 3 "gpc_reg_operand" "r,r"))
+   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
+       (plus:P (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64"
+  "@
+   stdux %3,%0,%2
+   stdu %3,%2(%0)"
+  [(set_attr "type" "store_ux,store_u")])
+
 (define_insn "*movsi_update1"
   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
        (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
    {stu|stwu} %3,%2(%0)"
   [(set_attr "type" "store_ux,store_u")])
 
+;; This is an unconditional pattern; needed for stack allocation, even
+;; if the user passes -mno-update.
+(define_insn "movsi_update_stack"
+  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
+                        (match_operand:SI 2 "reg_or_short_operand" "r,I")))
+       (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+       (plus:SI (match_dup 1) (match_dup 2)))]
+  ""
+  "@
+   {stux|stwux} %3,%0,%2
+   {stu|stwu} %3,%2(%0)"
+  [(set_attr "type" "store_ux,store_u")])
+
 (define_insn "*movhi_update1"
   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
        (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
 { rtx chain = gen_reg_rtx (Pmode);
   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
   rtx neg_op0;
+  rtx insn, par, set, mem;
 
   emit_move_insn (chain, stack_bot);
 
   else
     neg_op0 = GEN_INT (- INTVAL (operands[1]));
 
-  if (TARGET_UPDATE)
-    {
-      rtx insn, par, set, mem;
-
-      insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update
-                                          : gen_movdi_di_update))
+  insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update
+                                      : gen_movdi_di_update))
                        (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
                         chain));
-      /* Since we didn't use gen_frame_mem to generate the MEM, grab
-         it now and set the alias set/attributes. The above gen_*_update
-         calls will generate a PARALLEL with the MEM set being the first
-         operation. */
-      par = PATTERN (insn);
-      gcc_assert (GET_CODE (par) == PARALLEL);
-      set = XVECEXP (par, 0, 0);
-      gcc_assert (GET_CODE (set) == SET);
-      mem = SET_DEST (set);
-      gcc_assert (MEM_P (mem));
-      MEM_NOTRAP_P (mem) = 1;
-      set_mem_alias_set (mem, get_frame_alias_set ());
-    }
-
-  else
-    {
-      emit_insn ((* ((TARGET_32BIT) ? gen_addsi3 : gen_adddi3))
-                (stack_pointer_rtx, stack_pointer_rtx, neg_op0));
-      emit_move_insn (gen_frame_mem (Pmode, stack_pointer_rtx), chain);
-    }
+  /* Since we didn't use gen_frame_mem to generate the MEM, grab
+     it now and set the alias set/attributes. The above gen_*_update
+     calls will generate a PARALLEL with the MEM set being the first
+     operation. */
+  par = PATTERN (insn);
+  gcc_assert (GET_CODE (par) == PARALLEL);
+  set = XVECEXP (par, 0, 0);
+  gcc_assert (GET_CODE (set) == SET);
+  mem = SET_DEST (set);
+  gcc_assert (MEM_P (mem));
+  MEM_NOTRAP_P (mem) = 1;
+  set_mem_alias_set (mem, get_frame_alias_set ());
 
   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
   DONE;