about summary refs log tree commit diff
path: root/math/e_exp2_template.c
diff options
context:
space:
mode:
authorGabriel F. T. Gomes <gftg@linux.vnet.ibm.com>2017-05-16 13:34:34 -0300
committerGabriel F. T. Gomes <gftg@linux.vnet.ibm.com>2017-05-17 14:44:08 -0300
commit7620dc123570e2c8080a4dcc51d220a9d92c8841 (patch)
treeb6494a7a8a234c5d74af6e40a12e770185bd1c2d /math/e_exp2_template.c
parentad2f35cb396d24391150675fb55311c98d1e1592 (diff)
downloadglibc-7620dc123570e2c8080a4dcc51d220a9d92c8841.tar.gz
glibc-7620dc123570e2c8080a4dcc51d220a9d92c8841.tar.xz
glibc-7620dc123570e2c8080a4dcc51d220a9d92c8841.zip
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.
Diffstat (limited to 'math/e_exp2_template.c')
-rw-r--r--math/e_exp2_template.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/math/e_exp2_template.c b/math/e_exp2_template.c
new file mode 100644
index 0000000000..f1b34882d2
--- /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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+
+#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)