Patchwork Add workaround for LEON 3 FP errata

login
register
mail settings
Submitter Eric Botcazou
Date Nov. 23, 2012, 4:01 p.m.
Message ID <50181313.QIxRkrc9ui@polaris>
Download mbox | patch
Permalink /patch/201363/
State New
Headers show

Comments

Eric Botcazou - Nov. 23, 2012, 4:01 p.m.
Hi,

this adds a workaround (-mfix-ut699 switch) for the floating-point errata of 
the LEON 3 processor UT699.  It's almost entirely implemented in the SPARC 
back-end, but there is a small change in expand_builtin_mathfn to make use of 
sqrt_optab with a larger mode if it isn't available in the original mode.

Tested on SPARC/Solaris and x86-64/Linux, OK for the mainline?


2012-11-23  Eric Botcazou  <ebotcazou@adacore.com>

	* doc/invoke.texi (SPARC Options): Document -mfix-ut699.
	* builtins.c (expand_builtin_mathfn) <BUILT_IN_SQRT>: Try to widen the
	mode if the instruction isn't available in the original mode.
	* config/sparc/sparc.opt (mfix-ut699): New option.
	* config/sparc/sparc.md (muldf3_extend): Disable if -mfix-ut699.
	(divdf3): Turn into expander.
	(divdf3_nofix): New insn.
	(divdf3_fix): Likewise.
	(divsf3): Disable if -mfix-ut699.
	(sqrtdf2): Turn into expander.
	(sqrtdf2_nofix): New insn.
	(sqrtdf2_fix): Likewise.
	(sqrtsf2): Disable if -mfix-ut699.

Patch

Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 193720)
+++ doc/invoke.texi	(working copy)
@@ -932,7 +932,7 @@  See RS/6000 and PowerPC Options.
 -mvis2  -mno-vis2  -mvis3  -mno-vis3 @gol
 -mcbcond -mno-cbcond @gol
 -mfmaf  -mno-fmaf  -mpopc  -mno-popc @gol
