]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR target/44199
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 26 May 2010 06:00:44 +0000 (06:00 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 26 May 2010 06:00:44 +0000 (06:00 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159853 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md

index ed93893cea4d223e47bd3388d4f1694e944c8512..abcdeae510f0a1fe56f507ee1a25a50903f906b6 100644 (file)
@@ -1,3 +1,11 @@
+2010-05-26  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.
+
 2010-05-25  Eric Botcazou  <ebotcazou@adacore.com>
 
        * function.h (struct function): Add can_throw_non_call_exceptions bit.
index 35be57bac9e482ba8284aca23696466c55ad8a5b..eb8af6fea845f41d247854bccfcd322c167a3592 100644 (file)
@@ -19796,6 +19796,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)));
@@ -19805,6 +19815,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;
index 73eca193340544efb0a82b95862be2f06feb5d8e..34d619c38e74094ac93364c300fb6d1ea3330054 100644 (file)
   ""
   [(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))]