61 lines
2.2 KiB
Diff
61 lines
2.2 KiB
Diff
2010-05-20 Jakub Jelinek <jakub@redhat.com>
|
|
|
|
PR target/44199
|
|
* config/rs6000/rs6000.c (rs6000_emit_epilogue): If cfun->calls_alloca
|
|
or total_size is larger than red zone size for non-V4 ABI, emit a
|
|
stack_tie resp. frame_tie insn before stack pointer restore.
|
|
* config/rs6000/rs6000.md (frame_tie): New insn.
|
|
|
|
--- gcc/config/rs6000/rs6000.c.jj 2010-05-17 07:52:06.000000000 +0200
|
|
+++ gcc/config/rs6000/rs6000.c 2010-05-19 22:15:53.000000000 +0200
|
|
@@ -19775,6 +19775,16 @@ rs6000_emit_epilogue (int sibcall)
|
|
frame_reg_rtx = sp_reg_rtx;
|
|
if (DEFAULT_ABI == ABI_V4)
|
|
frame_reg_rtx = gen_rtx_REG (Pmode, 11);
|
|
+ /* Prevent reordering memory accesses against stack pointer restore. */
|
|
+ else if (cfun->calls_alloca
|
|
+ || offset_below_red_zone_p (-info->total_size))
|
|
+ {
|
|
+ rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
|
|
+ rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
|
|
+ MEM_NOTRAP_P (mem1) = 1;
|
|
+ MEM_NOTRAP_P (mem2) = 1;
|
|
+ emit_insn (gen_frame_tie (mem1, mem2));
|
|
+ }
|
|
|
|
insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
|
|
GEN_INT (info->total_size)));
|
|
@@ -19784,6 +19794,14 @@ rs6000_emit_epilogue (int sibcall)
|
|
&& DEFAULT_ABI != ABI_V4
|
|
&& !crtl->calls_eh_return)
|
|
{
|
|
+ /* Prevent reordering memory accesses against stack pointer restore. */
|
|
+ if (cfun->calls_alloca
|
|
+ || offset_below_red_zone_p (-info->total_size))
|
|
+ {
|
|
+ rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
|
|
+ MEM_NOTRAP_P (mem) = 1;
|
|
+ emit_insn (gen_stack_tie (mem));
|
|
+ }
|
|
insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
|
|
GEN_INT (info->total_size)));
|
|
sp_offset = 0;
|
|
--- gcc/config/rs6000/rs6000.md.jj 2010-03-26 17:13:37.000000000 +0100
|
|
+++ gcc/config/rs6000/rs6000.md 2010-05-19 22:15:19.000000000 +0200
|
|
@@ -15286,6 +15286,15 @@ (define_insn "stack_tie"
|
|
""
|
|
[(set_attr "length" "0")])
|
|
|
|
+; Like stack_tie, but depend on both fp and sp based memory.
|
|
+(define_insn "frame_tie"
|
|
+ [(set (match_operand:BLK 0 "memory_operand" "+m")
|
|
+ (unspec:BLK [(match_dup 0)
|
|
+ (match_operand:BLK 1 "memory_operand" "m")] UNSPEC_TIE))]
|
|
+ ""
|
|
+ ""
|
|
+ [(set_attr "length" "0")])
|
|
+
|
|
|
|
(define_expand "epilogue"
|
|
[(use (const_int 0))]
|