s390-protos.h (s390_back_chain_rtx): Add prototype.
authorUlrich Weigand <uweigand@de.ibm.com>
Sat, 25 Sep 2004 00:16:56 +0000 (00:16 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Sat, 25 Sep 2004 00:16:56 +0000 (00:16 +0000)
* config/s390/s390-protos.h (s390_back_chain_rtx): Add prototype.
* config/s390/s390.c (s390_back_chain_rtx): New function.
* config/s390/s390.md ("allocate_stack"): Use s390_back_chain_rtx.
Call anti_adjust_stack.
("restore_stack_block"): Use s390_back_chain_rtx.  Enable pattern
only if compiling with back chain.
("save_stack_nonlocal", "restore_stack_nonlocal"): Save/restore
back chain only if back chain enabled.  Use s390_back_chain_rtx.

From-SVN: r88087

gcc/ChangeLog
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.md

index f967b7b3d95059d464b6b5175108123fe8abf571..ab76350aa11f7e41cfb0aa07341b77cc7574adc9 100644 (file)
@@ -1,3 +1,14 @@
+2004-09-25  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * config/s390/s390-protos.h (s390_back_chain_rtx): Add prototype.
+       * config/s390/s390.c (s390_back_chain_rtx): New function.
+       * config/s390/s390.md ("allocate_stack"): Use s390_back_chain_rtx.
+       Call anti_adjust_stack.
+       ("restore_stack_block"): Use s390_back_chain_rtx.  Enable pattern
+       only if compiling with back chain.
+       ("save_stack_nonlocal", "restore_stack_nonlocal"): Save/restore
+       back chain only if back chain enabled.  Use s390_back_chain_rtx.
+       
 2004-09-25  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        * doc/trouble.texi: Remove obsolete information.  Update
index 8b5a263d98bffd67ec707f9879b0d9ce1c0ab970..359e20cd87b1afed32980ec7302a89f20fc4ecc4 100644 (file)
@@ -82,6 +82,7 @@ extern void s390_expand_clrmem (rtx, rtx);
 extern void s390_expand_cmpmem (rtx, rtx, rtx, rtx);
 extern bool s390_expand_addcc (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
 extern rtx s390_return_addr_rtx (int, rtx);
+extern rtx s390_back_chain_rtx (void);
 extern rtx s390_emit_call (rtx, rtx, rtx, rtx);
 
 extern bool s390_output_addr_const_extra (FILE*, rtx);
index 5d838ef715c256ae85768c9857d0031af1799b6a..7556b322669797f3f8bde93b8155d6c864c3d287 100644 (file)
@@ -5759,6 +5759,26 @@ s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
   return gen_rtx_MEM (Pmode, addr);
 }
 
+/* Return an RTL expression representing the back chain stored in
+   the current stack frame.  */
+
+rtx
+s390_back_chain_rtx (void)
+{
+  rtx chain;
+
+  gcc_assert (TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN);
+
+  if (TARGET_BACKCHAIN)
+    chain = stack_pointer_rtx;
+  else
+    chain = plus_constant (stack_pointer_rtx,
+                          STACK_POINTER_OFFSET - UNITS_PER_WORD);
+
+  chain = gen_rtx_MEM (Pmode, chain);
+  return chain;
+}
+
 /* Find first call clobbered register unused in a function.
    This could be used as base register in a leaf function
    or for holding the return address before epilogue.  */
index 8c65145f41924caa7176025c55c5f79d95a9e234..e5e0aabf3dcd3ccf08f2457f94ab507143ab5b10 100644 (file)
 ;
 
 (define_expand "allocate_stack"
-  [(set (reg 15)
-        (plus (reg 15) (match_operand 1 "general_operand" "")))
-   (set (match_operand 0 "general_operand" "")
-        (reg 15))]
+  [(match_operand 0 "general_operand" "")
+   (match_operand 1 "general_operand" "")]
  "TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN"
 {
-    rtx stack = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
-    rtx chain;
-    rtx temp;
-
-    if (TARGET_KERNEL_BACKCHAIN)
-      chain = plus_constant (stack, STACK_POINTER_OFFSET - UNITS_PER_WORD);
-    else
-      chain = stack;
-
-    chain = gen_rtx_MEM (Pmode, chain);
-    temp = gen_reg_rtx (Pmode);
-
-    emit_move_insn (temp, chain);
-
-    if (TARGET_64BIT)
-      emit_insn (gen_adddi3 (stack, stack, negate_rtx (Pmode, operands[1])));
-    else
-      emit_insn (gen_addsi3 (stack, stack, negate_rtx (Pmode, operands[1])));
+  rtx temp = gen_reg_rtx (Pmode);
 
-    emit_move_insn (chain, temp);
+  emit_move_insn (temp, s390_back_chain_rtx ());
+  anti_adjust_stack (operands[1]);
+  emit_move_insn (s390_back_chain_rtx (), temp);
 
-    emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
-    DONE;
+  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
+  DONE;
 })
 
 
   "DONE;")
 
 (define_expand "restore_stack_block"
-  [(use (match_operand 0 "register_operand" ""))
-   (set (match_dup 2) (match_dup 3))
-   (set (match_dup 0) (match_operand 1 "register_operand" ""))
-   (set (match_dup 3) (match_dup 2))]
-  ""
+  [(match_operand 0 "register_operand" "")
+   (match_operand 1 "register_operand" "")]
+  "TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN"
 {
-  operands[2] = gen_reg_rtx (Pmode);
-  operands[3] = gen_rtx_MEM (Pmode, operands[0]);
+  rtx temp = gen_reg_rtx (Pmode);
+
+  emit_move_insn (temp, s390_back_chain_rtx ());
+  emit_move_insn (operands[0], operands[1]);
+  emit_move_insn (s390_back_chain_rtx (), temp);
+
+  DONE;
 })
 
 (define_expand "save_stack_nonlocal"
    (match_operand 1 "register_operand" "")]
   ""
 {
-  rtx temp = gen_reg_rtx (Pmode);
+  enum machine_mode mode = TARGET_64BIT ? OImode : TImode;
+  rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
+
+  /* Copy the backchain to the first word, sp to the second and the
+     literal pool base to the third.  */
+
+  if (TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN)
+    {
+      rtx temp = force_reg (Pmode, s390_back_chain_rtx ());
+      emit_move_insn (operand_subword (operands[0], 0, 0, mode), temp);
+    }
+
+  emit_move_insn (operand_subword (operands[0], 1, 0, mode), operands[1]);
+  emit_move_insn (operand_subword (operands[0], 2, 0, mode), base);
 
-  /* Copy the backchain to the first word, sp to the second and the literal pool
-     base to the third.  */
-  emit_move_insn (operand_subword (operands[0], 2, 0,
-                  TARGET_64BIT ? OImode : TImode),
-                  gen_rtx_REG (Pmode, BASE_REGNUM));
-  emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
-  emit_move_insn (operand_subword (operands[0], 0, 0,
-                 TARGET_64BIT ? OImode : TImode),
-                 temp);
-  emit_move_insn (operand_subword (operands[0], 1, 0,
-                 TARGET_64BIT ? OImode : TImode),
-                 operands[1]);
   DONE;
 })
 
    (match_operand 1 "memory_operand" "")]
   ""
 {
-  rtx temp = gen_reg_rtx (Pmode);
+  enum machine_mode mode = TARGET_64BIT ? OImode : TImode;
   rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
+  rtx temp = NULL_RTX;
 
   /* Restore the backchain from the first word, sp from the second and the
      literal pool base from the third.  */
-  emit_move_insn (temp,
-                 operand_subword (operands[1], 0, 0,
-                 TARGET_64BIT ? OImode : TImode));
-  emit_move_insn (operands[0],
-                 operand_subword (operands[1], 1, 0,
-                 TARGET_64BIT ? OImode : TImode));
-  emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
-  emit_move_insn (base,
-                  operand_subword (operands[1], 2, 0,
-                  TARGET_64BIT ? OImode : TImode));
-  emit_insn (gen_rtx_USE (VOIDmode, base));
 
+  if (TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN)
+    temp = force_reg (Pmode, operand_subword (operands[1], 0, 0, mode));
+    
+  emit_move_insn (base, operand_subword (operands[1], 2, 0, mode));
+  emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, mode));
+
+  if (temp)
+    emit_move_insn (s390_back_chain_rtx (), temp);
+
+  emit_insn (gen_rtx_USE (VOIDmode, base));
   DONE;
 })