]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Merge common usage of mul_split function
authorPaul E. Murphy <murphyp@linux.vnet.ibm.com>
Mon, 8 Aug 2016 20:58:28 +0000 (15:58 -0500)
committerPaul E. Murphy <murphyp@linux.vnet.ibm.com>
Fri, 19 Aug 2016 16:29:43 +0000 (11:29 -0500)
A number of files share identical code for the
mul_split function.

This moves the duplicated function mul_split into its
own header, and refactors the fma usage into a single
selection macro.  Likewise, mul_split when used by a
long double implementation is renamed mul_splitl for
clarity.

14 files changed:
ChangeLog
math/mul_split.h [new file with mode: 0644]
math/mul_splitl.h [new file with mode: 0644]
sysdeps/ieee754/dbl-64/gamma_product.c
sysdeps/ieee754/dbl-64/lgamma_product.c
sysdeps/ieee754/dbl-64/x2y2m1.c
sysdeps/ieee754/ldbl-128/gamma_productl.c
sysdeps/ieee754/ldbl-128/lgamma_productl.c
sysdeps/ieee754/ldbl-128/x2y2m1l.c
sysdeps/ieee754/ldbl-128ibm/s_fmal.c
sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c
sysdeps/ieee754/ldbl-96/gamma_productl.c
sysdeps/ieee754/ldbl-96/lgamma_productl.c
sysdeps/ieee754/ldbl-96/x2y2m1l.c

index a9eb75d926ee7f9a1de57a7f790c02a548ed8880..0b4b5c023acc289152836f2ea48a0b47a84b4bab 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2016-08-19  Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
+
+       * sysdeps/ieee754/ldbl-128/gamma_productl.c:
+       (mul_split) Remove, rename as mul_splitl, remove
+       redundant float.h include, and include via mul_splitl.h
+
+       * sysdeps/ieee754/ldbl-128/lgamma_productl.c: Likewise.
+       * sysdeps/ieee754/ldbl-128/x2y2m1l.c: Likewise.
+       * sysdeps/ieee754/ldbl-96/gamma_product.c: Likewise.
+       * sysdeps/ieee754/ldbl-96/lgamma_product.c: Likewise.
+       * sysdeps/ieee754/ldbl-96/x2y2m1.c: Likewise.
+
+       * math/mul_splitl.h: New file.
+
+       * sysdeps/ieee754/dbl-64/gamma_product.c (mul_split):
+       Move into mul_split.h, and remove redundant float.h include.
+
+       * sysdeps/ieee754/dbl-64/lgamma_product.c: Likewise.
+       * sysdeps/ieee754/dbl-64/x2y2m1.c: Likewise.
+       * sysdeps/ieee754/ldbl-128ibm/s_fmal.c: Likewise.
+       * sysdeps/ieee754/ldbl-128ibm/x2y2m1.c: Likewise.
+
+       * math/mul_split.h: New file.
+
 2016-08-19  Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
 
        * math/Makefile (libm-gen-calls): Move
