sparc.opt (mfix-ut700): New option.
authorDaniel Cederman <cederman@gaisler.com>
Tue, 11 Jul 2017 07:18:50 +0000 (07:18 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 11 Jul 2017 07:18:50 +0000 (07:18 +0000)
* config/sparc/sparc.opt (mfix-ut700): New option.
(mfix-gr712rc): Likewise.
(sparc_fix_b2bst): New variable.
* doc/invoke.texi (SPARC options): Document them.
(ARM options): Fix warnings.
* config/sparc/sparc.c (sparc_do_work_around_errata): Insert NOP
instructions to prevent sequences that can trigger the store-store
errata for certain LEON3FT processors.
(pass_work_around_errata::gate): Also test sparc_fix_b2bst.
(sparc_option_override): Set sparc_fix_b2bst appropriately.
* config/sparc/sparc.md (fix_b2bst): New attribute.
(in_branch_delay): Prevent stores in delay slot if fix_b2bst.

From-SVN: r250114

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md
gcc/config/sparc/sparc.opt
gcc/doc/invoke.texi

index 908e8cad3e81f9fd31c63a9be45945d0d288ae54..185ae3313eba5d02b54117725a1e565b0ac48518 100644 (file)
@@ -1,3 +1,18 @@
+2017-07-11  Daniel Cederman  <cederman@gaisler.com>
+
+       * config/sparc/sparc.opt (mfix-ut700): New option.
+       (mfix-gr712rc): Likewise.
+       (sparc_fix_b2bst): New variable.
+       * doc/invoke.texi (SPARC options): Document them.
+       (ARM options): Fix warnings.
+       * config/sparc/sparc.c (sparc_do_work_around_errata): Insert NOP
+       instructions to prevent sequences that can trigger the store-store
+       errata for certain LEON3FT processors.
+       (pass_work_around_errata::gate): Also test sparc_fix_b2bst.
+       (sparc_option_override): Set sparc_fix_b2bst appropriately.
+       * config/sparc/sparc.md (fix_b2bst): New attribute.
+       (in_branch_delay): Prevent stores in delay slot if fix_b2bst.
+
 2017-07-10  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/81375
index 9f9a29ac4d2f5fc6676455956655bbab346970db..dae241111874becbcfe196a566e5383a8400ed58 100644 (file)
@@ -920,6 +920,12 @@ mem_ref (rtx x)
    to properly detect the various hazards.  Therefore, this machine specific
    pass runs as late as possible.  */
 
+/* True if INSN is a md pattern or asm statement.  */
+#define USEFUL_INSN_P(INSN)                                            \
+  (NONDEBUG_INSN_P (INSN)                                              \
+   && GET_CODE (PATTERN (INSN)) != USE                                 \
+   && GET_CODE (PATTERN (INSN)) != CLOBBER)
+
 static unsigned int
 sparc_do_work_around_errata (void)
 {
@@ -939,6 +945,81 @@ sparc_do_work_around_errata (void)
        if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
          insn = seq->insn (1);
 
+      /* Look for either of these two sequences:
+
+        Sequence A:
+        1. store of word size or less (e.g. st / stb / sth / stf)
+        2. any single instruction that is not a load or store
+        3. any store instruction (e.g. st / stb / sth / stf / std / stdf)
+
+        Sequence B:
+        1. store of double word size (e.g. std / stdf)
+        2. any store instruction (e.g. st / stb / sth / stf / std / stdf)  */
+      if (sparc_fix_b2bst
+         && NONJUMP_INSN_P (insn)
+         && (set = single_set (insn)) != NULL_RTX
+         && MEM_P (SET_DEST (set)))
+       {
+         /* Sequence B begins with a double-word store.  */
+         bool seq_b = GET_MODE_SIZE (GET_MODE (SET_DEST (set))) == 8;
+         rtx_insn *after;
+         int i;
+
+         next = next_active_insn (insn);
+         if (!next)
+           break;
+
+         for (after = next, i = 0; i < 2; i++)
+           {
+             /* Skip empty assembly statements.  */
+             if ((GET_CODE (PATTERN (after)) == UNSPEC_VOLATILE)
+                 || (USEFUL_INSN_P (after)
+                     && (asm_noperands (PATTERN (after))>=0)
+                     && !strcmp (decode_asm_operands (PATTERN (after),
+                                                      NULL, NULL, NULL,
+                                                      NULL, NULL), "")))
+               after = next_active_insn (after);
+             if (!after)
+               break;
+
+             /* If the insn is a branch, then it cannot be problematic.  */
+             if (!NONJUMP_INSN_P (after)
+                 || GET_CODE (PATTERN (after)) == SEQUENCE)
+               break;
+
+             /* Sequence B is only two instructions long.  */
+             if (seq_b)
+               {
+                 /* Add NOP if followed by a store.  */
+                 if ((set = single_set (after)) != NULL_RTX
+                     && MEM_P (SET_DEST (set)))
+                   insert_nop = true;
+
+                 /* Otherwise it is ok.  */
+                 break;
+               }
+
+             /* If the second instruction is a load or a store,
+                then the sequence cannot be problematic.  */
+             if (i == 0)
+               {
+                 if (((set = single_set (after)) != NULL_RTX)
+                     && (MEM_P (SET_DEST (set)) || MEM_P (SET_SRC (set))))
+                   break;
+
+                 after = next_active_insn (after);
+                 if (!after)
+                   break;
+               }
+
+             /* Add NOP if third instruction is a store.  */
+             if (i == 1
+                 && ((set = single_set (after)) != NULL_RTX)
+                 && MEM_P (SET_DEST (set)))
+               insert_nop = true;
+           }
+       }
+      else
       /* Look for a single-word load into an odd-numbered FP register.  */
       if (sparc_fix_at697f
          && NONJUMP_INSN_P (insn)
@@ -1191,8 +1272,7 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
     {
-      /* The only errata we handle are those of the AT697F and UT699.  */
-      return sparc_fix_at697f != 0 || sparc_fix_ut699 != 0;
+      return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst;
     }
 
   virtual unsigned int execute (function *)
@@ -1557,6 +1637,10 @@ sparc_option_override (void)
   if (!(target_flags_explicit & MASK_LRA))
     target_flags |= MASK_LRA;
 
+  /* Enable the back-to-back store errata workaround for LEON3FT.  */
+  if (sparc_fix_ut699 || sparc_fix_ut700 || sparc_fix_gr712rc)
+    sparc_fix_b2bst = 1;
+
   /* Supply a default value for align_functions.  */
   if (align_functions == 0)
     {
index cac1bd9343f5ba2ef52ee90cb2ff1fba12be47aa..afdc7d12700b1276a5cc265a582df7c0a0aeaf54 100644 (file)
    (symbol_ref "(sparc_fix_ut699 != 0
                 ? FIX_UT699_TRUE : FIX_UT699_FALSE)"))
 
+(define_attr "fix_b2bst" "false,true"
+   (symbol_ref "(sparc_fix_b2bst != 0
+                ? FIX_B2BST_TRUE : FIX_B2BST_FALSE)"))
+
 ;; Length (in # of insns).
 ;; Beware that setting a length greater or equal to 3 for conditional branches
 ;; has a side-effect (see output_cbranch and output_v9branch).
 (define_attr "in_branch_delay" "false,true"
   (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
           (const_string "false")
+        (and (eq_attr "fix_b2bst" "true") (eq_attr "type" "store,fpstore"))
+          (const_string "false")
         (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
           (const_string "false")
         (and (eq_attr "fix_ut699" "true")
index cc51bd4b584fe18e166173d194ab58531642184d..ae63d2018e3a8ee0948470a009ababbf529d4860 100644 (file)
@@ -237,6 +237,18 @@ mfix-ut699
 Target Report RejectNegative Var(sparc_fix_ut699)
 Enable workarounds for the errata of the UT699 processor.
 
+mfix-ut700
+Target Report RejectNegative Var(sparc_fix_ut700)
+Enable workarounds for the errata of the UT699E/UT700 processor.
+
+mfix-gr712rc
+Target Report RejectNegative Var(sparc_fix_gr712rc)
+Enable workarounds for the errata of the GR712RC processor.
+
+;; Enable workaround for back-to-back store errata
+TargetVariable
+unsigned int sparc_fix_b2bst
+
 Mask(LONG_DOUBLE_128)
 ;; Use 128-bit long double
 
index 4982f7c5d2d95720276560187df14320c7d62325..f93c825f15dcaeba051cc8763f0386672a0fc0f6 100644 (file)
@@ -1128,8 +1128,8 @@ See RS/6000 and PowerPC Options.
 -mvis2  -mno-vis2  -mvis3  -mno-vis3 @gol
 -mvis4 -mno-vis4 -mvis4b -mno-vis4b @gol
 -mcbcond  -mno-cbcond  -mfmaf  -mno-fmaf  @gol
--mpopc  -mno-popc  -msubxc  -mno-subxc@gol
--mfix-at697f  -mfix-ut699 @gol
+-mpopc  -mno-popc  -msubxc  -mno-subxc @gol
+-mfix-at697f  -mfix-ut699  -mfix-ut700  -mfix-gr712rc @gol
 -mlra  -mno-lra}
 
 @emph{SPU Options}
@@ -15205,7 +15205,7 @@ default is dependent on the selected target architecture.  For ARMv6
 and later architectures the default is BE8, for older architectures
 the default is BE32.  BE32 format has been deprecated by ARM.
 
-@item -march=@var{name@r{[}+extension@dots{}@r{]}}
+@item -march=@var{name}@r{[}+extension@dots{}@r{]}
 @opindex march
 This specifies the name of the target ARM architecture.  GCC uses this
 name to determine what kind of instructions it can emit when generating
@@ -15579,7 +15579,7 @@ of the build computer.  At present, this feature is only supported on
 GNU/Linux, and not all architectures are recognized.  If the auto-detect is
 unsuccessful the option has no effect.
 
-@item -mcpu=@var{name@r{[}+extension@dots{}@r{]}}
+@item -mcpu=@var{name}@r{[}+extension@dots{}@r{]}
 @opindex mcpu
 This specifies the name of the target ARM processor.  GCC uses this name
 to derive the name of the target ARM architecture (as if specified
@@ -24102,6 +24102,16 @@ processor (which corresponds to erratum #13 of the AT697E processor).
 @opindex mfix-ut699
 Enable the documented workarounds for the floating-point errata and the data
 cache nullify errata of the UT699 processor.
+
+@item -mfix-ut700
+@opindex mfix-ut700
+Enable the documented workaround for the back-to-back store errata of
+the UT699E/UT700 processor.
+
+@item -mfix-gr712rc
+@opindex mfix-gr712rc
+Enable the documented workaround for the back-to-back store errata of
+the GR712RC processor.
 @end table
 
 These @samp{-m} options are supported in addition to the above