public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata
@ 2017-11-27  9:57 Daniel Cederman
  2017-11-27  9:57 ` [PATCH v2 2/4] [SPARC] Errata workaround for GRLIB-TN-0011 Daniel Cederman
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Daniel Cederman @ 2017-11-27  9:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: ebotcazou, sebastian.huber, daniel

Hello Eric,

Thank you for your comments! I have updated the patches and will commit
them if you are OK with the changes.

Daniel Cederman (4):
  [SPARC] Errata workaround for GRLIB-TN-0012
  [SPARC] Errata workaround for GRLIB-TN-0011
  [SPARC] Errata workaround for GRLIB-TN-0010
  [SPARC] Errata workaround for GRLIB-TN-0013

 gcc/config/sparc/sparc.c   | 209 +++++++++++++++++++++++++++++++++++++++++++--
 gcc/config/sparc/sparc.md  |  35 ++++++++
 gcc/config/sparc/sparc.opt |   4 +
 gcc/config/sparc/sync.md   |  30 +++++--
 4 files changed, 267 insertions(+), 11 deletions(-)

-- 
2.9.3

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 2/4] [SPARC] Errata workaround for GRLIB-TN-0011
  2017-11-27  9:57 [PATCH v2 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata Daniel Cederman
@ 2017-11-27  9:57 ` Daniel Cederman
  2017-11-28 10:03   ` Eric Botcazou
  2017-11-27  9:57 ` [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010 Daniel Cederman
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: Daniel Cederman @ 2017-11-27  9:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: ebotcazou, sebastian.huber, daniel

This patch provides a workaround for the errata described in GRLIB-TN-0011.

If the workaround is enabled it will:

* Insert .align 16 before atomic instructions (swap, ldstub, casa).

It is applicable to GR712RC.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  <cederman@gaisler.com>

	* config/sparc/sync.md (swapsi): 16-byte align if sparc_fix_gr712rc.
	(atomic_compare_and_swap_leon3_1): Likewise.
	(ldstub): Likewise.
---
 gcc/config/sparc/sync.md | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index 1593bde..ead7c77 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -222,12 +222,16 @@
 	  UNSPECV_CAS))]
   "TARGET_LEON3"
 {
+  if (sparc_fix_gr712rc)
+    output_asm_insn (".align\t16", operands);
   if (TARGET_SV_MODE)
     return "casa\t%1 0xb, %2, %0"; /* ASI for supervisor data space.  */
   else
     return "casa\t%1 0xa, %2, %0"; /* ASI for user data space.  */
 }
-  [(set_attr "type" "multi")])
+  [(set_attr "type" "multi")
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+		      (const_int 4) (const_int 1)))])
 
 (define_insn "*atomic_compare_and_swapdi_v8plus"
   [(set (match_operand:DI 0 "register_operand" "=h")
@@ -275,8 +279,15 @@
    (set (match_dup 1)
 	(match_operand:SI 2 "register_operand" "0"))]
   "(TARGET_V8 || TARGET_V9) && !sparc_fix_ut699"
-  "swap\t%1, %0"
-  [(set_attr "type" "multi")])
+{
+  if (sparc_fix_gr712rc)
+    return ".align\t16\n\tswap\t%1, %0";
+  else
+    return "swap\t%1, %0";
+}
+  [(set_attr "type" "multi")
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+		      (const_int 4) (const_int 1)))])
 
 (define_expand "atomic_test_and_set"
   [(match_operand:QI 0 "register_operand" "")
@@ -307,5 +318,12 @@
 			    UNSPECV_LDSTUB))
    (set (match_dup 1) (const_int -1))]
   "!sparc_fix_ut699"
-  "ldstub\t%1, %0"
-  [(set_attr "type" "multi")])
+{
+  if (sparc_fix_gr712rc)
+    return ".align\t16\n\tldstub\t%1, %0";
+  else
+    return "ldstub\t%1, %0";
+}
+  [(set_attr "type" "multi")
+   (set (attr "length") (if_then_else (eq_attr "fix_gr712rc" "true")
+		      (const_int 4) (const_int 1)))])
-- 
2.9.3

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010
  2017-11-27  9:57 [PATCH v2 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata Daniel Cederman
  2017-11-27  9:57 ` [PATCH v2 2/4] [SPARC] Errata workaround for GRLIB-TN-0011 Daniel Cederman
@ 2017-11-27  9:57 ` Daniel Cederman
  2017-11-28 10:04   ` Eric Botcazou
  2017-12-04 11:06   ` Eric Botcazou
  2017-11-27 10:04 ` [PATCH v2 1/4] [SPARC] Errata workaround for GRLIB-TN-0012 Daniel Cederman
  2017-11-27 10:04 ` [PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013 Daniel Cederman
  3 siblings, 2 replies; 15+ messages in thread
From: Daniel Cederman @ 2017-11-27  9:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: ebotcazou, sebastian.huber, daniel

This patch provides a workaround for the errata described in GRLIB-TN-0010.

If the workaround is enabled it will:

* Insert a NOP between load instruction and atomic
  instruction (swap, ldstub, casa).

* Insert a NOP at branch target if load in delay slot
  and atomic instruction at branch target.

It is applicable to UT700.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  <cederman@gaisler.com>

	* config/sparc/sparc.c (atomic_insn_p): New function.
	(sparc_do_work_around_errata): Insert NOP instructions to
	prevent sequences that could trigger the TN-0010 errata for
	UT700.
	* config/sparc/sync.md (atomic_compare_and_swap_leon3_1): Make
	instruction referable in atomic_insns_p.
---
 gcc/config/sparc/sparc.c | 41 +++++++++++++++++++++++++++++++++++++++++
 gcc/config/sparc/sync.md |  2 +-
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 51045db..401dfcb 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -970,6 +970,22 @@ fpop_insn_p (rtx_insn *insn)
     }
 }
 
+/* True if INSN is an atomic instruction.  */
+
+static bool
+atomic_insn_for_leon3_p (rtx_insn *insn)
+{
+  switch (INSN_CODE (insn))
+    {
+    case CODE_FOR_swapsi:
+    case CODE_FOR_ldstub:
+    case CODE_FOR_atomic_compare_and_swap_leon3_1:
+      return true;
+    default:
+      return false;
+    }
+}
+
 /* We use a machine specific pass to enable workarounds for errata.
 
    We need to have the (essentially) final form of the insn stream in order
@@ -1024,6 +1040,31 @@ sparc_do_work_around_errata (void)
 	    emit_insn_before (gen_nop (), target);
 	}
 
+      /* Insert a NOP between load instruction and atomic
+	 instruction.  Insert a NOP at branch target if load
+	 in delay slot and atomic instruction at branch target.  */
+      if (sparc_fix_ut700
+	  && NONJUMP_INSN_P (insn)
+	  && (set = single_set (insn)) != NULL_RTX
+	  && MEM_P (SET_SRC (set))
+	  && REG_P (SET_DEST (set)))
+	{
+	  if (jump)
+	    {
+	      rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
+	      if (target
+		  && atomic_insn_for_leon3_p (target))
+		emit_insn_before (gen_nop (), target);
+	    }
+
+	  next = next_active_insn (insn);
+	  if (!next)
+	    break;
+
+	  if (atomic_insn_for_leon3_p (next))
+	    insert_nop = true;
+	}
+
       /* Look for either of these two sequences:
 
 	 Sequence A:
diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index ead7c77..43c66e9 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -212,7 +212,7 @@
   "cas<modesuffix>\t%1, %2, %0"
   [(set_attr "type" "multi")])
 
-(define_insn "*atomic_compare_and_swap_leon3_1"
+(define_insn "atomic_compare_and_swap_leon3_1"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(match_operand:SI 1 "mem_noofs_operand" "+w"))
    (set (match_dup 1)
-- 
2.9.3

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 1/4] [SPARC] Errata workaround for GRLIB-TN-0012
  2017-11-27  9:57 [PATCH v2 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata Daniel Cederman
  2017-11-27  9:57 ` [PATCH v2 2/4] [SPARC] Errata workaround for GRLIB-TN-0011 Daniel Cederman
  2017-11-27  9:57 ` [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010 Daniel Cederman
@ 2017-11-27 10:04 ` Daniel Cederman
  2017-11-28 10:01   ` Eric Botcazou
  2017-11-27 10:04 ` [PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013 Daniel Cederman
  3 siblings, 1 reply; 15+ messages in thread
From: Daniel Cederman @ 2017-11-27 10:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: ebotcazou, sebastian.huber, daniel

This patch provides a workaround for the errata described in GRLIB-TN-0012.

If the workaround is enabled it will:

* Prevent any floating-point operation from being placed in the
  delay slot of an annulled integer branch.

* Place a NOP at the branch target of an integer branch if it is
  a floating-point operation or a floating-point branch.

It is applicable to GR712RC.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  <cederman@gaisler.com>

	* config/sparc/sparc.c (fpop_insn_p): New function.
	(sparc_do_work_around_errata): Insert NOP instructions to
	prevent sequences that could trigger the TN-0012 errata for
	GR712RC.
	(pass_work_around_errata::gate): Also test sparc_fix_gr712rc.
	* config/sparc/sparc.md (fix_gr712rc): New attribute.
	(in_branch_annul_delay): Prevent floating-point instructions
	in delay slot of annulled integer branch.
---
 gcc/config/sparc/sparc.c  | 57 +++++++++++++++++++++++++++++++++++++++++++----
 gcc/config/sparc/sparc.md | 28 +++++++++++++++++++++++
 2 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index a9945e2..51045db 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -945,6 +945,31 @@ mem_ref (rtx x)
   return NULL_RTX;
 }
 
+/* True if INSN is a floating-point instruction.  */
+
+static bool
+fpop_insn_p (rtx_insn *insn)
+{
+  if (GET_CODE (PATTERN (insn)) != SET)
+    return false;
+
+  switch (get_attr_type (insn))
+    {
+    case TYPE_FPMOVE:
+    case TYPE_FPCMOVE:
+    case TYPE_FP:
+    case TYPE_FPCMP:
+    case TYPE_FPMUL:
+    case TYPE_FPDIVS:
+    case TYPE_FPSQRTS:
+    case TYPE_FPDIVD:
+    case TYPE_FPSQRTD:
+      return true;
+    default:
+      return false;
+    }
+}
+
 /* We use a machine specific pass to enable workarounds for errata.
 
    We need to have the (essentially) final form of the insn stream in order
@@ -970,11 +995,34 @@ sparc_do_work_around_errata (void)
     {
       bool insert_nop = false;
       rtx set;
+      rtx_insn *jump;
+      rtx_sequence *seq;
 
       /* Look into the instruction in a delay slot.  */
