[3/9] ldbl-128ibm-compat: Provide a generic scalb implementation
Commit Message
Create templates for scalb and reuse them in ldbl-128ibm-compat in order
to provide the local symbol __scalbf128 and the global symbol
__scalbieee128.
2018-06-06 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
* math/e_scalb_template.c: New file.
* math/w_scalb_template.c: New file.
* sysdeps/ieee754/ldbl-128ibm-compat/Makefile: New file.
* sysdeps/ieee754/ldbl-128ibm-compat/Versions: Add __scalbieee128.
* sysdeps/ieee754/ldbl-128ibm-compat/e_scalbf128.c: New file.
* sysdeps/ieee754/ldbl-128ibm-compat/w_scalbf128.c: New file.
---
math/e_scalb_template.c | 54 ++++++++++++++
math/w_scalb_template.c | 95 ++++++++++++++++++++++++
sysdeps/ieee754/ldbl-128ibm-compat/Makefile | 6 ++
sysdeps/ieee754/ldbl-128ibm-compat/Versions | 1 +
sysdeps/ieee754/ldbl-128ibm-compat/e_scalbf128.c | 21 ++++++
sysdeps/ieee754/ldbl-128ibm-compat/w_scalbf128.c | 27 +++++++
6 files changed, 204 insertions(+)
create mode 100644 math/e_scalb_template.c
create mode 100644 math/w_scalb_template.c
create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/Makefile
create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/e_scalbf128.c
create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/w_scalbf128.c
new file mode 100644
@@ -0,0 +1,54 @@
+/* Multiply by integral power of radix.
+ Copyright (C) 2018 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>
+
+static FLOAT
+__attribute__ ((noinline))
+invalid_fn (FLOAT x, FLOAT fn)
+{
+ if (M_SUF (__rint) (fn) != fn)
+ return (fn - fn) / (fn - fn);
+ else if (fn > M_LIT (65000.0))
+ return M_SUF (__scalbn) (x, 65000);
+ else
+ return M_SUF (__scalbn) (x,-65000);
+}
+
+
+FLOAT
+M_DECL_FUNC (__ieee754_scalb) (FLOAT x, FLOAT fn)
+{
+ if (__glibc_unlikely (isnan (x)))
+ return x * fn;
+ if (__glibc_unlikely (!isfinite (fn)))
+ {
+ if (isnan (fn) || fn > M_LIT (0.0))
+ return x * fn;
+ if (x == M_LIT (0.0))
+ return x;
+ return x / -fn;
+ }
+ if (__glibc_unlikely (M_FABS (fn) >= M_LIT (0x1p31)
+ || (FLOAT) (int) fn != fn))
+ return invalid_fn (x, fn);
+
+ return M_SCALBN (x, (int) fn);
+}
+declare_mgen_finite_alias (__ieee754_scalb, __scalb)
new file mode 100644
@@ -0,0 +1,95 @@
+/* Wrapper to set errno for scalb.
+ Copyright (C) 2018 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/>. */
+
+/* Only build wrappers from the templates for the types that define the macro
+ below. This macro is set in math-type-macros-<type>.h in sysdeps/generic
+ for each floating-point type. */
+#if __USE_WRAPPER_TEMPLATE
+
+#include <errno.h>
+#include <math.h>
+#include <math_private.h>
+#include <math-svid-compat.h>
+
+#if LIBM_SVID_COMPAT
+static FLOAT
+__attribute__ ((noinline))
+M_DECL_FUNC (sysv_scalb) (FLOAT x, FLOAT fn)
+{
+ FLOAT z = M_SUF (__ieee754_scalb) (x, fn);
+
+ if (__glibc_unlikely (isinf (z)))
+ {
+ if (isfinite (x))
+ {
+ /* scalb overflow. */
+ __set_errno (ERANGE);
+ return x > M_LIT (0.0) ? HUGE_VAL : -HUGE_VAL;
+ }
+ else
+ __set_errno (ERANGE);
+ }
+ else if (__builtin_expect (z == M_LIT (0.0), 0) && z != x)
+ {
+ /* scalb underflow. */
+ __set_errno (ERANGE);
+ return M_LIT (0.0);
+ }
+
+ return z;
+}
+#endif
+
+
+/* Wrapper scalb */
+FLOAT
+M_DECL_FUNC (__scalb) (FLOAT x, FLOAT fn)
+{
+#if LIBM_SVID_COMPAT
+ if (__glibc_unlikely (_LIB_VERSION == _SVID_))
+ return M_SUF (sysv_scalb) (x, fn);
+ else
+#endif
+ {
+ FLOAT z = __ieee754_scalbl (x, fn);
+
+ if (__glibc_unlikely (!isfinite (z) || z == M_LIT (0.0)))
+ {
+ if (isnan (z))
+ {
+ if (!isnan (x) && !isnan (fn))
+ __set_errno (EDOM);
+ }
+ else if (isinf (z))
+ {
+ if (!isinf (x) && !isinf (fn))
+ __set_errno (ERANGE);
+ }
+ else
+ {
+ /* z == 0. */
+ if (x != M_LIT (0.0) && !isinf (fn))
+ __set_errno (ERANGE);
+ }
+ }
+ return z;
+ }
+}
+declare_mgen_alias (__scalb, scalb);
+
+#endif /* __USE_WRAPPER_TEMPLATE. */
new file mode 100644
@@ -0,0 +1,6 @@
+ifeq ($(subdir),math)
+# scalb is a libm-compat-call, so it gets excluded from f128.
+# It's necessary to build it for f128 in order to provide long double symbols
+# based on the f128 implementation.
+libm-routines += w_scalbf128
+endif
@@ -105,6 +105,7 @@ libm {
__rintieee128;
__roundevenieee128;
__roundieee128;
+ __scalbieee128;
__scalblnieee128;
__scalbnieee128;
__setpayloadieee128;
new file mode 100644
@@ -0,0 +1,21 @@
+/* Get mantissa of long double.
+ Copyright (C) 2018 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-type-macros-float128.h>
+
+#include <math/e_scalb_template.c>
new file mode 100644
@@ -0,0 +1,27 @@
+/* Get mantissa of long double.
+ Copyright (C) 2018 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 <float128_private.h>
+#include <math-type-macros-float128.h>
+
+#undef declare_mgen_alias
+#define declare_mgen_alias(a,b)
+#define __ieee754_scalbl __ieee754_scalbf128
+#include <w_scalb_template.c>
+
+libm_alias_float128_other_r_ldbl (__scalb, scalb,)