diff options
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/s390/s390-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 20 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 101 |
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; }) |