aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJames Greenhalgh <james.greenhalgh@arm.com>2016-11-23 17:15:17 +0000
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>2016-11-23 17:15:17 +0000
commite97dfd54b7d13f321c1ad18ee316d114c06b92ee (patch)
tree3dc62ee556ac7d4a97e9e8030730f97947a26971 /gcc
parent42e02b207fdf71f09020eef2bba3e25f5f57a946 (diff)
downloadgcc-e97dfd54b7d13f321c1ad18ee316d114c06b92ee.zip
gcc-e97dfd54b7d13f321c1ad18ee316d114c06b92ee.tar.gz
gcc-e97dfd54b7d13f321c1ad18ee316d114c06b92ee.tar.bz2
[Patch 2/17] Implement TARGET_C_EXCESS_PRECISION for i386
gcc/ * config/i386/i386.c (ix86_excess_precision): New. (TARGET_C_EXCESS_PRECISION): Define. From-SVN: r242772
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/i386/i386.c40
2 files changed, 45 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7cf9720..7b6e1b6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
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.
* target.h (flt_eval_method): New.
(excess_precision_type): Likewise.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index aa52ba3..3ccee08 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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