aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/s_nexttowardf.c2
-rw-r--r--sysdeps/i386/fpu/s_nextafterl.c8
-rw-r--r--sysdeps/i386/fpu/s_nexttoward.c101
-rw-r--r--sysdeps/i386/fpu/s_nexttowardf.c81
-rw-r--r--sysdeps/ia64/fpu/s_nexttoward.c1
-rw-r--r--sysdeps/ia64/fpu/s_nexttowardf.c1
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nextafterl.c6
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nexttoward.c4
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nexttowardf.c6
9 files changed, 197 insertions, 13 deletions
diff --git a/sysdeps/generic/s_nexttowardf.c b/sysdeps/generic/s_nexttowardf.c
index f99b503f4e..1b3a2536ba 100644
--- a/sysdeps/generic/s_nexttowardf.c
+++ b/sysdeps/generic/s_nexttowardf.c
@@ -39,7 +39,7 @@
ix = hx&0x7fffffff; /* |x| */
iy = hy&0x7fffffff; /* |y| */
- if((ix>=0x7f800000) || /* x is nan */
+ if((ix>0x7f800000) || /* x is nan */
((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */
return x+y;
if((long double) x==y) return y; /* x=y, return y */
diff --git a/sysdeps/i386/fpu/s_nextafterl.c b/sysdeps/i386/fpu/s_nextafterl.c
index 82a0190ca6..a6ead79221 100644
--- a/sysdeps/i386/fpu/s_nextafterl.c
+++ b/sysdeps/i386/fpu/s_nextafterl.c
@@ -45,10 +45,10 @@ static char rcsid[] = "$NetBSD: $";
ix = esx&0x7fff; /* |x| */
iy = esy&0x7fff; /* |y| */
- /* The additional &hx/&hy is required because Intel's extended format
- has the normally implicit 1 explicit present. Sigh! */
- if(((ix==0x7fff)&&(((hx|lx)|-(hx|lx))&hx)>>31!=0) || /* x is nan */
- ((iy==0x7fff)&&(((hy|ly)|-(hy|ly))&hy)>>31!=0)) /* y is nan */
+ /* Intel's extended format has the normally implicit 1 explicit
+ present. Sigh! */
+ if(((ix==0x7fff)&&((hx&0x7fffffff|lx)!=0)) || /* x is nan */
+ ((iy==0x7fff)&&((hy&0x7fffffff|ly)!=0))) /* y is nan */
return x+y;
if(x==y) return y; /* x=y, return y */
if((ix|hx|lx)==0) { /* x == 0 */
diff --git a/sysdeps/i386/fpu/s_nexttoward.c b/sysdeps/i386/fpu/s_nexttoward.c
new file mode 100644
index 0000000000..6b18df1532
--- /dev/null
+++ b/sysdeps/i386/fpu/s_nexttoward.c
@@ -0,0 +1,101 @@
+/* s_nexttoward.c
+ * Special i387 version
+ * Conversion from s_nextafter.c by Ulrich Drepper, Cygnus Support,
+ * drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* IEEE functions
+ * nexttoward(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __nexttoward(double x, long double y)
+#else
+ double __nexttoward(x,y)
+ double x;
+ long double y;
+#endif
+{
+ int32_t hx,ix,iy;
+ u_int32_t lx,hy,ly,esy;
+
+ EXTRACT_WORDS(hx,lx,x);
+ GET_LDOUBLE_WORDS(esy,hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = esy&0x7fff; /* |y| */
+
+ /* Intel's extended format has the normally implicit 1 explicit
+ present. Sigh! */
+ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
+ ((iy>=0x7fff)&&((hy&0x7fffffff)|ly)!=0)) /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if((ix|lx)==0) { /* x == 0 */
+ double x2;
+ INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00
+ || (((ix>>20)&0x7ff)==iy-0x3c00
+ && (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
+ || (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
+ && (lx<<11)>ly)))) { /* x > y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x < y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ } else { /* x < 0 */
+ if (esy<0x8000||((ix>>20)&0x7ff)>iy-0x3c00
+ || (((ix>>20)&0x7ff)==iy-0x3c00
+ && (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
+ || (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
+ && (lx<<11)>ly)))) {/* x < y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x > y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ }
+ hy = hx&0x7ff00000;
+ if(hy>=0x7ff00000) return x+x; /* overflow */
+ if(hy<0x00100000) { /* underflow */
+ double x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ INSERT_WORDS(x2,hx,lx);
+ return x2;
+ }
+ }
+ INSERT_WORDS(x,hx,lx);
+ return x;
+}
+weak_alias (__nexttoward, nexttoward)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__nexttoward, __nexttowardl)
+weak_alias (__nexttoward, nexttowardl)
+#endif
diff --git a/sysdeps/i386/fpu/s_nexttowardf.c b/sysdeps/i386/fpu/s_nexttowardf.c
new file mode 100644
index 0000000000..150641f335
--- /dev/null
+++ b/sysdeps/i386/fpu/s_nexttowardf.c
@@ -0,0 +1,81 @@
+/* s_nexttowardf.c -- float version of s_nextafter.c.
+ * Special i387 version.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __nexttowardf(float x, long double y)
+#else
+ float __nexttowardf(x,y)
+ float x;
+ long double y;
+#endif
+{
+ int32_t hx,ix,iy;
+ u_int32_t hy,ly,esy;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_LDOUBLE_WORDS(esy,hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = esy&0x7fff; /* |y| */
+
+ /* Intel's extended format has the normally implicit 1 explicit
+ present. Sigh! */
+ if((ix>0x7f800000) || /* x is nan */
+ (iy>=0x7fff&&(((hy&0x7fffffff)|ly)!=0))) /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if(ix==0) { /* x == 0 */
+ float x2;
+ SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80
+ || (((ix>>23)&0xff)==iy-0x3f80
+ && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x > y, x -= ulp */
+ hx -= 1;
+ } else { /* x < y, x += ulp */
+ hx += 1;
+ }
+ } else { /* x < 0 */
+ if(esy<0x8000||((ix>>23)&0xff)>iy-0x3f80
+ || (((ix>>23)&0xff)==iy-0x3f80
+ && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x < y, x -= ulp */
+ hx -= 1;
+ } else { /* x > y, x += ulp */
+ hx += 1;
+ }
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) return x+x; /* overflow */
+ if(hy<0x00800000) { /* underflow */
+ float x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ SET_FLOAT_WORD(x2,hx);
+ return x2;
+ }
+ }
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
+weak_alias (__nexttowardf, nexttowardf)
diff --git a/sysdeps/ia64/fpu/s_nexttoward.c b/sysdeps/ia64/fpu/s_nexttoward.c
new file mode 100644
index 0000000000..aee2bb5895
--- /dev/null
+++ b/sysdeps/ia64/fpu/s_nexttoward.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/fpu/s_nexttoward.c>
diff --git a/sysdeps/ia64/fpu/s_nexttowardf.c b/sysdeps/ia64/fpu/s_nexttowardf.c
new file mode 100644
index 0000000000..55e95f6916
--- /dev/null
+++ b/sysdeps/ia64/fpu/s_nexttowardf.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/fpu/s_nexttowardf.c>
diff --git a/sysdeps/ieee754/ldbl-96/s_nextafterl.c b/sysdeps/ieee754/ldbl-96/s_nextafterl.c
index aea57e3086..bcbc3049dc 100644
--- a/sysdeps/ieee754/ldbl-96/s_nextafterl.c
+++ b/sysdeps/ieee754/ldbl-96/s_nextafterl.c
@@ -43,12 +43,12 @@ static char rcsid[] = "$NetBSD: $";
ix = esx&0x7fff; /* |x| */
iy = esy&0x7fff; /* |y| */
- if(((ix==0x7fff)&&((hx|lx)|-(hx|lx))!=0) || /* x is nan */
- ((iy==0x7fff)&&((hy|ly)|-(hy|ly))!=0)) /* y is nan */
+ if(((ix==0x7fff)&&((hx|lx)!=0) || /* x is nan */
+ ((iy==0x7fff)&&((hy|ly)!=0)) /* y is nan */
return x+y;
if(x==y) return y; /* x=y, return y */
if((ix|hx|lx)==0) { /* x == 0 */
- SET_LDOUBLE_WORDS(x,esx&0x8000,0,1);/* return +-minsubnormal */
+ SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
y = x*x;
if(y==x) return y; else return x; /* raise underflow flag */
}
diff --git a/sysdeps/ieee754/ldbl-96/s_nexttoward.c b/sysdeps/ieee754/ldbl-96/s_nexttoward.c
index 9df393a7bd..c29bcd146d 100644
--- a/sysdeps/ieee754/ldbl-96/s_nexttoward.c
+++ b/sysdeps/ieee754/ldbl-96/s_nexttoward.c
@@ -45,12 +45,12 @@ static char rcsid[] = "$NetBSD: $";
iy = esy&0x7fff; /* |y| */
if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
- ((iy>=0x7fff)&&((hy|ly)|-(hy|ly))!=0)) /* y is nan */
+ ((iy>=0x7fff)&&(hy|ly)!=0)) /* y is nan */
return x+y;
if((long double) x==y) return y; /* x=y, return y */
if((ix|lx)==0) { /* x == 0 */
double x2;
- INSERT_WORDS(x,esy&0x8000?0x80000000:0,1);/* return +-minsub */
+ INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
x2 = x*x;
if(x2==x) return x2; else return x; /* raise underflow flag */
}
diff --git a/sysdeps/ieee754/ldbl-96/s_nexttowardf.c b/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
index b7e9f00185..a1c38b5d4c 100644
--- a/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
+++ b/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
@@ -36,13 +36,13 @@ static char rcsid[] = "$NetBSD: $";
ix = hx&0x7fffffff; /* |x| */
iy = esy&0x7fff; /* |y| */
- if((ix>0x7f800000) || /* x is nan */
- (iy>=0x7fff&&((hy|ly)|-(hy|ly))!=0)) /* y is nan */
+ if((ix>0x7f800000) || /* x is nan */
+ (iy>=0x7fff&&((hy|ly)!=0))) /* y is nan */
return x+y;
if((long double) x==y) return y; /* x=y, return y */
if(ix==0) { /* x == 0 */
float x2;
- SET_FLOAT_WORD(x,(esy&0x8000?0x80000000:0)|1);/* return +-minsub*/
+ SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
x2 = x*x;
if(x2==x) return x2; else return x; /* raise underflow flag */
}