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:
parent
214f700a8b
commit
67091cb476
5 changed files with 133 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue