public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 2/4] [SPARC] Errata workaround for GRLIB-TN-0011
  2017-11-20 12:50 [PATCH 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata Daniel Cederman
  2017-11-20 12:50 ` [PATCH 1/4] [SPARC] Errata workaround for GRLIB-TN-0012 Daniel Cederman
@ 2017-11-20 12:50 ` Daniel Cederman
  2017-11-24 10:57   ` Eric Botcazou
  2017-11-20 12:52 ` [PATCH 4/4] [SPARC] Errata workaround for GRLIB-TN-0013 Daniel Cederman
  2017-11-20 12:53 ` [PATCH 3/4] [SPARC] Errata workaround for GRLIB-TN-0010 Daniel Cederman
  3 siblings, 1 reply; 9+ messages in thread
From: Daniel Cederman @ 2017-11-20 12:50 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 | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index 1593bde..d5c505b 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -222,6 +222,8 @@
 	  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
@@ -275,7 +277,12 @@
    (set (match_dup 1)
 	(match_operand:SI 2 "register_operand" "0"))]
   "(TARGET_V8 || TARGET_V9) && !sparc_fix_ut699"
-  "swap\t%1, %0"
+{
+  if (sparc_fix_gr712rc)
+    return ".align\t16\n\tswap\t%1, %0";
+  else
+    return "swap\t%1, %0";
+}
   [(set_attr "type" "multi")])
 
 (define_expand "atomic_test_and_set"
@@ -307,5 +314,10 @@
 			    UNSPECV_LDSTUB))
    (set (match_dup 1) (const_int -1))]
   "!sparc_fix_ut699"
-  "ldstub\t%1, %0"
+{
+  if (sparc_fix_gr712rc)
+    return ".align\t16\n\tldstub\t%1, %0";
+  else
+    return "ldstub\t%1, %0";
+}
   [(set_attr "type" "multi")])
-- 
2.9.3

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

* [PATCH 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata
@ 2017-11-20 12:50 Daniel Cederman
  2017-11-20 12:50 ` [PATCH 1/4] [SPARC] Errata workaround for GRLIB-TN-0012 Daniel Cederman
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Daniel Cederman @ 2017-11-20 12:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: ebotcazou, sebastian.huber, daniel

Hello,

This patch series adds workarounds for the newly discovered errata for UT699, UT700, and GR712RC. The errata and possible workarounds are described in the following documents available at http://www.gaisler.com/index.php/information/app-tech-notes:

GRLIB-TN-0010 - LEON3/FT AHB Deadlock After Sequence of Load and Atomic Instructions
GRLIB-TN-0011 - LEON3/FT AHB Lock Release during Atomic Operation
GRLIB-TN-0012 - GR712RC Incorrect Annulation of Floating-point Operation on Instruction Cache Parity Error
GRLIB-TN-0013 - GRFPU Floating-point controller: Missing FDIV/FSQRT Result

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   | 205 ++++++++++++++++++++++++++++++++++++++++++++-
 gcc/config/sparc/sparc.md  |  24 ++++++
 gcc/config/sparc/sparc.opt |   4 +
 gcc/config/sparc/sync.md   |  18 +++-
 4 files changed, 245 insertions(+), 6 deletions(-)

-- 
2.9.3

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

* [PATCH 1/4] [SPARC] Errata workaround for GRLIB-TN-0012
  2017-11-20 12:50 [PATCH 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata Daniel Cederman
@ 2017-11-20 12:50 ` Daniel Cederman
  2017-11-24 10:57   ` Eric Botcazou
  2017-11-20 12:50 ` [PATCH 2/4] [SPARC] Errata workaround for GRLIB-TN-0011 Daniel Cederman
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Daniel Cederman @ 2017-11-20 12:50 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  | 50 +++++++++++++++++++++++++++++++++++++++++++++--
 gcc/config/sparc/sparc.md | 17 ++++++++++++++++
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index a9945e2..8f6eb48 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 floating-point instruction.  */
+
+static int
+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,31 @@ sparc_do_work_around_errata (void)
     {
       bool insert_nop = false;
       rtx set;
+      rtx_insn *jump = 0;
 
       /* 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);
+	  {
+	    jump = seq->insn (0);
+	    insn = seq->insn (1);
+	  }
+
+      /* 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_P (insn) || jump)
+	  && get_attr_branch_type (jump ? jump : insn) == BRANCH_TYPE_ICC)
+	{
+	  rtx_insn *target;
+
+	  target = next_active_insn (JUMP_LABEL_AS_INSN (jump ? jump : insn));
+	  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 +1348,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..ef789e2 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,15 @@
 	   (const_string "true")
 	] (const_string "false")))
 
+(define_attr "in_branch_annul_delay" "false,true"
+  (cond[(and (eq_attr "fix_gr712rc" "true")
+	     (eq_attr "type" "fp,fpcmp,fpmove,fpcmove,fpmul,
+			      fpdivs,fpsqrts,fpdivd,fpsqrtd"))
+	   (const_string "false")
+	(eq_attr "in_branch_delay" "true")
+	   (const_string "true")
+	] (const_string "false")))
+
 (define_delay (eq_attr "type" "call")
   [(eq_attr "in_call_delay" "true") (nil) (nil)])
 
@@ -602,6 +615,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_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] 9+ messages in thread

* [PATCH 4/4] [SPARC] Errata workaround for GRLIB-TN-0013
  2017-11-20 12:50 [PATCH 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata Daniel Cederman
  2017-11-20 12:50 ` [PATCH 1/4] [SPARC] Errata workaround for GRLIB-TN-0012 Daniel Cederman
  2017-11-20 12:50 ` [PATCH 2/4] [SPARC] Errata workaround for GRLIB-TN-0011 Daniel Cederman
@ 2017-11-20 12:52 ` Daniel Cederman
  2017-11-24 11:53   ` Eric Botcazou
  2017-11-20 12:53 ` [PATCH 3/4] [SPARC] Errata workaround for GRLIB-TN-0010 Daniel Cederman
  3 siblings, 1 reply; 9+ messages in thread
From: Daniel Cederman @ 2017-11-20 12:52 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   | 114 ++++++++++++++++++++++++++++++++++++++++++++-
 gcc/config/sparc/sparc.md  |   7 +++
 gcc/config/sparc/sparc.opt |   4 ++
 3 files changed, 123 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 9faf774..3da642e 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 the floating-point instruction's source
+   registers is the same as the provided register.  */
+
+static int
+fpop_reg_depend_p (rtx_insn *insn, unsigned int reg)
+{
+  extract_insn (insn);
+  return (REGNO (recog_data.operand[1]) == reg
+	  || (recog_data.n_operands == 3
+	      && REGNO (recog_data.operand[2]) == reg));
+}
+
+/* True if the instruction is floating-point division or
+   floating-point square-root.  */
+
+static int
+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 floating-point instruction.  */
 
 static int
@@ -1064,6 +1097,80 @@ sparc_do_work_around_errata (void)
 	    insert_nop = true;
 	}
 
+      /* Look for sequences that could trigger the TN-0013 errata.  */
+      if (sparc_fix_tn0013
+	  && NONJUMP_INSN_P (insn)
+	  && div_sqrt_insn_p (insn))
+	{
+	  int i;
+	  int fp_found = 0;
+	  unsigned int dest_reg;
+	  rtx_insn *after;
+
+	  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 (fpop_reg_depend_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))
+		{
+		  /* Add extra NOP to prevent second version of
+		     problematic sequence.  */
+		  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:
@@ -1392,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_tn0013;
     }
 
   virtual unsigned int execute (function *)
@@ -1762,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_tn0013 = 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 ef789e2..ec2b476 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_tn0013" "false,true"
+   (symbol_ref "(sparc_fix_tn0013 != 0
+		 ? FIX_TN0013_TRUE : FIX_TN0013_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_tn0013" "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..43cd964 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 TN-0013 errata
+TargetVariable
+unsigned int sparc_fix_tn0013
+
 Mask(LONG_DOUBLE_128)
 ;; Use 128-bit long double
 
-- 
2.9.3

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

* [PATCH 3/4] [SPARC] Errata workaround for GRLIB-TN-0010
  2017-11-20 12:50 [PATCH 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata Daniel Cederman
                   ` (2 preceding siblings ...)
  2017-11-20 12:52 ` [PATCH 4/4] [SPARC] Errata workaround for GRLIB-TN-0013 Daniel Cederman
@ 2017-11-20 12:53 ` Daniel Cederman
  2017-11-24 11:12   ` Eric Botcazou
  3 siblings, 1 reply; 9+ messages in thread
From: Daniel Cederman @ 2017-11-20 12:53 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 | 43 +++++++++++++++++++++++++++++++++++++++++++
 gcc/config/sparc/sync.md |  2 +-
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 8f6eb48..9faf774 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 complex atomic instruction.  */
+
+static int
+atomic_insn_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
@@ -1021,6 +1037,33 @@ 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;
+
+	      target = next_active_insn (JUMP_LABEL_AS_INSN (jump));
+	      if (target
+		  && atomic_insn_p (target))
+		emit_insn_before (gen_nop (), target);
+	    }
+
+	  next = next_active_insn (insn);
+	  if (!next)
+	    break;
+
+	  if (atomic_insn_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 d5c505b..b1baa73 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] 9+ messages in thread

* Re: [PATCH 2/4] [SPARC] Errata workaround for GRLIB-TN-0011
  2017-11-20 12:50 ` [PATCH 2/4] [SPARC] Errata workaround for GRLIB-TN-0011 Daniel Cederman
@ 2017-11-24 10:57   ` Eric Botcazou
  0 siblings, 0 replies; 9+ messages in thread
From: Eric Botcazou @ 2017-11-24 10:57 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.

You need to adjust the "length" attribute accordingly (and conservatively), 
see atomic_compare_and_swapdi_v8plus for reference.

-- 
Eric Botcazou

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

* Re: [PATCH 1/4] [SPARC] Errata workaround for GRLIB-TN-0012
  2017-11-20 12:50 ` [PATCH 1/4] [SPARC] Errata workaround for GRLIB-TN-0012 Daniel Cederman
@ 2017-11-24 10:57   ` Eric Botcazou
  0 siblings, 0 replies; 9+ messages in thread
From: Eric Botcazou @ 2017-11-24 10:57 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.

OK for mainline and 7 branch modulo the following nits:

> +/* True if floating-point instruction.  */
> +
> +static int
> +fpop_insn_p (rtx_insn *insn)

'bool' instead of 'int'.  "True if INSN is a floating-point instruction."

> +{
> +  if ( GET_CODE (PATTERN (insn)) != SET)
> +    return false;

No space before GET_CODE.

>  /* 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,31 @@ sparc_do_work_around_errata (void)
>      {
>        bool insert_nop = false;
>        rtx set;
> +      rtx_insn *jump = 0;
> 
>        /* 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);
> +	  {
> +	    jump = seq->insn (0);
> +	    insn = seq->insn (1);
> +	  }

This should be changed into:

      rtx_insn jump;

      /* Look into the instruction in a delay slot.  */
      if (NONJUMP_INSN_P (insn)
	  && (rtx_sequence *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_RTX;

and the block below simplified accordingly.

> +      /* 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_P (insn) || jump)
> +	  && get_attr_branch_type (jump ? jump : insn) == BRANCH_TYPE_ICC)
> +	{
> +	  rtx_insn *target;
> +
> +	  target = next_active_insn (JUMP_LABEL_AS_INSN (jump ? jump : insn));

	  rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));

>        /* Look for either of these two sequences:
> 
> @@ -1303,7 +1348,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;
>      }

"|| sparc_fix_gr712rc" lined up under sparc_fix_at697f.

> @@ -602,6 +615,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_branch_annul_delay" "true")])
> +

I think that we'd better keep the various define_delay's mutually exclusive.

-- 
Eric Botcazou

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

* Re: [PATCH 3/4] [SPARC] Errata workaround for GRLIB-TN-0010
  2017-11-20 12:53 ` [PATCH 3/4] [SPARC] Errata workaround for GRLIB-TN-0010 Daniel Cederman
@ 2017-11-24 11:12   ` Eric Botcazou
  0 siblings, 0 replies; 9+ messages in thread
From: Eric Botcazou @ 2017-11-24 11:12 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 modulo the following nits:

> +/* True if complex atomic instruction.  */
> +
> +static int
> +atomic_insn_p (rtx_insn *insn)

'bool' instead of 'int'.  "True if INSN is an atomic instruction."

I'd rename the function into "atomic_insn_for_leon3_p" since you're handling 
only the LEON3 instructions.

> @@ -1021,6 +1037,33 @@ 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.  */

Double space after colon.

> +      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;
> +
> +	      target = next_active_insn (JUMP_LABEL_AS_INSN (jump));

	      rtx_insn *target
		= next_active_insn (JUMP_LABEL_AS_INSN (jump));


> +	      if (target
> +		  && atomic_insn_p (target))

On a single line.

-- 
Eric Botcazou

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

* Re: [PATCH 4/4] [SPARC] Errata workaround for GRLIB-TN-0013
  2017-11-20 12:52 ` [PATCH 4/4] [SPARC] Errata workaround for GRLIB-TN-0013 Daniel Cederman
@ 2017-11-24 11:53   ` Eric Botcazou
  0 siblings, 0 replies; 9+ messages in thread
From: Eric Botcazou @ 2017-11-24 11:53 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 the following nits:

> +/* True if any of the floating-point instruction's source
> +   registers is the same as the provided register.  */
> +
> +static int
> fpop_reg_depend_p (rtx_insn *insn, unsigned int reg)

'bool' instead of 'int'.  "True if any of INSN's source register(s) is REG".

The function's name is awkward.  insn_uses_reg_p?  insn_reads_reg_p?

> +/* True if the instruction is floating-point division or
> +   floating-point square-root.  */
> +
> +static int
> +div_sqrt_insn_p (rtx_insn *insn)

'bool' instead of 'int'. "True if INSN is a floating-point ..."

> +  if ( GET_CODE (PATTERN (insn)) != SET)
> +    return false;

No space before GET_CODE.

> @@ -1064,6 +1097,80 @@ sparc_do_work_around_errata (void)
>  	    insert_nop = true;
>  	}
> 
> +      /* Look for sequences that could trigger the TN-0013 errata.  */
> +      if (sparc_fix_tn0013
> +	  && NONJUMP_INSN_P (insn)
> +	  && div_sqrt_insn_p (insn))
> +	{
> +	  int i;
> +	  int fp_found = 0;
> +	  unsigned int dest_reg;
> +	  rtx_insn *after;
> +
> +	  dest_reg = REGNO (SET_DEST (single_set (insn)));

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

On a single line.

> +		  /* If the insn uses the destination register of
> +		     the div/sqrt, then it cannot be problematic.  */
> +		  if (fpop_reg_depend_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))
> +		{
> +		  /* Add extra NOP to prevent second version of
> +		     problematic sequence.  */
> +		  if (i == 2)
> +		    emit_insn_before (gen_nop (), next);
> +		  insert_nop = true;
> +		  break;
> +		}

So you emit 2 NOPs in a row if i == 2?

> diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
> index 22267f5..43cd964 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 TN-0013 errata
> +TargetVariable
> +unsigned int sparc_fix_tn0013

Can we find a more evocative name for the variable?

-- 
Eric Botcazou

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

end of thread, other threads:[~2017-11-24 11:22 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-20 12:50 [PATCH 0/4] [SPARC] Workarounds for UT699, UT700, and GR712RC errata Daniel Cederman
2017-11-20 12:50 ` [PATCH 1/4] [SPARC] Errata workaround for GRLIB-TN-0012 Daniel Cederman
2017-11-24 10:57   ` Eric Botcazou
2017-11-20 12:50 ` [PATCH 2/4] [SPARC] Errata workaround for GRLIB-TN-0011 Daniel Cederman
2017-11-24 10:57   ` Eric Botcazou
2017-11-20 12:52 ` [PATCH 4/4] [SPARC] Errata workaround for GRLIB-TN-0013 Daniel Cederman
2017-11-24 11:53   ` Eric Botcazou
2017-11-20 12:53 ` [PATCH 3/4] [SPARC] Errata workaround for GRLIB-TN-0010 Daniel Cederman
2017-11-24 11:12   ` 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).