aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/s390/s390-protos.h1
-rw-r--r--gcc/config/s390/s390.c20
-rw-r--r--gcc/config/s390/s390.md101
4 files changed, 76 insertions, 57 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f967b7b..ab76350 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 8b5a263..359e20c 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -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);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 5d838ef..7556b32 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -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. */
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 8c65145..e5e0aab 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -7207,35 +7207,18 @@
;
(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;
})
@@ -7274,14 +7257,17 @@
"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"
@@ -7289,20 +7275,21 @@
(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;
})
@@ -7311,23 +7298,23 @@
(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;
})