diff options
author | James Greenhalgh <james.greenhalgh@arm.com> | 2016-11-23 17:15:17 +0000 |
---|---|---|
committer | James Greenhalgh <jgreenhalgh@gcc.gnu.org> | 2016-11-23 17:15:17 +0000 |
commit | e97dfd54b7d13f321c1ad18ee316d114c06b92ee (patch) | |
tree | 3dc62ee556ac7d4a97e9e8030730f97947a26971 /gcc | |
parent | 42e02b207fdf71f09020eef2bba3e25f5f57a946 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 40 |
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 |