diff options
author | James Greenhalgh <james.greenhalgh@arm.com> | 2016-11-23 17:16:29 +0000 |
---|---|---|
committer | James Greenhalgh <jgreenhalgh@gcc.gnu.org> | 2016-11-23 17:16:29 +0000 |
commit | 638108bd6748d7c38dceac491a62c6ce5355850d (patch) | |
tree | c918945c4fc2bd799b75ae07a3b7473459eefeb0 /gcc | |
parent | e97dfd54b7d13f321c1ad18ee316d114c06b92ee (diff) | |
download | gcc-638108bd6748d7c38dceac491a62c6ce5355850d.zip gcc-638108bd6748d7c38dceac491a62c6ce5355850d.tar.gz gcc-638108bd6748d7c38dceac491a62c6ce5355850d.tar.bz2 |
[Patch 3/17] Implement TARGET_C_EXCESS_PRECISION for s390
* config/s390/s390.c (s390_excess_precision): New.
(TARGET_C_EXCESS_PRECISION): Define.
From-SVN: r242773
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 40 |
2 files changed, 45 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b6e1b6..ab0154b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2016-11-23 James Greenhalgh <james.greenhalgh@arm.com> + * config/s390/s390.c (s390_excess_precision): New. + (TARGET_C_EXCESS_PRECISION): Define. + +2016-11-23 James Greenhalgh <james.greenhalgh@arm.com> + * config/i386/i386.c (ix86_excess_precision): New. (TARGET_C_EXCESS_PRECISION): Define. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index aeafdd4..dc82fb6 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -15260,6 +15260,43 @@ s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree ty return NULL; } +/* Implement TARGET_C_EXCESS_PRECISION. + + FIXME: For historical reasons, float_t and double_t are typedef'ed to + double on s390, causing operations on float_t to operate in a higher + precision than is necessary. However, it is not the case that SFmode + operations have implicit excess precision, and we generate more optimal + code if we let the compiler know no implicit extra precision is added. + + That means when we are compiling with -fexcess-precision=fast, the value + we set for FLT_EVAL_METHOD will be out of line with the actual precision of + float_t (though they would be correct for -fexcess-precision=standard). + + A complete fix would modify glibc to remove the unnecessary typedef + of float_t to double. */ + +static enum flt_eval_method +s390_excess_precision (enum excess_precision_type type) +{ + switch (type) + { + case EXCESS_PRECISION_TYPE_IMPLICIT: + 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: + /* Otherwise, when we are in a standards compliant mode, to + ensure consistency with the implementation in glibc, report that + float is evaluated to the range and precision of double. */ + return FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE; + default: + gcc_unreachable (); + } + return FLT_EVAL_METHOD_UNPREDICTABLE; +} + /* Initialize GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -15320,6 +15357,9 @@ s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree ty #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true +#undef TARGET_C_EXCESS_PRECISION +#define TARGET_C_EXCESS_PRECISION s390_excess_precision + #undef TARGET_SCHED_ADJUST_PRIORITY #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority #undef TARGET_SCHED_ISSUE_RATE |