[SPARC] Errata workaround for GRLIB-TN-0011
authorDaniel Cederman <cederman@gaisler.com>
Wed, 29 Nov 2017 15:20:48 +0000 (15:20 +0000)
committerDaniel Hellstrom <danielh@gcc.gnu.org>
Wed, 29 Nov 2017 15:20:48 +0000 (16:20 +0100)
This patch provides a workaround for the errata described in GRLIB-TN-0011.

If the workaround is enabled it will:

 * Insert .align 16 before atomic instructions (swap, ldstub, casa).

It is applicable to GR712RC.

2017-11-29  Daniel Cederman  <cederman@gaisler.com>

gcc/
* config/sparc/sync.md (swapsi): 16-byte align if sparc_fix_gr712rc.
(atomic_compare_and_swap_leon3_1): Likewise.
(ldstub): Likewise.

From-SVN: r255235

gcc/ChangeLog
gcc/config/sparc/sync.md

index 390a0b79b1e1098696cc2305737b05033cca333f..02cb730e3cf836a63d679803e2c9a98c3f3d03e3 100644 (file)
@@ -1,3 +1,9 @@
+2017-11-29  Daniel Cederman  <cederman@gaisler.com>
+
+       * config/sparc/sync.md (swapsi): 16-byte align if sparc_fix_gr712rc.
+       (atomic_compare_and_swap_leon3_1): Likewise.
+       (ldstub): Likewise.
+
 2017-11-29  Daniel Cederman  <cederman@gaisler.com>
 
        * config/sparc/sparc.c (fpop_insn_p): New function.
index 1593bdeb903f901331e01c200cf92610bee24e55..ead7c777caba449e30f3cf8e2e112a4ea572fbde 100644 (file)
          UNSPECV_CAS))]
   "TARGET_LEON3"
 {
+  if (sparc_fix_gr712rc)
+    output_asm_insn (".align\t16", operands);
   if (TARGET_SV_MODE)
     return "casa\t%1 0xb, %2, %0"; /* ASI for supervisor data space.  */
   else
     return "casa\t%1 0xa, %2, %0"; /* ASI for user data space.  */
 }
-  [(set_attr "type" "multi")])
+  [(set_attr "type" "multi")
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+                     (const_int 4) (const_int 1)))])
 
 (define_insn "*atomic_compare_and_swapdi_v8plus"
   [(set (match_operand:DI 0 "register_operand" "=h")
    (set (match_dup 1)
        (match_operand:SI 2 "register_operand" "0"))]
   "(TARGET_V8 || TARGET_V9) && !sparc_fix_ut699"
-  "swap\t%1, %0"
-  [(set_attr "type" "multi")])
+{
+  if (sparc_fix_gr712rc)
+    return ".align\t16\n\tswap\t%1, %0";
+  else
+    return "swap\t%1, %0";
+}
+  [(set_attr "type" "multi")
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+                     (const_int 4) (const_int 1)))])
 
 (define_expand "atomic_test_and_set"
   [(match_operand:QI 0 "register_operand" "")
                            UNSPECV_LDSTUB))
    (set (match_dup 1) (const_int -1))]
   "!sparc_fix_ut699"
-  "ldstub\t%1, %0"
-  [(set_attr "type" "multi")])
+{
+  if (sparc_fix_gr712rc)
+    return ".align\t16\n\tldstub\t%1, %0";
+  else
+    return "ldstub\t%1, %0";
+}
+  [(set_attr "type" "multi")
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+                     (const_int 4) (const_int 1)))])