-      if (NONJUMP_INSN_P (insn))
-	if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
-	  insn = seq->insn (1);
+      if (NONJUMP_INSN_P (insn)
+	  && (seq = dyn_cast <rtx_sequence *> (PATTERN (insn))))
+	  {
+	    jump = seq->insn (0);
+	    insn = seq->insn (1);
+	  }
+      else if (JUMP_P (insn))
+	jump = insn;
+      else
+	jump = NULL;
+
+      /* Place a NOP at the branch target of an integer branch if it is
+	 a floating-point operation or a floating-point branch.  */
+      if (sparc_fix_gr712rc
+	  && jump != NULL_RTX
+	  && get_attr_branch_type (jump) == BRANCH_TYPE_ICC)
+	{
+	  rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
+	  if (target
+	      && (fpop_insn_p (target)
+		  || ((JUMP_P (target)
+		       && get_attr_branch_type (target) == BRANCH_TYPE_FCC))))
+	    emit_insn_before (gen_nop (), target);
+	}
 
       /* Look for either of these two sequences:
 
@@ -1303,7 +1351,8 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
     {
-      return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst;
+      return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst
+          || sparc_fix_gr712rc;
     }
 
   virtual unsigned int execute (function *)
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index d9cbd4f..7e03bda 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -430,6 +430,10 @@
    (symbol_ref "(sparc_fix_b2bst != 0
 		 ? FIX_B2BST_TRUE : FIX_B2BST_FALSE)"))
 
+(define_attr "fix_gr712rc" "false,true"
+   (symbol_ref "(sparc_fix_gr712rc != 0
+		 ? FIX_GR712RC_TRUE : FIX_GR712RC_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).
@@ -590,6 +594,26 @@
 	   (const_string "true")
 	] (const_string "false")))
 
+(define_attr "in_integer_branch_annul_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_gr712rc" "true")
+	      (eq_attr "type" "fp,fpcmp,fpmove,fpcmove,fpmul,
+			       fpdivs,fpsqrts,fpdivd,fpsqrtd"))
+	   (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")
+	      (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
+		   (ior (eq_attr "fptype" "single")
+		        (eq_attr "fptype_ut699" "single"))))
+	   (const_string "false")
+	 (eq_attr "length" "1")
+	   (const_string "true")
+	] (const_string "false")))
+
 (define_delay (eq_attr "type" "call")
   [(eq_attr "in_call_delay" "true") (nil) (nil)])
 
@@ -602,6 +626,10 @@
 (define_delay (eq_attr "type" "branch")
   [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
 
+(define_delay (and (eq_attr "type" "branch") (eq_attr "branch_type" "icc"))
+  [(eq_attr "in_branch_delay" "true") (nil)
+  (eq_attr "in_integer_branch_annul_delay" "true")])
+
 (define_delay (eq_attr "type" "uncond_branch")
   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013
  2017-11-27  9:57 [PATCH v2 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata Daniel Cederman
                   ` (2 preceding siblings ...)
  2017-11-27 10:04 ` [PATCH v2 1/4] [SPARC] Errata workaround for GRLIB-TN-0012 Daniel Cederman
@ 2017-11-27 10:04 ` Daniel Cederman
  2017-11-27 16:43   ` Daniel Cederman
  2017-11-28 10:05   ` Eric Botcazou
  3 siblings, 2 replies; 15+ messages in thread
From: Daniel Cederman @ 2017-11-27 10:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: ebotcazou, sebastian.huber, daniel

This patch provides a workaround for the errata described in GRLIB-TN-0013.

If the workaround is enabled it will:

* Prevent div and sqrt instructions in the delay slot.

* Insert NOPs to prevent the sequence (div/sqrt) -> (two or three floating
  point operations or loads) -> (div/sqrt).

* Not insert NOPs if any of the floating point operations have a dependency
  on the destination register of the first (div/sqrt).

* Not insert NOPs if one of the floating point operations is a (div/sqrt).

* Insert NOPs to prevent (div/sqrt) followed by a branch.

It is applicable to GR712RC, UT700, and UT699.

gcc/ChangeLog:

2017-11-17  Daniel Cederman  <cederman@gaisler.com>

	* config/sparc/sparc.c (fpop_reg_depend_p): New function.
	(div_sqrt_insn_p): New function.
	(sparc_do_work_around_errata): Insert NOP instructions to
	prevent sequences that could trigger the TN-0013 errata for
	certain LEON3 processors.
	(pass_work_around_errata::gate): Also test sparc_fix_tn0013.
	(sparc_option_override): Set sparc_fix_tn0013 appropriately.
	* config/sparc/sparc.md (fix_tn0013): New attribute.
	(in_branch_delay): Prevent div and sqrt in delay slot if fix_tn0013.
	* config/sparc/sparc.opt (sparc_fix_tn0013: New variable.
---
 gcc/config/sparc/sparc.c   | 113 ++++++++++++++++++++++++++++++++++++++++++++-
 gcc/config/sparc/sparc.md  |   7 +++
 gcc/config/sparc/sparc.opt |   4 ++
 3 files changed, 122 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 401dfcb..6e91114 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -945,6 +945,39 @@ mem_ref (rtx x)
   return NULL_RTX;
 }
 
+/* True if any of INSN's source register(s) is REG.  */
+
+static bool
+insn_uses_reg_p (rtx_insn *insn, unsigned int reg)
+{
+  extract_insn (insn);
+  return ((REG_P (recog_data.operand[1])
+	   && REGNO (recog_data.operand[1]) == reg)
+	  || (recog_data.n_operands == 3
+	      && REG_P (recog_data.operand[2])
+	      && REGNO (recog_data.operand[2]) == reg));
+}
+
+/* True if INSN is a floating-point division or square-root.  */
+
+static bool
+div_sqrt_insn_p (rtx_insn *insn)
+{
+  if (GET_CODE (PATTERN (insn)) != SET)
+    return false;
+
+  switch (get_attr_type (insn))
+    {
+    case TYPE_FPDIVS:
+    case TYPE_FPSQRTS:
+    case TYPE_FPDIVD:
+    case TYPE_FPSQRTD:
+      return true;
+    default:
+      return false;
+    }
+}
+
 /* True if INSN is a floating-point instruction.  */
 
 static bool
