]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
sparc: Treat more instructions as load or store in errata workarounds
authorDaniel Cederman <cederman@gaisler.com>
Fri, 25 Sep 2020 11:17:46 +0000 (13:17 +0200)
committerDaniel Hellstrom <daniel@gaisler.com>
Thu, 16 Sep 2021 11:05:47 +0000 (13:05 +0200)
Check the attribute of instruction to determine if it performs a store
or load operation. This more generic approach sees the last instruction
in the GOTdata_op model as a potential load and treats the memory barrier
as a potential store instruction.

gcc/ChangeLog:

* config/sparc/sparc.c (store_insn_p): Add predicate for store
attributes.
(load_insn_p): Add predicate for load attributes.
(sparc_do_work_around_errata): Use new predicates.

gcc/config/sparc/sparc.c

index d5a0ff7d4ea07087fc32c9a081c262f19c72844d..49cee356a836c1723937719cba87bd0571c2c0ed 100644 (file)
@@ -1045,6 +1045,43 @@ atomic_insn_for_leon3_p (rtx_insn *insn)
     }
 }
 
+/* True if INSN is a store instruction.  */
+
+static bool
+store_insn_p (rtx_insn *insn)
+{
+  if (GET_CODE (PATTERN (insn)) != SET)
+    return false;
+
+  switch (get_attr_type (insn))
+    {
+    case TYPE_STORE:
+    case TYPE_FPSTORE:
+      return true;
+    default:
+      return false;
+    }
+}
+
+/* True if INSN is a load instruction.  */
+
+static bool
+load_insn_p (rtx_insn *insn)
+{
+  if (GET_CODE (PATTERN (insn)) != SET)
+    return false;
+
+  switch (get_attr_type (insn))
+    {
+    case TYPE_LOAD:
+    case TYPE_SLOAD:
+    case TYPE_FPLOAD:
+      return true;
+    default:
+      return false;
+    }
+}
+
 /* We use a machine specific pass to enable workarounds for errata.
 
    We need to have the (essentially) final form of the insn stream in order
@@ -1105,9 +1142,7 @@ sparc_do_work_around_errata (void)
         instruction at branch target.  */
       if (sparc_fix_ut700
          && NONJUMP_INSN_P (insn)
-         && (set = single_set (insn)) != NULL_RTX
-         && mem_ref (SET_SRC (set))
-         && REG_P (SET_DEST (set)))
+         && load_insn_p (insn))
        {
          if (jump && jump_to_label_p (jump))
            {
@@ -1212,7 +1247,7 @@ sparc_do_work_around_errata (void)
       if (sparc_fix_b2bst
          && NONJUMP_INSN_P (insn)
          && (set = single_set (insn)) != NULL_RTX
-         && MEM_P (SET_DEST (set)))
+         && store_insn_p (insn))
        {
          /* Sequence B begins with a double-word store.  */
          bool seq_b = GET_MODE_SIZE (GET_MODE (SET_DEST (set))) == 8;
@@ -1245,8 +1280,7 @@ sparc_do_work_around_errata (void)
              if (seq_b)
                {
                  /* Add NOP if followed by a store.  */
-                 if ((set = single_set (after)) != NULL_RTX
-                     && MEM_P (SET_DEST (set)))
+                 if (store_insn_p (after))
                    insert_nop = true;
 
                  /* Otherwise it is ok.  */
@@ -1268,8 +1302,7 @@ sparc_do_work_around_errata (void)
 
              /* Add NOP if third instruction is a store.  */
              if (i == 1
-                 && (set = single_set (after)) != NULL_RTX
-                 && MEM_P (SET_DEST (set)))
+                 && store_insn_p (after))
                insert_nop = true;
            }
        }