--mfix-at697f}
+-mfix-at697f -mfix-ut699}
 
 @emph{SPU Options}
 @gccoptlist{-mwarn-reloc -merror-reloc @gol
@@ -19200,6 +19200,11 @@  later.
 @opindex mfix-at697f
 Enable the documented workaround for the single erratum of the Atmel AT697F
 processor (which corresponds to erratum #13 of the AT697E processor).
+
+@item -mfix-ut699
+@opindex mfix-ut699
+Enable the documented workarounds for the floating-point errata of the UT699
+processor.
 @end table
 
 These @samp{-m} options are supported in addition to the above
Index: builtins.c
===================================================================
--- builtins.c	(revision 193720)
+++ builtins.c	(working copy)
@@ -1959,6 +1959,7 @@  expand_builtin_mathfn (tree exp, rtx tar
   tree fndecl = get_callee_fndecl (exp);
   enum machine_mode mode;
   bool errno_set = false;
+  bool try_widening = false;
   tree arg;
 
   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
@@ -1970,6 +1971,7 @@  expand_builtin_mathfn (tree exp, rtx tar
     {
     CASE_FLT_FN (BUILT_IN_SQRT):
       errno_set = ! tree_expr_nonnegative_p (arg);
+      try_widening = true;
       builtin_optab = sqrt_optab;
       break;
     CASE_FLT_FN (BUILT_IN_EXP):
@@ -2026,8 +2028,10 @@  expand_builtin_mathfn (tree exp, rtx tar
   if (! flag_errno_math || ! HONOR_NANS (mode))
     errno_set = false;
 
-  /* Before working hard, check whether the instruction is available.  */
-  if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing
+  /* Before working hard, check whether the instruction is available, but try
+     to widen the mode for specific operations.  */
+  if ((optab_handler (builtin_optab, mode) != CODE_FOR_nothing
+       || (try_widening && !excess_precision_type (TREE_TYPE (exp))))
       && (!errno_set || !optimize_insn_for_size_p ()))
     {
       target = gen_reg_rtx (mode);
Index: config/sparc/sparc.md
===================================================================
--- config/sparc/sparc.md	(revision 193720)
+++ config/sparc/sparc.md	(working copy)
@@ -5550,7 +5550,7 @@  (define_insn "*muldf3_extend"
   [(set (match_operand:DF 0 "register_operand" "=e")
 	(mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
 		 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
-  "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
+  "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
   "fsmuld\t%1, %2, %0"
   [(set_attr "type" "fpmul")
    (set_attr "fptype" "double")])
@@ -5579,20 +5579,37 @@  (define_insn "*divtf3_hq"
   "fdivq\t%1, %2, %0"
   [(set_attr "type" "fpdivd")])
 
-(define_insn "divdf3"
+(define_expand "divdf3"
   [(set (match_operand:DF 0 "register_operand" "=e")
 	(div:DF (match_operand:DF 1 "register_operand" "e")
 		(match_operand:DF 2 "register_operand" "e")))]
   "TARGET_FPU"
+  "")
+
+(define_insn "*divdf3_nofix"
+  [(set (match_operand:DF 0 "register_operand" "=e")
+	(div:DF (match_operand:DF 1 "register_operand" "e")
+		(match_operand:DF 2 "register_operand" "e")))]
+  "TARGET_FPU && !sparc_fix_ut699"
   "fdivd\t%1, %2, %0"
   [(set_attr "type" "fpdivd")
    (set_attr "fptype" "double")])
 
+(define_insn "*divdf3_fix"
+  [(set (match_operand:DF 0 "register_operand" "=e")
+	(div:DF (match_operand:DF 1 "register_operand" "e")
+		(match_operand:DF 2 "register_operand" "e")))]
+  "TARGET_FPU && sparc_fix_ut699"
+  "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
+  [(set_attr "type" "fpdivd")
+   (set_attr "fptype" "double")
+   (set_attr "length" "2")])
+
 (define_insn "divsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
 	(div:SF (match_operand:SF 1 "register_operand" "f")
 		(match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_FPU"
+  "TARGET_FPU && !sparc_fix_ut699"
   "fdivs\t%1, %2, %0"
   [(set_attr "type" "fpdivs")])
 
@@ -5793,18 +5810,33 @@  (define_insn "*sqrttf2_hq"
   "fsqrtq\t%1, %0"
   [(set_attr "type" "fpsqrtd")])
 
-(define_insn "sqrtdf2"
+(define_expand "sqrtdf2"
   [(set (match_operand:DF 0 "register_operand" "=e")
 	(sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
   "TARGET_FPU"
+  "")
+
+(define_insn "*sqrtdf2_nofix"
+  [(set (match_operand:DF 0 "register_operand" "=e")
+	(sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
+  "TARGET_FPU && !sparc_fix_ut699"
   "fsqrtd\t%1, %0"
   [(set_attr "type" "fpsqrtd")
    (set_attr "fptype" "double")])
 
+(define_insn "*sqrtdf2_fix"
+  [(set (match_operand:DF 0 "register_operand" "=e")
+	(sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
+  "TARGET_FPU && sparc_fix_ut699"
+  "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
+  [(set_attr "type" "fpsqrtd")
+   (set_attr "fptype" "double")
+   (set_attr "length" "2")])
+
 (define_insn "sqrtsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
 	(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
-  "TARGET_FPU"
+  "TARGET_FPU && !sparc_fix_ut699"
   "fsqrts\t%1, %0"
   [(set_attr "type" "fpsqrts")])
 
Index: config/sparc/sparc.opt
===================================================================
--- config/sparc/sparc.opt	(revision 193720)
+++ config/sparc/sparc.opt	(working copy)
@@ -201,6 +201,10 @@  Target Report RejectNegative Var(sparc_f
 Enable workaround for single erratum of AT697F processor
 (corresponding to erratum #13 of AT697E processor)
 
+mfix-ut699
+Target Report RejectNegative Var(sparc_fix_ut699)
+Enable workarounds for the FP errata of the UT699 processor
+
 Mask(LONG_DOUBLE_128)
 ;; Use 128-bit long double