@@ -1065,6 +1098,79 @@ sparc_do_work_around_errata (void)
 	    insert_nop = true;
 	}
 
+      /* Look for sequences that could trigger the GRLIB-TN-0013 errata.  */
+      if (sparc_fix_lost_divsqrt
+	  && NONJUMP_INSN_P (insn)
+	  && div_sqrt_insn_p (insn))
+	{
+	  int i;
+	  int fp_found = 0;
+	  rtx_insn *after;
+
+	  const unsigned int dest_reg = REGNO (SET_DEST (single_set (insn)));
+
+	  next = next_active_insn (insn);
+	  if (!next)
+	    break;
+
+	  for (after = next, i = 0; i < 4; i++)
+	    {
+	      /* Count floating-point operations.  */
+	      if (i != 3 && fpop_insn_p (after))
+		{
+		  /* If the insn uses the destination register of
+		     the div/sqrt, then it cannot be problematic.  */
+		  if (insn_uses_reg_p (after, dest_reg))
+		    break;
+		  fp_found++;
+		}
+
+	      /* Count floating-point loads.  */
+	      if (i != 3
+		  && (set = single_set (after)) != NULL_RTX
+		  && REG_P (SET_DEST (set))
+		  && REGNO (SET_DEST (set)) > 31)
+		{
+		  /* If the insn uses the destination register of
+		     the div/sqrt, then it cannot be problematic.  */
+		  if (REGNO (SET_DEST (set)) == dest_reg)
+		    break;
+		  fp_found++;
+		}
+
+	      /* Check if this is a problematic sequence.  */
+	      if (i > 1
+		  && fp_found >= 2
+		  && div_sqrt_insn_p (after))
+		{
+		  /* If is this is the short version of the problematic
+		     sequence we add two NOPs in a row to also prevent
+		     the long version.  */
+		  if (i == 2)
+		    emit_insn_before (gen_nop (), next);
+		  insert_nop = true;
+		  break;
+		}
+
+	      /* No need to scan past a second div/sqrt.  */
+	      if (div_sqrt_insn_p (after))
+		break;
+
+	      /* Insert NOP before branch.  */
+	      if (i < 3
+		  && (!NONJUMP_INSN_P (after)
+		      || GET_CODE (PATTERN (after)) == SEQUENCE))
+		{
+		  insert_nop = true;
+		  break;
+		}
+
+	      after = next_active_insn (after);
+	      if (!after)
+		break;
+	    }
+	}
+
       /* Look for either of these two sequences:
 
 	 Sequence A:
@@ -1393,7 +1499,7 @@ public:
   virtual bool gate (function *)
     {
       return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst
-          || sparc_fix_gr712rc;
+          || sparc_fix_gr712rc || sparc_fix_lost_divsqrt;
     }
 
   virtual unsigned int execute (function *)
@@ -1763,9 +1869,12 @@ sparc_option_override (void)
   if (!(target_flags_explicit & MASK_LRA))
     target_flags |= MASK_LRA;
 
-  /* Enable the back-to-back store errata workaround for LEON3FT.  */
+  /* Enable applicable errata workarounds for LEON3FT.  */
   if (sparc_fix_ut699 || sparc_fix_ut700 || sparc_fix_gr712rc)
