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 | 37 +++++++++++++++++++++++++++++--------
 1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index d5a0ff7d4ea..fa78e0dc739 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1045,6 +1045,31 @@ 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;
+
+   return (get_attr_type (insn) == TYPE_STORE)
+     || (get_attr_type (insn) == TYPE_FPSTORE);
+}
+
+/* True if INSN is a load instruction.  */
+
+static bool
+load_insn_p (rtx_insn *insn)
+{
+   if (GET_CODE (PATTERN (insn)) != SET)
+    return false;
+
+   return (get_attr_type (insn) == TYPE_LOAD)
+     || (get_attr_type (insn) == TYPE_SLOAD)
+     || (get_attr_type (insn) == TYPE_FPLOAD);
+}
+
 /* 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 +1130,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 +1235,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 +1268,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 +1290,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;
            }
        }
-- 
2.25.1

Reply via email to