aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/rs6000/rs6000.md51
2 files changed, 38 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e26c7d..0b7c8bd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2005-09-13 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/23774
+ * config/rs6000/rs6000.md (restore_stack_block): Write the backchain
+ word before changing the stack pointer. Use gen_frame_mem for MEMs.
+ Use UNSPEC_TIE to prevent insn scheduling reordering the insns.
+ (restore_stack_nonlocal): Likewise.
+ (save_stack_nonlocal): Use template to emit insns, and gen_frame_mem.
+
2005-09-12 Ian Lance Taylor <ian@airs.com>
PR g++/7874
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 46381dc..6171cad 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -9347,51 +9347,58 @@
""
"DONE;")
+;; Adjust stack pointer (op0) to a new value (op1).
+;; First copy old stack backchain to new location, and ensure that the
+;; scheduler won't reorder the sp assignment before the backchain write.
(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))]
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 4) (match_dup 2))
+ (set (match_dup 5) (unspec:BLK [(match_dup 5)] UNSPEC_TIE))
+ (set (match_operand 0 "register_operand" "")
+ (match_operand 1 "register_operand" ""))]
""
"
{
operands[2] = gen_reg_rtx (Pmode);
- operands[3] = gen_rtx_MEM (Pmode, operands[0]);
+ operands[3] = gen_frame_mem (Pmode, operands[0]);
+ operands[4] = gen_frame_mem (Pmode, operands[1]);
+ operands[5] = gen_frame_mem (BLKmode, operands[0]);
}")
(define_expand "save_stack_nonlocal"
- [(match_operand 0 "memory_operand" "")
- (match_operand 1 "register_operand" "")]
+ [(set (match_dup 3) (match_dup 4))
+ (set (match_operand 0 "memory_operand" "") (match_dup 3))
+ (set (match_dup 2) (match_operand 1 "register_operand" ""))]
""
"
{
- rtx temp = gen_reg_rtx (Pmode);
int units_per_word = (TARGET_32BIT) ? 4 : 8;
/* Copy the backchain to the first word, sp to the second. */
- emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
- emit_move_insn (adjust_address_nv (operands[0], Pmode, 0), temp);
- emit_move_insn (adjust_address_nv (operands[0], Pmode, units_per_word),
- operands[1]);
- DONE;
+ operands[0] = adjust_address_nv (operands[0], Pmode, 0);
+ operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
+ operands[3] = gen_reg_rtx (Pmode);
+ operands[4] = gen_frame_mem (Pmode, operands[1]);
}")
(define_expand "restore_stack_nonlocal"
- [(match_operand 0 "register_operand" "")
- (match_operand 1 "memory_operand" "")]
+ [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
+ (set (match_dup 3) (match_dup 4))
+ (set (match_dup 5) (match_dup 2))
+ (set (match_dup 6) (unspec:BLK [(match_dup 6)] UNSPEC_TIE))
+ (set (match_operand 0 "register_operand" "") (match_dup 3))]
""
"
{
- rtx temp = gen_reg_rtx (Pmode);
int units_per_word = (TARGET_32BIT) ? 4 : 8;
/* Restore the backchain from the first word, sp from the second. */
- emit_move_insn (temp,
- adjust_address_nv (operands[1], Pmode, 0));
- emit_move_insn (operands[0],
- adjust_address_nv (operands[1], Pmode, units_per_word));
- emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
- DONE;
+ operands[2] = gen_reg_rtx (Pmode);
+ operands[3] = gen_reg_rtx (Pmode);
+ operands[1] = adjust_address_nv (operands[1], Pmode, 0);
+ operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
+ operands[5] = gen_frame_mem (Pmode, operands[3]);
+ operands[6] = gen_frame_mem (BLKmode, operands[0]);
}")
;; TOC register handling.