+    {
     sparc_fix_b2bst = 1;
+    sparc_fix_lost_divsqrt = 1;
+    }
 
   /* Disable FsMULd for the UT699 since it doesn't work correctly.  */
   if (sparc_fix_ut699)
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 7e03bda..0e45509 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -430,6 +430,10 @@
    (symbol_ref "(sparc_fix_b2bst != 0
 		 ? FIX_B2BST_TRUE : FIX_B2BST_FALSE)"))
 
+(define_attr "fix_lost_divsqrt" "false,true"
+   (symbol_ref "(sparc_fix_lost_divsqrt != 0
+		 ? FIX_LOST_DIVSQRT_TRUE : FIX_LOST_DIVSQRT_FALSE)"))
+
 (define_attr "fix_gr712rc" "false,true"
    (symbol_ref "(sparc_fix_gr712rc != 0
 		 ? FIX_GR712RC_TRUE : FIX_GR712RC_FALSE)"))
@@ -581,6 +585,9 @@
 (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_lost_divsqrt" "true")
+	      (eq_attr "type" "fpdivs,fpsqrts,fpdivd,fpsqrtd"))
+	   (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"))
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index 22267f5..71ead75 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -253,6 +253,10 @@ Enable workarounds for the errata of the GR712RC processor.
 TargetVariable
 unsigned int sparc_fix_b2bst
 
+;; Enable workaround for GRLIB-TN-0013 errata
+TargetVariable
+unsigned int sparc_fix_lost_divsqrt
+
 Mask(LONG_DOUBLE_128)
 ;; Use 128-bit long double
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013
  2017-11-27 10:04 ` [PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013 Daniel Cederman
@ 2017-11-27 16:43   ` Daniel Cederman
  2017-11-28 10:08     ` Eric Botcazou
  2017-11-28 10:05   ` Eric Botcazou
  1 sibling, 1 reply; 15+ messages in thread
From: Daniel Cederman @ 2017-11-27 16:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: ebotcazou, sebastian.huber, daniel

> +	 (and (eq_attr "fix_lost_divsqrt" "true")
> +	      (eq_attr "type" "fpdivs,fpsqrts,fpdivd,fpsqrtd"))
> +	   (const_string "false")

These lines should also be added to the in_integer_branch_annul_delay 
attribute.

/Daniel C

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/4] [SPARC] Errata workaround for GRLIB-TN-0012
  2017-11-27 10:04 ` [PATCH v2 1/4] [SPARC] Errata workaround for GRLIB-TN-0012 Daniel Cederman
@ 2017-11-28 10:01   ` Eric Botcazou
  2017-11-28 12:26     ` Daniel Cederman
  0 siblings, 1 reply; 15+ messages in thread
From: Eric Botcazou @ 2017-11-28 10:01 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, sebastian.huber, daniel

> 2017-11-17  Daniel Cederman  <cederman@gaisler.com>
> 
> 	* config/sparc/sparc.c (fpop_insn_p): New function.
> 	(sparc_do_work_around_errata): Insert NOP instructions to
> 	prevent sequences that could trigger the TN-0012 errata for
> 	GR712RC.
> 	(pass_work_around_errata::gate): Also test sparc_fix_gr712rc.
> 	* config/sparc/sparc.md (fix_gr712rc): New attribute.
> 	(in_branch_annul_delay): Prevent floating-point instructions
> 	in delay slot of annulled integer branch.

Sorry, I should have been more explicit in my first reply, because:

> @@ -590,6 +594,26 @@
>  	   (const_string "true")
>  	] (const_string "false")))
> 
> +(define_attr "in_integer_branch_annul_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_gr712rc" "true")
> +	      (eq_attr "type" "fp,fpcmp,fpmove,fpcmove,fpmul,
> +			       fpdivs,fpsqrts,fpdivd,fpsqrtd"))
> +	   (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")
> +	      (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
> +		   (ior (eq_attr "fptype" "single")
> +		        (eq_attr "fptype_ut699" "single"))))
> +	   (const_string "false")
> +	 (eq_attr "length" "1")
> +	   (const_string "true")
> +	] (const_string "false")))
> +
>  (define_delay (eq_attr "type" "call")
>    [(eq_attr "in_call_delay" "true") (nil) (nil)])

is barely maintainable.  So let's go back to the original version and...

> @@ -602,6 +626,10 @@
>  (define_delay (eq_attr "type" "branch")
>    [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay"
> "true")])
> 
> +(define_delay (and (eq_attr "type" "branch") (eq_attr "branch_type" "icc"))
> +  [(eq_attr "in_branch_delay" "true") (nil)
> +  (eq_attr "in_integer_branch_annul_delay" "true")])
> +
>  (define_delay (eq_attr "type" "uncond_branch")
>    [(eq_attr "in_branch_delay" "true") (nil) (nil)])

...add (and (.) (not (eq_attr "branch_type" "icc")) to the first define_delay.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/4] [SPARC] Errata workaround for GRLIB-TN-0011
  2017-11-27  9:57 ` [PATCH v2 2/4] [SPARC] Errata workaround for GRLIB-TN-0011 Daniel Cederman
@ 2017-11-28 10:03   ` Eric Botcazou
  0 siblings, 0 replies; 15+ messages in thread
From: Eric Botcazou @ 2017-11-28 10:03 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, sebastian.huber, daniel

> 2017-11-17  Daniel Cederman  <cederman@gaisler.com>
> 
> 	* config/sparc/sync.md (swapsi): 16-byte align if sparc_fix_gr712rc.
> 	(atomic_compare_and_swap_leon3_1): Likewise.
> 	(ldstub): Likewise.

OK for mainline and 7 branch, thanks.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010
  2017-11-27  9:57 ` [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010 Daniel Cederman
@ 2017-11-28 10:04   ` Eric Botcazou
  2017-12-04 11:06   ` Eric Botcazou
  1 sibling, 0 replies; 15+ messages in thread
From: Eric Botcazou @ 2017-11-28 10:04 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, sebastian.huber, daniel

> 2017-11-17  Daniel Cederman  <cederman@gaisler.com>
> 
> 	* config/sparc/sparc.c (atomic_insn_p): New function.
> 	(sparc_do_work_around_errata): Insert NOP instructions to
> 	prevent sequences that could trigger the TN-0010 errata for
> 	UT700.
> 	* config/sparc/sync.md (atomic_compare_and_swap_leon3_1): Make
> 	instruction referable in atomic_insns_p.

OK for mainline and 7 branch, thanks.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013
  2017-11-27 10:04 ` [PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013 Daniel Cederman
  2017-11-27 16:43   ` Daniel Cederman
@ 2017-11-28 10:05   ` Eric Botcazou
  1 sibling, 0 replies; 15+ messages in thread
From: Eric Botcazou @ 2017-11-28 10:05 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, sebastian.huber, daniel

> 2017-11-17  Daniel Cederman  <cederman@gaisler.com>
> 
> 	* config/sparc/sparc.c (fpop_reg_depend_p): New function.
> 	(div_sqrt_insn_p): New function.
> 	(sparc_do_work_around_errata): Insert NOP instructions to
> 	prevent sequences that could trigger the TN-0013 errata for
> 	certain LEON3 processors.
> 	(pass_work_around_errata::gate): Also test sparc_fix_tn0013.
> 	(sparc_option_override): Set sparc_fix_tn0013 appropriately.
> 	* config/sparc/sparc.md (fix_tn0013): New attribute.
> 	(in_branch_delay): Prevent div and sqrt in delay slot if fix_tn0013.
> 	* config/sparc/sparc.opt (sparc_fix_tn0013: New variable.

OK for mainline and 7 branch modulo:

> +	      /* Check if this is a problematic sequence.  */
> +	      if (i > 1
> +		  && fp_found >= 2
> +		  && div_sqrt_insn_p (after))
> +		{
> +		  /* If is this is the short version of the problematic
> +		     sequence we add two NOPs in a row to also prevent
> +		     the long version.  */
> +		  if (i == 2)
> +		    emit_insn_before (gen_nop (), next);
> +		  insert_nop = true;
> +		  break;
> +		}

Superfluous "is".

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013
  2017-11-27 16:43   ` Daniel Cederman
@ 2017-11-28 10:08     ` Eric Botcazou
  0 siblings, 0 replies; 15+ messages in thread
From: Eric Botcazou @ 2017-11-28 10:08 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, sebastian.huber, daniel

> > +	 (and (eq_attr "fix_lost_divsqrt" "true")
> > +	      (eq_attr "type" "fpdivs,fpsqrts,fpdivd,fpsqrtd"))
> > +	   (const_string "false")
> 
> These lines should also be added to the in_integer_branch_annul_delay
> attribute.

Let's not though and make the modification I suggested instead.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/4] [SPARC] Errata workaround for GRLIB-TN-0012
  2017-11-28 10:01   ` Eric Botcazou
@ 2017-11-28 12:26     ` Daniel Cederman
  0 siblings, 0 replies; 15+ messages in thread
From: Daniel Cederman @ 2017-11-28 12:26 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches, sebastian.huber, daniel

> ...add (and (.) (not (eq_attr "branch_type" "icc")) to the first define_delay.

Ah, OK, that makes more sense. I will submit an updated version. Thanks 
for getting back so quickly.

Daniel C

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010
  2017-11-27  9:57 ` [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010 Daniel Cederman
  2017-11-28 10:04   ` Eric Botcazou
@ 2017-12-04 11:06   ` Eric Botcazou
  2017-12-04 12:25     ` Daniel Cederman
  1 sibling, 1 reply; 15+ messages in thread
From: Eric Botcazou @ 2017-12-04 11:06 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, sebastian.huber, daniel

> @@ -1024,6 +1040,31 @@ sparc_do_work_around_errata (void)
>  	    emit_insn_before (gen_nop (), target);
>  	}
> 
> +      /* Insert a NOP between load instruction and atomic
> +	 instruction.  Insert a NOP at branch target if load
> +	 in delay slot and atomic instruction at branch target.  */
> +      if (sparc_fix_ut700
> +	  && NONJUMP_INSN_P (insn)
> +	  && (set = single_set (insn)) != NULL_RTX
> +	  && MEM_P (SET_SRC (set))
> +	  && REG_P (SET_DEST (set)))

Any particular reason to use MEM_P instead of mem_ref here?  It looks like 
there is also a case for the b2bst workaround (only loads are concerned).

If no, I'll make the changes along with more cosmetic fixes.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010
  2017-12-04 11:06   ` Eric Botcazou
@ 2017-12-04 12:25     ` Daniel Cederman
  2017-12-04 23:14       ` Eric Botcazou
  0 siblings, 1 reply; 15+ messages in thread
From: Daniel Cederman @ 2017-12-04 12:25 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches, sebastian.huber, daniel

> Any particular reason to use MEM_P instead of mem_ref here?  It looks like
> there is also a case for the b2bst workaround (only loads are concerned).

No, there was no particular reason. mem_ref seems like a better choice 
if it detects more types of loads.

/Daniel C

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010
  2017-12-04 12:25     ` Daniel Cederman
@ 2017-12-04 23:14       ` Eric Botcazou
  0 siblings, 0 replies; 15+ messages in thread
From: Eric Botcazou @ 2017-12-04 23:14 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, sebastian.huber, daniel

[-- Attachment #1: Type: text/plain, Size: 429 bytes --]

> No, there was no particular reason. mem_ref seems like a better choice
> if it detects more types of loads.

Right, it's supposed to detect all types of loads.  Here's what I have 
installed on the mainline and 7 branch.


2017-12-04  Eric Botcazou  <ebotcazou@adacore.com>

	* config/sparc/sparc.c (sparc_do_work_around_errata): Use mem_ref
	instead of MEM_P in a couple more places.  Fix formatting issues.

-- 
Eric Botcazou

[-- Attachment #2: p.diff --]
[-- Type: text/x-patch, Size: 4182 bytes --]

Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 255291)
+++ config/sparc/sparc.c	(working copy)
@@ -1050,43 +1050,42 @@ sparc_do_work_around_errata (void)
       /* Look into the instruction in a delay slot.  */
       if (NONJUMP_INSN_P (insn)
 	  && (seq = dyn_cast <rtx_sequence *> (PATTERN (insn))))
-	  {
-	    jump = seq->insn (0);
-	    insn = seq->insn (1);
-	  }
+	{
+	  jump = seq->insn (0);
+	  insn = seq->insn (1);
+	}
       else if (JUMP_P (insn))
 	jump = insn;
       else
 	jump = NULL;
 
-      /* Place a NOP at the branch target of an integer branch if it is
-	 a floating-point operation or a floating-point branch.  */
+      /* Place a NOP at the branch target of an integer branch if it is a
+	 floating-point operation or a floating-point branch.  */
       if (sparc_fix_gr712rc
-	  && jump != NULL_RTX
+	  && jump
 	  && get_attr_branch_type (jump) == BRANCH_TYPE_ICC)
 	{
 	  rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
 	  if (target
 	      && (fpop_insn_p (target)
-		  || ((JUMP_P (target)
-		       && get_attr_branch_type (target) == BRANCH_TYPE_FCC))))
+		  || (JUMP_P (target)
+		      && get_attr_branch_type (target) == BRANCH_TYPE_FCC)))
 	    emit_insn_before (gen_nop (), target);
 	}
 
-      /* Insert a NOP between load instruction and atomic
-	 instruction.  Insert a NOP at branch target if load
-	 in delay slot and atomic instruction at branch target.  */
+      /* Insert a NOP between load instruction and atomic instruction.  Insert
+	 a NOP at branch target if there is a load in delay slot and an atomic
+	 instruction at branch target.  */
       if (sparc_fix_ut700
 	  && NONJUMP_INSN_P (insn)
 	  && (set = single_set (insn)) != NULL_RTX
-	  && MEM_P (SET_SRC (set))
+	  && mem_ref (SET_SRC (set))
 	  && REG_P (SET_DEST (set)))
 	{
 	  if (jump)
 	    {
 	      rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
-	      if (target
-		  && atomic_insn_for_leon3_p (target))
+	      if (target && atomic_insn_for_leon3_p (target))
 		emit_insn_before (gen_nop (), target);
 	    }
 
@@ -1098,7 +1097,9 @@ sparc_do_work_around_errata (void)
 	    insert_nop = true;
 	}
 
-      /* Look for sequences that could trigger the GRLIB-TN-0013 errata.  */
+      /* Look for a sequence that starts with a fdiv or fsqrt instruction and
+	 ends with another fdiv or fsqrt instruction with no dependencies on
+	 the former, along with an appropriate pattern in between.  */
       if (sparc_fix_lost_divsqrt
 	  && NONJUMP_INSN_P (insn)
 	  && div_sqrt_insn_p (insn))
@@ -1229,8 +1230,8 @@ sparc_do_work_around_errata (void)
 		 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))))
