sparc.opt (mfix-ut700): New option.

* 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
This commit is contained in:
Daniel Cederman 2017-07-11 07:18:50 +00:00 committed by Eric Botcazou
parent 214f700a8b
commit 67091cb476
5 changed files with 133 additions and 6 deletions

View 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

View 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)
{

View file

@ -426,6 +426,10 @@
(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).
@ -573,6 +577,8 @@
(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")

View 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

View 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