OSDN Git Service

* config/sparc/sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant.
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Dec 2011 23:37:48 +0000 (23:37 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Dec 2011 23:37:48 +0000 (23:37 +0000)
(frame_blockage): New expander.
(frame_blockage<P:mode>): New instruction.
* config/sparc/sparc.c (sparc_expand_prologue): When the sequence of
instructions establishing the frame isn't atomic, emit frame blockage.

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

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md

index 5849861..1c8b3a2 100644 (file)
@@ -1,3 +1,11 @@
+2011-12-16  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * config/sparc/sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant.
+       (frame_blockage): New expander.
+       (frame_blockage<P:mode>): New instruction.
+       * config/sparc/sparc.c (sparc_expand_prologue): When the sequence of
+       instructions establishing the frame isn't atomic, emit frame blockage.
+
 2011-12-16  Tristan Gingold  <gingold@adacore.com>
 
        * config/alpha/vms.h (USE_TM_CLONE_REGISTRY): Define.
 2011-12-16  Tristan Gingold  <gingold@adacore.com>
 
        * config/alpha/vms.h (USE_TM_CLONE_REGISTRY): Define.
index 20efb00..19ab54a 100644 (file)
@@ -4972,8 +4972,9 @@ sparc_expand_prologue (void)
       else if (size <= 8192)
        {
          insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-4096)));
       else if (size <= 8192)
        {
          insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-4096)));
-         /* %sp is still the CFA register.  */
          RTX_FRAME_RELATED_P (insn) = 1;
          RTX_FRAME_RELATED_P (insn) = 1;
+
+         /* %sp is still the CFA register.  */
          insn = emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
        }
       else
          insn = emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
        }
       else
@@ -4996,8 +4997,18 @@ sparc_expand_prologue (void)
       else if (size <= 8192)
        {
          emit_window_save (GEN_INT (-4096));
       else if (size <= 8192)
        {
          emit_window_save (GEN_INT (-4096));
+
          /* %sp is not the CFA register anymore.  */
          emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
          /* %sp is not the CFA register anymore.  */
          emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
+
+         /* Make sure no %fp-based store is issued until after the frame is
+            established.  The offset between the frame pointer and the stack
+            pointer is calculated relative to the value of the stack pointer
+            at the end of the function prologue, and moving instructions that
+            access the stack via the frame pointer between the instructions
+            that decrement the stack pointer could result in accessing the
+            register window save area, which is volatile.  */
+         emit_insn (gen_frame_blockage ());
        }
       else
        {
        }
       else
        {
index 37ac170..f67ee83 100644 (file)
@@ -28,6 +28,7 @@
   [(UNSPEC_MOVE_PIC            0)
    (UNSPEC_UPDATE_RETURN       1)
    (UNSPEC_LOAD_PCREL_SYM      2)
   [(UNSPEC_MOVE_PIC            0)
    (UNSPEC_UPDATE_RETURN       1)
    (UNSPEC_LOAD_PCREL_SYM      2)
+   (UNSPEC_FRAME_BLOCKAGE      3)
    (UNSPEC_MOVE_PIC_LABEL      5)
    (UNSPEC_SETH44              6)
    (UNSPEC_SETM44              7)
    (UNSPEC_MOVE_PIC_LABEL      5)
    (UNSPEC_SETH44              6)
    (UNSPEC_SETM44              7)
   ""
   [(set_attr "length" "0")])
 
   ""
   [(set_attr "length" "0")])
 
+;; Do not schedule instructions accessing memory before this point.
+
+(define_expand "frame_blockage"
+  [(set (match_dup 0)
+       (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
+  ""
+{
+  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+  MEM_VOLATILE_P (operands[0]) = 1;
+  operands[1] = stack_pointer_rtx;
+})
+
+(define_insn "*frame_blockage<P:mode>"
+  [(set (match_operand:BLK 0 "" "")
+       (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
+  ""
+  ""
+  [(set_attr "length" "0")])
+
 (define_expand "probe_stack"
   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
   ""
 (define_expand "probe_stack"
   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
   ""