Hi, This patch ports the logic from i386's TARGET_FLT_EVAL_METHOD to the new target hook TARGET_C_EXCESS_PRECISION.
Bootstrapped and tested with no issues. OK? Thanks, James --- gcc/ 2016-09-30 James Greenhalgh <james.greenha...@arm.com> * config/i386/i386.c (ix86_excess_precision): New. (TARGET_C_EXCESS_PRECISION): Define.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e0b2d57..3c801c2 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -50359,6 +50359,45 @@ ix86_addr_space_zero_address_valid (addr_space_t as) { return as != ADDR_SPACE_GENERIC; } + +/* 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; +} + #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID ix86_addr_space_zero_address_valid @@ -50563,6 +50602,8 @@ ix86_addr_space_zero_address_valid (addr_space_t as) #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