[Patch 2/17] Implement TARGET_C_EXCESS_PRECISION for i386
authorJames Greenhalgh <james.greenhalgh@arm.com>
Wed, 23 Nov 2016 17:15:17 +0000 (17:15 +0000)
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>
Wed, 23 Nov 2016 17:15:17 +0000 (17:15 +0000)
gcc/
* config/i386/i386.c (ix86_excess_precision): New.
(TARGET_C_EXCESS_PRECISION): Define.

From-SVN: r242772

gcc/ChangeLog
gcc/config/i386/i386.c

index 7cf97207916fd3e6523d5fd36337619ff04071a0..7b6e1b6433d0ce706ba32c7a1fa5d0bd372eddc4 100644 (file)
@@ -1,3 +1,8 @@
+2016-11-23  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       * config/i386/i386.c (ix86_excess_precision): New.
+       (TARGET_C_EXCESS_PRECISION): Define.
+
 2016-11-23  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * target.def (excess_precision): New hook.
index aa52ba3f7a8906e614f7d238e96e09963af4184f..3ccee085cdbfe8d28c1c2bd768cd1d40e4386815 100644 (file)
@@ -51002,6 +51002,44 @@ ix86_expand_divmod_libfunc (rtx libfunc, machine_mode mode,
   *rem_p = rem;
 }
 
+/* Set the value of FLT_EVAL_METHOD in float.h.  When using only the
+   FPU, assume that the fpcw is set to extended precision; when using
+   only SSE, rounding is correct; when using both SSE and the FPU,
+   the rounding precision is indeterminate, since either may be chosen
+   apparently at random.  */
+
+static enum flt_eval_method
+ix86_excess_precision (enum excess_precision_type type)
+{
+  switch (type)
+    {
+      case EXCESS_PRECISION_TYPE_FAST:
+       /* The fastest type to promote to will always be the native type,
+          whether that occurs with implicit excess precision or
+          otherwise.  */
+       return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
+      case EXCESS_PRECISION_TYPE_STANDARD:
+      case EXCESS_PRECISION_TYPE_IMPLICIT:
+       /* Otherwise, the excess precision we want when we are
+          in a standards compliant mode, and the implicit precision we
+          provide can be identical.  */
+       if (!TARGET_80387)
+         return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
+       else if (TARGET_MIX_SSE_I387)
+         return FLT_EVAL_METHOD_UNPREDICTABLE;
+       else if (!TARGET_SSE_MATH)
+         return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE;
+       else if (TARGET_SSE2)
+         return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
+       else
+         return FLT_EVAL_METHOD_UNPREDICTABLE;
+      default:
+       gcc_unreachable ();
+    }
+
+  return FLT_EVAL_METHOD_UNPREDICTABLE;
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
@@ -51233,6 +51271,8 @@ ix86_run_selftests (void)
 #undef TARGET_MD_ASM_ADJUST
 #define TARGET_MD_ASM_ADJUST ix86_md_asm_adjust
 
+#undef TARGET_C_EXCESS_PRECISION
+#define TARGET_C_EXCESS_PRECISION ix86_excess_precision
 #undef TARGET_PROMOTE_PROTOTYPES
 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
 #undef TARGET_SETUP_INCOMING_VARARGS