From 7620dc123570e2c8080a4dcc51d220a9d92c8841 Mon Sep 17 00:00:00 2001 From: "Gabriel F. T. Gomes" Date: Tue, 16 May 2017 13:34:34 -0300 Subject: Convert e_exp2l.c into a template This patch converts the implementation of exp2l in math/e_exp2l.c into a template in math/e_exp2_template.c, then adjusts Makefile to use this template for long double (the implementations for float and double in sysdeps have higher precedence and are not used). This template can also be used for float128, thus reducing the amount of duplicated code that gets added when adding support the new type. Tested for powerpc64le and s390x. * math/Makefile (libm-calls): Move e_exp2F to gen-libm-calls. (gen-libm-calls): Add e_exp2F to use the template. * math/e_exp2l.c: Rename to math/e_exp2_template.c. * math/e_exp2_template.c: New file, renamed from math/e_exp2l.c, and made into a template. * sysdeps/generic/math-type-macros.h (M_MIN_EXP): New macro. --- math/Makefile | 4 ++-- math/e_exp2_template.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ math/e_exp2l.c | 62 -------------------------------------------------- 3 files changed, 63 insertions(+), 64 deletions(-) create mode 100644 math/e_exp2_template.c delete mode 100644 math/e_exp2l.c (limited to 'math') diff --git a/math/Makefile b/math/Makefile index ff4aa00..9aca4e0 100644 --- a/math/Makefile +++ b/math/Makefile @@ -59,7 +59,7 @@ gen-libm-calls = cargF conjF cimagF crealF cabsF s_cacosF \ w_acoshF w_asinF w_atan2F w_atanhF w_coshF w_exp10F \ w_exp2F w_fmodF w_hypotF w_j0F w_j1F w_jnF w_logF \ w_log10F w_log2F w_powF w_remainderF w_sinhF w_sqrtF \ - w_tgammaF w_lgammaF w_lgammaF_r w_expF + w_tgammaF w_lgammaF w_lgammaF_r w_expF e_exp2F libm-calls = \ e_acosF e_acoshF e_asinF e_atan2F e_atanhF e_coshF e_expF e_fmodF \ @@ -72,7 +72,7 @@ libm-calls = \ s_nextafterF s_nexttowardF s_rintF s_scalblnF \ s_significandF s_sinF s_tanF s_tanhF \ s_fpclassifyF s_truncF \ - s_remquoF e_log2F e_exp2F s_roundF s_nearbyintF s_sincosF \ + s_remquoF e_log2F s_roundF s_nearbyintF s_sincosF \ s_fmaF s_lrintF s_llrintF s_lroundF s_llroundF e_exp10F \ s_issignalingF $(calls:s_%=m_%) x2y2m1F \ gamma_productF lgamma_negF lgamma_productF \ diff --git a/math/e_exp2_template.c b/math/e_exp2_template.c new file mode 100644 index 0000000..f1b3488 --- /dev/null +++ b/math/e_exp2_template.c @@ -0,0 +1,61 @@ +/* Compute 2^x. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +#define declare_mgen_finite_alias_x(from, to) \ + strong_alias (from, to ## _finite) +#define declare_mgen_finite_alias_s(from,to) \ + declare_mgen_finite_alias_x (from, to) +#define declare_mgen_finite_alias(from, to) \ + declare_mgen_finite_alias_s (M_SUF (from), M_SUF (to)) + +FLOAT +M_DECL_FUNC (__ieee754_exp2) (FLOAT x) +{ + if (__glibc_likely (isless (x, (FLOAT) M_MAX_EXP))) + { + if (__builtin_expect (isgreaterequal (x, (FLOAT) (M_MIN_EXP - M_MANT_DIG + - 1)), 1)) + { + int intx = (int) x; + FLOAT fractx = x - intx; + FLOAT result; + if (M_FABS (fractx) < M_EPSILON / 4) + result = M_SCALBN (1 + fractx, intx); + else + result = M_SCALBN (M_EXP (M_SUF (M_LN2) * fractx), intx); + math_check_force_underflow_nonneg (result); + return result; + } + else + { + /* Underflow or exact zero. */ + if (isinf (x)) + return 0; + else + return M_MIN * M_MIN; + } + } + else + /* Infinity, NaN or overflow. */ + return M_MAX * x; +} +declare_mgen_finite_alias (__ieee754_exp2, __exp2) diff --git a/math/e_exp2l.c b/math/e_exp2l.c deleted file mode 100644 index bd68e62..0000000 --- a/math/e_exp2l.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Compute 2^x. - Copyright (C) 2012-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -/* To avoid spurious underflows, use this definition to treat IBM long - double as approximating an IEEE-style format. */ -#if LDBL_MANT_DIG == 106 -# undef LDBL_EPSILON -# define LDBL_EPSILON 0x1p-106L -#endif - -long double -__ieee754_exp2l (long double x) -{ - if (__glibc_likely (isless (x, (long double) LDBL_MAX_EXP))) - { - if (__builtin_expect (isgreaterequal (x, (long double) (LDBL_MIN_EXP - - LDBL_MANT_DIG - - 1)), 1)) - { - int intx = (int) x; - long double fractx = x - intx; - long double result; - if (fabsl (fractx) < LDBL_EPSILON / 4.0L) - result = __scalbnl (1.0L + fractx, intx); - else - result = __scalbnl (__ieee754_expl (M_LN2l * fractx), intx); - math_check_force_underflow_nonneg (result); - return result; - } - else - { - /* Underflow or exact zero. */ - if (isinf (x)) - return 0; - else - return LDBL_MIN * LDBL_MIN; - } - } - else - /* Infinity, NaN or overflow. */ - return LDBL_MAX * x; -} -strong_alias (__ieee754_exp2l, __exp2l_finite) -- cgit v1.1