+		  if ((set = single_set (after)) != NULL_RTX
+		      && (MEM_P (SET_DEST (set)) || mem_ref (SET_SRC (set))))
 		    break;
 
 		  after = next_active_insn (after);
@@ -1240,21 +1241,21 @@ sparc_do_work_around_errata (void)
 
 	      /* Add NOP if third instruction is a store.  */
 	      if (i == 1
-		  && ((set = single_set (after)) != NULL_RTX)
+		  && (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)
-	  && (set = single_set (insn)) != NULL_RTX
-	  && GET_MODE_SIZE (GET_MODE (SET_SRC (set))) == 4
-	  && MEM_P (SET_SRC (set))
-	  && REG_P (SET_DEST (set))
-	  && REGNO (SET_DEST (set)) > 31
-	  && REGNO (SET_DEST (set)) % 2 != 0)
+      else if (sparc_fix_at697f
+	       && NONJUMP_INSN_P (insn)
+	       && (set = single_set (insn)) != NULL_RTX
+	       && GET_MODE_SIZE (GET_MODE (SET_SRC (set))) == 4
+	       && mem_ref (SET_SRC (set))
+	       && REG_P (SET_DEST (set))
+	       && REGNO (SET_DEST (set)) > 31
+	       && REGNO (SET_DEST (set)) % 2 != 0)
 	{
 	  /* The wrong dependency is on the enclosing double register.  */
 	  const unsigned int x = REGNO (SET_DEST (set)) - 1;

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2017-12-04 23:14 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-27  9:57 [PATCH v2 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata Daniel Cederman
2017-11-27  9:57 ` [PATCH v2 2/4] [SPARC] Errata workaround for GRLIB-TN-0011 Daniel Cederman
2017-11-28 10:03   ` Eric Botcazou
2017-11-27  9:57 ` [PATCH v2 3/4] [SPARC] Errata workaround for GRLIB-TN-0010 Daniel Cederman
2017-11-28 10:04   ` Eric Botcazou
2017-12-04 11:06   ` Eric Botcazou
2017-12-04 12:25     ` Daniel Cederman
2017-12-04 23:14       ` Eric Botcazou
2017-11-27 10:04 ` [PATCH v2 1/4] [SPARC] Errata workaround for GRLIB-TN-0012 Daniel Cederman
2017-11-28 10:01   ` Eric Botcazou
2017-11-28 12:26     ` Daniel Cederman
2017-11-27 10:04 ` [PATCH v2 4/4] [SPARC] Errata workaround for GRLIB-TN-0013 Daniel Cederman
2017-11-27 16:43   ` Daniel Cederman
2017-11-28 10:08     ` Eric Botcazou
2017-11-28 10:05   ` Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).