about summary refs log tree commit diff
path: root/sysdeps/ieee754
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r--sysdeps/ieee754/dbl-64/s_nextup.c58
-rw-r--r--sysdeps/ieee754/flt-32/s_nextupf.c46
-rw-r--r--sysdeps/ieee754/ldbl-128/s_nextupl.c56
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_nextupl.c78
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nextupl.c84
-rw-r--r--sysdeps/ieee754/ldbl-opt/Makefile5
-rw-r--r--sysdeps/ieee754/ldbl-opt/nldbl-nextdown.c27
-rw-r--r--sysdeps/ieee754/ldbl-opt/nldbl-nextup.c27
8 files changed, 380 insertions, 1 deletions
diff --git a/sysdeps/ieee754/dbl-64/s_nextup.c b/sysdeps/ieee754/dbl-64/s_nextup.c
new file mode 100644
index 0000000000..d2432b550b
--- /dev/null
+++ b/sysdeps/ieee754/dbl-64/s_nextup.c
@@ -0,0 +1,58 @@
+/* Return the least floating-point number greater than X.
+   Copyright (C) 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/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+/* Return the least floating-point number greater than X.  */
+double
+__nextup (double x)
+{
+  int32_t hx, ix;
+  u_int32_t lx;
+
+  EXTRACT_WORDS (hx, lx, x);
+  ix = hx & 0x7fffffff;
+
+  if (((ix >= 0x7ff00000) && ((ix - 0x7ff00000) | lx) != 0))  /* x is nan.  */
+    return x + x;
+  if ((ix | lx) == 0)
+    return DBL_TRUE_MIN;
+  if (hx >= 0)
+    {				/* x > 0.  */
+      if (isinf (x))
+        return x;
+      lx += 1;
+      if (lx == 0)
+        hx += 1;
+    }
+  else
+    {				/* x < 0.  */
+      if (lx == 0)
+        hx -= 1;
+      lx -= 1;
+    }
+  INSERT_WORDS (x, hx, lx);
+  return x;
+}
+
+weak_alias (__nextup, nextup)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__nextup, __nextupl)
+weak_alias (__nextup, nextupl)
+#endif
diff --git a/sysdeps/ieee754/flt-32/s_nextupf.c b/sysdeps/ieee754/flt-32/s_nextupf.c
new file mode 100644
index 0000000000..9f3398e02e
--- /dev/null
+++ b/sysdeps/ieee754/flt-32/s_nextupf.c
@@ -0,0 +1,46 @@
+/* Return the least floating-point number greater than X.
+   Copyright (C) 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/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+/* Return the least floating-point number greater than X.  */
+float
+__nextupf (float x)
+{
+  int32_t hx, ix;
+
+  GET_FLOAT_WORD (hx, x);
+  ix = hx & 0x7fffffff;
+  if (ix == 0)
+    return FLT_TRUE_MIN;
+  if (ix > 0x7f800000)		/* x is nan.  */
+    return x + x;
+  if (hx >= 0)
+    {				/* x > 0.  */
+      if (isinf (x))
+        return x;
+      hx += 1;
+    }
+  else
+    hx -= 1;
+  SET_FLOAT_WORD (x, hx);
+  return x;
+}
+
+weak_alias (__nextupf, nextupf)
diff --git a/sysdeps/ieee754/ldbl-128/s_nextupl.c b/sysdeps/ieee754/ldbl-128/s_nextupl.c
new file mode 100644
index 0000000000..3ee47d8090
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/s_nextupl.c
@@ -0,0 +1,56 @@
+/* Return the least floating-point number greater than X.
+   Copyright (C) 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/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+/* Return the least floating-point number greater than X.  */
+long double
+__nextupl (long double x)
+{
+  int64_t hx, ix;
+  u_int64_t lx;
+
+  GET_LDOUBLE_WORDS64 (hx, lx, x);
+  ix = hx & 0x7fffffffffffffffLL;
+
+  /* x is nan.  */
+  if (((ix >= 0x7fff000000000000LL)
+       && ((ix - 0x7fff000000000000LL) | lx) != 0))
+    return x + x;
+  if ((ix | lx) == 0)
+    return LDBL_TRUE_MIN;
+  if (hx >= 0)
+    {				/* x > 0.  */
+      if (isinf (x))
+        return x;
+      lx++;
+      if (lx == 0)
+        hx++;
+    }
+  else
+    {				/* x < 0.  */
+      if (lx == 0)
+        hx--;
+      lx--;
+    }
+  SET_LDOUBLE_WORDS64 (x, hx, lx);
+  return x;
+}
+
+weak_alias (__nextupl, nextupl)
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nextupl.c b/sysdeps/ieee754/ldbl-128ibm/s_nextupl.c
new file mode 100644
index 0000000000..2a4fae7e2e
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nextupl.c
@@ -0,0 +1,78 @@
+/* Return the least floating-point number greater than X.
+   Copyright (C) 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/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <math_ldbl_opt.h>
+
+/* Return the least floating-point number greater than X.  */
+long double
+__nextupl (long double x)
+{
+  int64_t hx, ihx, lx;
+  double xhi, xlo, yhi;
+
+  ldbl_unpack (x, &xhi, &xlo);
+  EXTRACT_WORDS64 (hx, xhi);
+  EXTRACT_WORDS64 (lx, xlo);
+  ihx = hx & 0x7fffffffffffffffLL;
+
+  if (ihx > 0x7ff0000000000000LL)	/* x is nan.  */
+    return x + x;		/* Signal the nan.  */
+  if (ihx == 0)
+    return LDBL_TRUE_MIN;
+
+  long double u;
+  if ((hx == 0x7fefffffffffffffLL) && (lx == 0x7c8ffffffffffffeLL))
+    return INFINITY;
+  if ((uint64_t) hx >= 0xfff0000000000000ULL)
+    {
+      u = -0x1.fffffffffffff7ffffffffffff8p+1023L;
+      return u;
+    }
+  if (ihx <= 0x0360000000000000LL)
+    {				/* x <= LDBL_MIN.  */
+      x += LDBL_TRUE_MIN;
+      if (x == 0.0L)		/* Handle negative LDBL_TRUE_MIN case.  */
+        x = -0.0L;
+      return x;
+    }
+  /* If the high double is an exact power of two and the low
+     double is the opposite sign, then 1ulp is one less than
+     what we might determine from the high double.  Similarly
+     if X is an exact power of two, and negative, because
+     making it a little larger will result in the exponent
+     decreasing by one and normalisation of the mantissa.   */
+  if ((hx & 0x000fffffffffffffLL) == 0
+      && ((lx != 0 && lx != 0x8000000000000000LL && (hx ^ lx) < 0)
+          || ((lx == 0 || lx == 0x8000000000000000LL) && hx < 0)))
+    ihx -= 1LL << 52;
+  if (ihx < (106LL << 52))
+    {				/* ulp will denormal.  */
+      INSERT_WORDS64 (yhi, ihx & (0x7ffLL << 52));
+      u = yhi * 0x1p-105;
+    }
+  else
+    {
+      INSERT_WORDS64 (yhi, (ihx & (0x7ffLL << 52)) - (105LL << 52));
+      u = yhi;
+    }
+  return x + u;
+}
+
+weak_alias (__nextupl, nextupl)
diff --git a/sysdeps/ieee754/ldbl-96/s_nextupl.c b/sysdeps/ieee754/ldbl-96/s_nextupl.c
new file mode 100644
index 0000000000..701842d3e1
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/s_nextupl.c
@@ -0,0 +1,84 @@
+/* Return the least floating-point number greater than X.
+   Copyright (C) 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/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+/* Return the least floating-point number greater than X.  */
+long double
+__nextupl (long double x)
+{
+  u_int32_t hx, ix;
+  u_int32_t lx;
+  int32_t esx;
+
+  GET_LDOUBLE_WORDS (esx, hx, lx, x);
+  ix = esx & 0x7fff;
+
+  if (((ix == 0x7fff) && (((hx & 0x7fffffff) | lx) != 0)))  /* x is nan.  */
+    return x + x;
+  if ((ix | hx | lx) == 0)
+    return LDBL_TRUE_MIN;
+  if (esx >= 0)
+    {				/* x > 0.  */
+      if (isinf (x))
+        return x;
+      lx += 1;
+      if (lx == 0)
+        {
+          hx += 1;
+#if LDBL_MIN_EXP == -16381
+          if (hx == 0 || (esx == 0 && hx == 0x80000000))
+#else
+          if (hx == 0)
+#endif
+          {
+            esx += 1;
+            hx |= 0x80000000;
+          }
+        }
+    }
+  else
+    {				/* x < 0.  */
+      if (lx == 0)
+        {
+#if LDBL_MIN_EXP == -16381
+          if (hx <= 0x80000000 && esx != 0xffff8000)
+            {
+              esx -= 1;
+              hx = hx - 1;
+              if ((esx & 0x7fff) > 0)
+                hx |= 0x80000000;
+            }
+          else
+            hx -= 1;
+#else
+          if (ix != 0 && hx == 0x80000000)
+            hx = 0;
+          if (hx == 0)
+            esx -= 1;
+          hx -= 1;
+#endif
+        }
+      lx -= 1;
+    }
+  SET_LDOUBLE_WORDS (x, esx, hx, lx);
+  return x;
+}
+
+weak_alias (__nextupl, nextupl)
diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile
index 53091e410c..af08209570 100644
--- a/sysdeps/ieee754/ldbl-opt/Makefile
+++ b/sysdeps/ieee754/ldbl-opt/Makefile
@@ -40,7 +40,8 @@ libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
 		 isoc99_scanf isoc99_fscanf isoc99_sscanf \
 		 isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \
 		 isoc99_wscanf isoc99_fwscanf isoc99_swscanf \
