This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
S/390: Respect backchain mode in stack save/restore patterns
- From: Ulrich Weigand <weigand at i1 dot informatik dot uni-erlangen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 25 Sep 2004 02:18:36 +0200 (CEST)
- Subject: 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