[3/9] ldbl-128ibm-compat: Provide a generic scalb implementation

Message ID 20180606223909.16675-4-tuliom@linux.ibm.com
State New
Headers show
Series
  • Introduce ieee128 symbols and redirections
Related show

Commit Message

Tulio Magno Quites Machado Filho June 6, 2018, 10:39 p.m.
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

Patch

diff --git a/math/e_scalb_template.c b/math/e_scalb_template.c
new file mode 100644
index 0000000000..02663424a7
--- /dev/null
+++ b/math/e_scalb_template.c
@@ -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)
diff --git a/math/w_scalb_template.c b/math/w_scalb_template.c
new file mode 100644
index 0000000000..b42659e561
--- /dev/null
+++ b/math/w_scalb_template.c
@@ -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.  */
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/Makefile b/sysdeps/ieee754/ldbl-128ibm-compat/Makefile
new file mode 100644
index 0000000000..47d2632850
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/Makefile
@@ -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
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/Versions b/sysdeps/ieee754/ldbl-128ibm-compat/Versions
index af6b4b3f60..8133d874df 100644
--- a/sysdeps/ieee754/ldbl-128ibm-compat/Versions
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/Versions
@@ -105,6 +105,7 @@  libm {
     __rintieee128;
     __roundevenieee128;
     __roundieee128;
+    __scalbieee128;
     __scalblnieee128;
     __scalbnieee128;
     __setpayloadieee128;
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/e_scalbf128.c b/sysdeps/ieee754/ldbl-128ibm-compat/e_scalbf128.c
new file mode 100644
index 0000000000..355be95996
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/e_scalbf128.c
@@ -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>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/w_scalbf128.c b/sysdeps/ieee754/ldbl-128ibm-compat/w_scalbf128.c
new file mode 100644
index 0000000000..4094fbfb19
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/w_scalbf128.c
@@ -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,)