* 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
+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
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)
{
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)
/* 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 *)
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)
{
(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")
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
-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}
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
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
@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