From 67091cb476bc792a2050d2ce43f878c33465ae36 Mon Sep 17 00:00:00 2001 From: Daniel Cederman Date: Tue, 11 Jul 2017 07:18:50 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 15 +++++++ gcc/config/sparc/sparc.c | 88 +++++++++++++++++++++++++++++++++++++- gcc/config/sparc/sparc.md | 6 +++ gcc/config/sparc/sparc.opt | 12 ++++++ gcc/doc/invoke.texi | 18 ++++++-- 5 files changed, 133 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 908e8cad3e8..185ae3313eb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2017-07-11 Daniel Cederman + + * 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 PR target/81375 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 9f9a29ac4d2..dae24111187 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -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 (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) { diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index cac1bd9343f..afdc7d12700 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -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") diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt index cc51bd4b584..ae63d2018e3 100644 --- a/gcc/config/sparc/sparc.opt +++ b/gcc/config/sparc/sparc.opt @@ -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 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 4982f7c5d2d..f93c825f15d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 -- 2.30.2