-		 isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf
+		 isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf \
+		 nextup nextdown
 libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
 libnldbl-inhibit-o = $(object-suffixes)
 libnldbl-static-only-routines = $(libnldbl-routines)
@@ -120,8 +121,10 @@ CFLAGS-nldbl-modf.c = -fno-builtin-modfl
 CFLAGS-nldbl-nan.c = -fno-builtin-nanl
 CFLAGS-nldbl-nearbyint.c = -fno-builtin-nearbyintl
 CFLAGS-nldbl-nextafter.c = -fno-builtin-nextafterl
+CFLAGS-nldbl-nextdown.c = -fno-builtin-nextdownl
 CFLAGS-nldbl-nexttoward.c = -fno-builtin-nexttoward -fno-builtin-nexttowardl
 CFLAGS-nldbl-nexttowardf.c = -fno-builtin-nexttowardf
+CFLAGS-nldbl-nextup.c = -fno-builtin-nextupl
 CFLAGS-nldbl-pow.c = -fno-builtin-powl
 CFLAGS-nldbl-pow10.c = -fno-builtin-pow10l
 CFLAGS-nldbl-remainder.c = -fno-builtin-remainderl -fno-builtin-dreml
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-nextdown.c b/sysdeps/ieee754/ldbl-opt/nldbl-nextdown.c
new file mode 100644
index 0000000000..3b0047c09d
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-nextdown.c
@@ -0,0 +1,27 @@
+/* Compatibility routine for IEEE double as long double for nextdown.
+   Copyright (C) 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/>.  */
+
+#include "nldbl-compat.h"
+
+/* Return the greatest floating-point number less than X.  */
+double
+attribute_hidden
+nextdownl (double x)
+{
+  return nextdown (x);
+}
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-nextup.c b/sysdeps/ieee754/ldbl-opt/nldbl-nextup.c
new file mode 100644
index 0000000000..b557edffe3
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-nextup.c
@@ -0,0 +1,27 @@
+/* Compatibility routine for IEEE double as long double for nextup.
+   Copyright (C) 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/>.  */
+
+#include "nldbl-compat.h"
+
+/* Return the least floating-point number greater than X.  */
+double
+attribute_hidden
+nextupl (double x)
+{
+  return nextup (x);
+}