This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

S/390: Respect backchain mode in stack save/restore patterns


Hello,

this fixes some fall-out from the packed-stack patch: it is now
crucial that the stack save/restore patterns take the -mbackchain/
-mkernel-backchain/-mno-backchain setting into accout, or else they
might fail to restore the correct back chain, or even worse, clobber
a stack location used for some other purpose.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux,
applied to mainline.

Bye,
Ulrich


ChangeLog:

	* 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.
	

Index: gcc/config/s390/s390-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390-protos.h,v
retrieving revision 1.57
diff -c -p -r1.57 s390-protos.h
*** gcc/config/s390/s390-protos.h	22 Sep 2004 13:57:34 -0000	1.57
--- gcc/config/s390/s390-protos.h	24 Sep 2004 20:29:02 -0000
*************** extern void s390_expand_clrmem (rtx, rtx
*** 82,87 ****
--- 82,88 ----
  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: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.178
diff -c -p -r1.178 s390.c
*** gcc/config/s390/s390.c	22 Sep 2004 13:57:34 -0000	1.178
--- gcc/config/s390/s390.c	24 Sep 2004 20:29:03 -0000
*************** s390_return_addr_rtx (int count, rtx fra
*** 5759,5764 ****
--- 5759,5784 ----
    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: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.125
diff -c -p -r1.125 s390.md
*** gcc/config/s390/s390.md	22 Sep 2004 13:57:38 -0000	1.125
--- gcc/config/s390/s390.md	24 Sep 2004 20:29:04 -0000
***************
*** 7207,7241 ****
  ;
  
  (define_expand "allocate_stack"
!   [(set (reg 15)
!         (plus (reg 15) (match_operand 1 "general_operand" "")))
!    (set (match_operand 0 "general_operand" "")
!         (reg 15))]
   "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])));
  
!     emit_move_insn (chain, temp);
  
!     emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
!     DONE;
  })
  
  
--- 7207,7224 ----
  ;
  
  (define_expand "allocate_stack"
!   [(match_operand 0 "general_operand" "")
!    (match_operand 1 "general_operand" "")]
   "TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN"
  {
!   rtx temp = gen_reg_rtx (Pmode);
  
!   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;
  })
  
  
***************
*** 7274,7287 ****
    "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))]
!   ""
  {
!   operands[2] = gen_reg_rtx (Pmode);
!   operands[3] = gen_rtx_MEM (Pmode, operands[0]);
  })
  
  (define_expand "save_stack_nonlocal"
--- 7257,7273 ----
    "DONE;")
  
  (define_expand "restore_stack_block"
!   [(match_operand 0 "register_operand" "")
!    (match_operand 1 "register_operand" "")]
!   "TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN"
  {
!   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"
***************
*** 7289,7308 ****
     (match_operand 1 "register_operand" "")]
    ""
  {
!   rtx temp = gen_reg_rtx (Pmode);
  
-   /* 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;
  })
  
--- 7275,7295 ----
     (match_operand 1 "register_operand" "")]
    ""
  {
!   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);
  
    DONE;
  })
  
***************
*** 7311,7333 ****
     (match_operand 1 "memory_operand" "")]
    ""
  {
!   rtx temp = gen_reg_rtx (Pmode);
    rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
  
    /* 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));
  
    DONE;
  })
  
--- 7298,7320 ----
     (match_operand 1 "memory_operand" "")]
    ""
  {
!   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.  */
  
+   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;
  })
  
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]