re PR target/23774 (dealloc of dynamic stack space breaks backchain)

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.

From-SVN: r104206
This commit is contained in:
Alan Modra 2005-09-13 02:00:53 +00:00 committed by Alan Modra
parent 7e15cfee21
commit 2eef28ec7b
2 changed files with 38 additions and 22 deletions

View File

@ -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

View File

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