[ARC] Prevent moving stores to the frame before the stack adjustment.
authorClaudiu Zissulescu <claziss@synopsys.com>
Thu, 1 Jun 2017 09:42:49 +0000 (11:42 +0200)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Thu, 1 Jun 2017 09:42:49 +0000 (11:42 +0200)
If the stack pointer is needed, emit a special barrier that will prevent
the scheduler from moving stores to the frame before the stack adjustment.

For example:

[snip]
mov_s fp,sp  ; frame pointer is set here
[snip]
st r1,[fp,-24] ; frame pointer is used here
[snip]
sub_s sp,sp,0x20 ; stack pointer adjusted

So we can easily see that any interrupt between the `st` and `sub`
instruction will lead to faulty code as the interrupt routine will use
a faulty sp register, and, potentially, overwriting the value stored
by 'st' instruction. Thus, adding a scheduler barrier will force the
compiler to emit the `sub` instruction before the store one.

2017-06-01  Claudiu Zissulescu  <claziss@synopsys.com>

* config/arc/arc.c (arc_expand_prologue): Emit a special barrier
to prevent store reordering.
* config/arc/arc.md (UNSPEC_ARC_STKTIE): Define.
(type): Add block type.
(stack_tie): Define special instruction to be used in
expand_prologue.

From-SVN: r248781

gcc/ChangeLog
gcc/config/arc/arc.c
gcc/config/arc/arc.md

index 867947a88dd7d5ae328e257d2dd7d58f775e4923..92a7c0ab6bca7dd8eb6054f1aff8f99ce30f8568 100644 (file)
@@ -1,3 +1,12 @@
+2017-06-01  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * config/arc/arc.c (arc_expand_prologue): Emit a special barrier
+       to prevent store reordering.
+       * config/arc/arc.md (UNSPEC_ARC_STKTIE): Define.
+       (type): Add block type.
+       (stack_tie): Define special instruction to be used in
+       expand_prologue.
+
 2017-06-01  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * config/arc/arc.md (commutative_binary_comparison): Remove 'I'
index a45e12bc7d3921101105a188172760a39d4e4083..caf01c8b6e135210c0375a51f13b4fdc65f6c833 100644 (file)
@@ -2968,7 +2968,15 @@ arc_expand_prologue (void)
   frame_size_to_allocate -= first_offset;
   /* Allocate the stack frame.  */
   if (frame_size_to_allocate > 0)
-    frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
+    {
+      frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
+      /* If the frame pointer is needed, emit a special barrier that
+        will prevent the scheduler from moving stores to the frame
+        before the stack adjustment.  */
+      if (arc_frame_pointer_needed ())
+       emit_insn (gen_stack_tie (stack_pointer_rtx,
+                                 hard_frame_pointer_rtx));
+    }
 
   /* Setup the gp register, if needed.  */
   if (crtl->uses_pic_offset_table)
index b53ec02f6625df90b23bd45ef5b79f0a8c50d5c5..501413854dde7e3c7575df0360c07488c15781fa 100644 (file)
   UNSPEC_ARC_VMAC2HU
   UNSPEC_ARC_VMPY2H
   UNSPEC_ARC_VMPY2HU
+  UNSPEC_ARC_STKTIE
   ])
 
 (define_c_enum "vunspec" [
    simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
    simd_valign, simd_valign_with_acc, simd_vcontrol,
    simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem,
-   fpu"
+   fpu, block"
   (cond [(eq_attr "is_sfunc" "yes")
         (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
                (match_test "flag_pic") (const_string "sfunc")]
   (set_attr "predicable" "yes,no,no,yes,no")
   (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
 
+(define_insn "stack_tie"
+  [(set (mem:BLK (scratch))
+       (unspec:BLK [(match_operand:SI 0 "register_operand" "rb")
+                    (match_operand:SI 1 "register_operand" "rb")]
+                   UNSPEC_ARC_STKTIE))]
+  ""
+  ""
+  [(set_attr "length" "0")
+   (set_attr "iscompact" "false")
+   (set_attr "type" "block")]
+  )
+
 ;; include the arc-FPX instructions
 (include "fpx.md")