diff --git a/math/mul_split.h b/math/mul_split.h
new file mode 100644 (file)
index 0000000..85038dc
--- /dev/null
@@ -0,0 +1,50 @@
+/* Compute full X * Y for double type.
+   Copyright (C) 2013-2016 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/>.  */
+
+#ifndef _MUL_SPLIT_H
+#define _MUL_SPLIT_H
+
+#include <float.h>
+
+/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
+   given that the values are small enough that no overflow occurs and
+   large enough (or zero) that no underflow occurs.  */
+
+static void
+mul_split (double *hi, double *lo, double x, double y)
+{
+#ifdef __FP_FAST_FMA
+  /* Fast built-in fused multiply-add.  */
+  *hi = x * y;
+  *lo = __builtin_fma (x, y, -*hi);
+#else
+  /* Apply Dekker's algorithm.  */
+  *hi = x * y;
+# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
+  double x1 = x * C;
+  double y1 = y * C;
+# undef C
+  x1 = (x - x1) + x1;
+  y1 = (y - y1) + y1;
+  double x2 = x - x1;
+  double y2 = y - y1;
+  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
+#endif
+}
+
+#endif /* _MUL_SPLIT_H */
diff --git a/math/mul_splitl.h b/math/mul_splitl.h
new file mode 100644 (file)
index 0000000..8a39ce0
--- /dev/null
@@ -0,0 +1,50 @@
+/* Compute full X * Y for long double type.
+   Copyright (C) 2013-2016 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/>.  */
+
+#ifndef _MUL_SPLITL_H
+#define _MUL_SPLITL_H
+
+#include <float.h>
+
+/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
+   given that the values are small enough that no overflow occurs and
+   large enough (or zero) that no underflow occurs.  */
+
+static inline void
+mul_splitl (long double *hi, long double *lo, long double x, long double y)
+{
+#ifdef __FP_FAST_FMAL
+  /* Fast built-in fused multiply-add.  */
+  *hi = x * y;
+  *lo = __builtin_fmal (x, y, -*hi);
+#else
+  /* Apply Dekker's algorithm.  */
+  *hi = x * y;
+# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
+  long double x1 = x * C;
+  long double y1 = y * C;
+# undef C
+  x1 = (x - x1) + x1;
+  y1 = (y - y1) + y1;
+  long double x2 = x - x1;
+  long double y2 = y - y1;
+  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
+#endif
+}
+
+#endif /* _MUL_SPLITL_H */
index 7ae144aeb3bc43e5150f673ecaa6299f649a9a1d..51407b196c7dc8c8b7fb6bbaeed1d7c19e802013 100644 (file)
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
-
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static void
-mul_split (double *hi, double *lo, double x, double y)
-{
-#ifdef __FP_FAST_FMA
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fma (x, y, -*hi);
-#elif defined FP_FAST_FMA
-  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
-  *hi = x * y;
-  *lo = __fma (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
-  double x1 = x * C;
-  double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  double x2 = x - x1;
-  double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
+#include <mul_split.h>
 
 /* Compute the product of X + X_EPS, X + X_EPS + 1, ..., X + X_EPS + N
    - 1, in the form R * (1 + *EPS) where the return value R is an
index d956575bc7ac9065ec5a9ecd116774b3791209f3..fa89337ebc2467e7825d031193670b2abe00d995 100644 (file)
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
-
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static void
-mul_split (double *hi, double *lo, double x, double y)
-{
-#ifdef __FP_FAST_FMA
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fma (x, y, -*hi);
-#elif defined FP_FAST_FMA
-  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
-  *hi = x * y;
-  *lo = __fma (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
-  double x1 = x * C;
-  double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  double x2 = x - x1;
-  double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
+#include <mul_split.h>
 
 /* Compute the product of 1 + (T / (X + X_EPS)), 1 + (T / (X + X_EPS +
    1)), ..., 1 + (T / (X + X_EPS + N - 1)), minus 1.  X is such that
index 96078888a781e61f3f19ff2c4fa39401e9324389..75052159e14693b50174418a588b2c8090f589c2 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
+#include <mul_split.h>
 #include <stdlib.h>
 
 /* Calculate X + Y exactly and store the result in *HI + *LO.  It is
@@ -33,36 +33,6 @@ add_split (double *hi, double *lo, double x, double y)
   *lo = (x - *hi) + y;
 }
 
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static void
-mul_split (double *hi, double *lo, double x, double y)
-{
-#ifdef __FP_FAST_FMA
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fma (x, y, -*hi);
-#elif defined FP_FAST_FMA
-  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
-  *hi = x * y;
-  *lo = __fma (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
-  double x1 = x * C;
-  double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  double x2 = x - x1;
-  double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
-
 /* Compare absolute values of floating-point values pointed to by P
    and Q for qsort.  */
 
index 849b57d95d112c74cee8ab072e5f856f5dec8d6d..8ad045263b3f11147d8a42a60dd2829d4de06e8f 100644 (file)
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
-
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static inline void
-mul_split (long double *hi, long double *lo, long double x, long double y)
-{
-#ifdef __FP_FAST_FMAL
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fmal (x, y, -*hi);
-#elif defined FP_FAST_FMAL
-  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
-  *hi = x * y;
-  *lo = __fmal (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
-  long double x1 = x * C;
-  long double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  long double x2 = x - x1;
-  long double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
+#include <mul_splitl.h>
 
 /* Compute the product of X + X_EPS, X + X_EPS + 1, ..., X + X_EPS + N
    - 1, in the form R * (1 + *EPS) where the return value R is an
@@ -68,7 +38,7 @@ __gamma_productl (long double x, long double x_eps, int n, long double *eps)
     {
       *eps += x_eps / (x + i);
       long double lo;
-      mul_split (&ret, &lo, ret, x + i);
+      mul_splitl (&ret, &lo, ret, x + i);
       *eps += lo / ret;
     }
   return ret;
index de67cbe665de27dd8887c28af959a6ba0c6807b7..9aa0137fbb2c7acd67ad4324a8e05a8b127c1c2c 100644 (file)
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
-
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static void
-mul_split (long double *hi, long double *lo, long double x, long double y)
-{
-#ifdef __FP_FAST_FMAL
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fmal (x, y, -*hi);
-#elif defined FP_FAST_FMAL
-  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
-  *hi = x * y;
-  *lo = __fmal (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
-  long double x1 = x * C;
-  long double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  long double x2 = x - x1;
-  long double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
+#include <mul_splitl.h>
 
 /* Compute the product of 1 + (T / (X + X_EPS)), 1 + (T / (X + X_EPS +
    1)), ..., 1 + (T / (X + X_EPS + N - 1)), minus 1.  X is such that
@@ -65,11 +35,11 @@ __lgamma_productl (long double t, long double x, long double x_eps, int n)
       long double xi = x + i;
       long double quot = t / xi;
       long double mhi, mlo;
-      mul_split (&mhi, &mlo, quot, xi);
+      mul_splitl (&mhi, &mlo, quot, xi);
       long double quot_lo = (t - mhi - mlo) / xi - t * x_eps / (xi * xi);
       /* We want (1 + RET + RET_EPS) * (1 + QUOT + QUOT_LO) - 1.  */
       long double rhi, rlo;
-      mul_split (&rhi, &rlo, ret, quot);
+      mul_splitl (&rhi, &rlo, ret, quot);
       long double rpq = ret + quot;
       long double rpq_eps = (ret - rpq) + quot;
       long double nret = rpq + rhi;
index 733742da042aa1cdde06f6bfea33d20a7dc3d0b5..4e97885d59ca22cf9f77f81292033cec92684c3d 100644 (file)
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
+#include <mul_splitl.h>
 #include <stdlib.h>
 
+
 /* Calculate X + Y exactly and store the result in *HI + *LO.  It is
    given that |X| >= |Y| and the values are small enough that no
    overflow occurs.  */
@@ -33,36 +34,6 @@ add_split (long double *hi, long double *lo, long double x, long double y)
   *lo = (x - *hi) + y;
 }
 
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static inline void
-mul_split (long double *hi, long double *lo, long double x, long double y)
-{
-#ifdef __FP_FAST_FMAL
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fmal (x, y, -*hi);
-#elif defined FP_FAST_FMAL
-  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
-  *hi = x * y;
-  *lo = __fmal (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
-  long double x1 = x * C;
-  long double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  long double x2 = x - x1;
-  long double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
-
 /* Compare absolute values of floating-point values pointed to by P
    and Q for qsort.  */
 
@@ -88,8 +59,8 @@ __x2y2m1l (long double x, long double y)
 {
   long double vals[5];
   SET_RESTORE_ROUNDL (FE_TONEAREST);
-  mul_split (&vals[1], &vals[0], x, x);
-  mul_split (&vals[3], &vals[2], y, y);
+  mul_splitl (&vals[1], &vals[0], x, x);
+  mul_splitl (&vals[3], &vals[2], y, y);
   vals[4] = -1.0L;
   qsort (vals, 5, sizeof (long double), compare);
   /* Add up the values so that each element of VALS has absolute value
index 177a04817b6d422d672891e531a8155bba75e406..140576315ac7f6f1a936ac6c6463c962cc3f3109 100644 (file)
@@ -22,6 +22,7 @@
 #include <math.h>
 #include <math_private.h>
 #include <math_ldbl_opt.h>
+#include <mul_split.h>
 #include <stdlib.h>
 
 /* Calculate X + Y exactly and store the result in *HI + *LO.  It is
@@ -36,32 +37,6 @@ add_split (double *hi, double *lo, double x, double y)
   *lo = (x - *hi) + y;
 }
 
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static void
-mul_split (double *hi, double *lo, double x, double y)
-{
-#ifdef __FP_FAST_FMA
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fma (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
-  double x1 = x * C;
-  double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  double x2 = x - x1;
-  double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
-
 /* Value with extended range, used in intermediate computations.  */
 typedef struct
 {
index da2e9291755d01aa38f5db1c47089b31574758ee..a8b489530dcc381290a8ac7a831e3543a02b6339 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
+#include <mul_split.h>
 #include <stdlib.h>
 
 /* Calculate X + Y exactly and store the result in *HI + *LO.  It is
@@ -33,36 +33,6 @@ add_split (double *hi, double *lo, double x, double y)
   *lo = (x - *hi) + y;
 }
 
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static inline void
-mul_split (double *hi, double *lo, double x, double y)
-{
-#ifdef __FP_FAST_FMA
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fma (x, y, -*hi);
-#elif defined FP_FAST_FMA
-  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
-  *hi = x * y;
-  *lo = __fma (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
-  double x1 = x * C;
-  double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  double x2 = x - x1;
-  double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
-
 /* Compare absolute values of floating-point values pointed to by P
    and Q for qsort.  */
 
index 849b57d95d112c74cee8ab072e5f856f5dec8d6d..8ad045263b3f11147d8a42a60dd2829d4de06e8f 100644 (file)
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
-
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static inline void
-mul_split (long double *hi, long double *lo, long double x, long double y)
-{
-#ifdef __FP_FAST_FMAL
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fmal (x, y, -*hi);
-#elif defined FP_FAST_FMAL
-  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
-  *hi = x * y;
-  *lo = __fmal (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
-  long double x1 = x * C;
-  long double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  long double x2 = x - x1;
-  long double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
+#include <mul_splitl.h>
 
 /* Compute the product of X + X_EPS, X + X_EPS + 1, ..., X + X_EPS + N
    - 1, in the form R * (1 + *EPS) where the return value R is an
@@ -68,7 +38,7 @@ __gamma_productl (long double x, long double x_eps, int n, long double *eps)
     {
       *eps += x_eps / (x + i);
       long double lo;
-      mul_split (&ret, &lo, ret, x + i);
+      mul_splitl (&ret, &lo, ret, x + i);
       *eps += lo / ret;
     }
   return ret;
index de67cbe665de27dd8887c28af959a6ba0c6807b7..9aa0137fbb2c7acd67ad4324a8e05a8b127c1c2c 100644 (file)
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
-
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static void
-mul_split (long double *hi, long double *lo, long double x, long double y)
-{
-#ifdef __FP_FAST_FMAL
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fmal (x, y, -*hi);
-#elif defined FP_FAST_FMAL
-  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
-  *hi = x * y;
-  *lo = __fmal (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
-  long double x1 = x * C;
-  long double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  long double x2 = x - x1;
-  long double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
+#include <mul_splitl.h>
 
 /* Compute the product of 1 + (T / (X + X_EPS)), 1 + (T / (X + X_EPS +
    1)), ..., 1 + (T / (X + X_EPS + N - 1)), minus 1.  X is such that
@@ -65,11 +35,11 @@ __lgamma_productl (long double t, long double x, long double x_eps, int n)
       long double xi = x + i;
       long double quot = t / xi;
       long double mhi, mlo;
-      mul_split (&mhi, &mlo, quot, xi);
+      mul_splitl (&mhi, &mlo, quot, xi);
       long double quot_lo = (t - mhi - mlo) / xi - t * x_eps / (xi * xi);
       /* We want (1 + RET + RET_EPS) * (1 + QUOT + QUOT_LO) - 1.  */
       long double rhi, rlo;
-      mul_split (&rhi, &rlo, ret, quot);
+      mul_splitl (&rhi, &rlo, ret, quot);
       long double rpq = ret + quot;
       long double rpq_eps = (ret - rpq) + quot;
       long double nret = rpq + rhi;
index 733742da042aa1cdde06f6bfea33d20a7dc3d0b5..b86ba1ce179a1f8b567abc3a0a6ea926cbc57069 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
+#include <mul_splitl.h>
 #include <stdlib.h>
 
 /* Calculate X + Y exactly and store the result in *HI + *LO.  It is
@@ -33,36 +33,6 @@ add_split (long double *hi, long double *lo, long double x, long double y)
   *lo = (x - *hi) + y;
 }
 
-/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
-   given that the values are small enough that no overflow occurs and
-   large enough (or zero) that no underflow occurs.  */
-
-static inline void
-mul_split (long double *hi, long double *lo, long double x, long double y)
-{
-#ifdef __FP_FAST_FMAL
-  /* Fast built-in fused multiply-add.  */
-  *hi = x * y;
-  *lo = __builtin_fmal (x, y, -*hi);
-#elif defined FP_FAST_FMAL
-  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
-  *hi = x * y;
-  *lo = __fmal (x, y, -*hi);
-#else
-  /* Apply Dekker's algorithm.  */
-  *hi = x * y;
-# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
-  long double x1 = x * C;
-  long double y1 = y * C;
-# undef C
-  x1 = (x - x1) + x1;
-  y1 = (y - y1) + y1;
-  long double x2 = x - x1;
-  long double y2 = y - y1;
-  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
-#endif
-}
-
 /* Compare absolute values of floating-point values pointed to by P
    and Q for qsort.  */
 
@@ -88,8 +58,8 @@ __x2y2m1l (long double x, long double y)
 {
   long double vals[5];
   SET_RESTORE_ROUNDL (FE_TONEAREST);
-  mul_split (&vals[1], &vals[0], x, x);
-  mul_split (&vals[3], &vals[2], y, y);
+  mul_splitl (&vals[1], &vals[0], x, x);
+  mul_splitl (&vals[3], &vals[2], y, y);
   vals[4] = -1.0L;
   qsort (vals, 5, sizeof (long double), compare);
   /* Add up the values so that each element of VALS has absolute value