This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] Make ilogb C99 compliant


Hi!

ISO C99 explicitely requires that:
ilogb(0) returns FP_ILOGB0 where FP_ILOGB0 is either INT_MIN, or -INT_MAX.
ilogb(NaN) returns FP_ILOGBNAN where FP_ILOGBNAN is either INT_MIN or
INT_MAX.
ilogb(+-Inf) returns INT_MAX.
so we return wrong results on i386 for infinity where FP_ILOGBNAN is
INT_MIN.
The following patch makes sure ilogb(+-Inf) returns INT_MAX (the
non-assembly changes are actually not required, but are there for
completeness and are optimized out).

2001-06-04  Jakub Jelinek  <jakub@redhat.com>

	* math/libm-test.inc (ilogb_test): Test that ilogb(+-Inf) == INT_MAX.
	* sysdeps/i386/fpu/s_ilogb.S (__ilogb): Return INT_MAX for +-Inf.
	* sysdeps/i386/fpu/s_ilogbf.S (__ilogbf): Likewise.
	* sysdeps/i386/fpu/s_ilogbl.S (__ilogbl): Likewise.
	* sysdeps/ieee754/dbl-64/s_ilogb.c (__ilogb): Likewise.
	* sysdeps/ieee754/flt-32/s_ilogbf.c (__ilogbf): Likewise.
	* sysdeps/ieee754/ldbl-128/s_ilogbl.c (__ilogbl): Likewise.
	* sysdeps/ieee754/ldbl-96/s_ilogbl.c (__ilogbl): Likewise.

--- libc/math/libm-test.inc.jj	Mon Jun  4 10:01:59 2001
+++ libc/math/libm-test.inc	Mon Jun  4 12:54:26 2001
@@ -120,6 +120,7 @@
 #include <math.h>
 #include <float.h>
 #include <fenv.h>
+#include <limits.h>
 
 #include <errno.h>
 #include <stdlib.h>
@@ -2800,6 +2801,8 @@ ilogb_test (void)
 
   TEST_f_i (ilogb, 0.0, FP_ILOGB0, EXCEPTIONS_OK);
   TEST_f_i (ilogb, nan_value, FP_ILOGBNAN, EXCEPTIONS_OK);
+  TEST_f_i (ilogb, plus_infty, INT_MAX, EXCEPTIONS_OK);
+  TEST_f_i (ilogb, minus_infty, INT_MAX, EXCEPTIONS_OK);
 
   END (ilogb);
 }
--- libc/sysdeps/i386/fpu/s_ilogb.S.jj	Wed Jul 14 01:34:41 1999
+++ libc/sysdeps/i386/fpu/s_ilogb.S	Mon Jun  4 12:48:24 2001
@@ -9,6 +9,16 @@ RCSID("$NetBSD: s_ilogb.S,v 1.5 1995/10/
 
 ENTRY(__ilogb)
 	fldl	4(%esp)
+/* I added the following ugly construct because ilogb(+-Inf) is
+   required to return INT_MAX in ISO C99.
+   -- jakub@redhat.com.  */
+	fxam			/* Is NaN or +-Inf?  */
+	fstsw   %ax
+	movb    $0x45, %dh
+	andb    %ah, %dh
+	cmpb    $0x05, %dh
+	je      1f		/* Is +-Inf, jump.  */
+
 	fxtract
 	pushl	%eax
 	fstp	%st
@@ -17,6 +27,10 @@ ENTRY(__ilogb)
 	fwait
 	popl	%eax
 
+	ret
+
+1:	fstp	%st
+	movl	$0x7fffffff, %eax
 	ret
 END (__ilogb)
 weak_alias (__ilogb, ilogb)
--- libc/sysdeps/i386/fpu/s_ilogbl.S.jj	Wed Jul 14 01:34:48 1999
+++ libc/sysdeps/i386/fpu/s_ilogbl.S	Mon Jun  4 12:50:35 2001
@@ -10,6 +10,16 @@ RCSID("$NetBSD: $")
 
 ENTRY(__ilogbl)
 	fldt	4(%esp)
+/* I added the following ugly construct because ilogb(+-Inf) is
+   required to return INT_MAX in ISO C99.
+   -- jakub@redhat.com.  */
+	fxam			/* Is NaN or +-Inf?  */
+	fstsw   %ax
+	movb    $0x45, %dh
+	andb    %ah, %dh
+	cmpb    $0x05, %dh
+	je      1f		/* Is +-Inf, jump.  */
+
 	fxtract
 	pushl	%eax
 	fstp	%st
@@ -18,6 +28,10 @@ ENTRY(__ilogbl)
 	fwait
 	popl	%eax
 
+	ret
+
+1:	fstp	%st
+	movl	$0x7fffffff, %eax
 	ret
 END (__ilogbl)
 weak_alias (__ilogbl, ilogbl)
--- libc/sysdeps/i386/fpu/s_ilogbf.S.jj	Wed Jul 14 01:34:45 1999
+++ libc/sysdeps/i386/fpu/s_ilogbf.S	Mon Jun  4 12:50:27 2001
@@ -9,6 +9,16 @@ RCSID("$NetBSD: s_ilogbf.S,v 1.4 1995/10
 
 ENTRY(__ilogbf)
 	flds	4(%esp)
+/* I added the following ugly construct because ilogb(+-Inf) is
+   required to return INT_MAX in ISO C99.
+   -- jakub@redhat.com.  */
+	fxam			/* Is NaN or +-Inf?  */
+	fstsw   %ax
+	movb    $0x45, %dh
+	andb    %ah, %dh
+	cmpb    $0x05, %dh
+	je      1f		/* Is +-Inf, jump.  */
+
 	fxtract
 	pushl	%eax
 	fstp	%st
@@ -17,6 +27,10 @@ ENTRY(__ilogbf)
 	fwait
 	popl	%eax
 
+	ret
+
+1:	fstp	%st
+	movl	$0x7fffffff, %eax
 	ret
 END (__ilogbf)
 weak_alias (__ilogbf, ilogbf)
--- libc/sysdeps/ieee754/dbl-64/s_ilogb.c.jj	Wed Jul 14 01:52:14 1999
+++ libc/sysdeps/ieee754/dbl-64/s_ilogb.c	Mon Jun  4 12:26:17 2001
@@ -16,10 +16,12 @@ static char rcsid[] = "$NetBSD: s_ilogb.
 
 /* ilogb(double x)
  * return the binary exponent of non-zero x
- * ilogb(0) = 0x80000001
- * ilogb(inf/NaN) = 0x7fffffff (no signal is raised)
+ * ilogb(0) = FP_ILOGB0
+ * ilogb(NaN) = FP_ILOGBNAN (no signal is raised)
+ * ilogb(+-Inf) = INT_MAX (no signal is raised)
  */
 
+#include <limits.h>
 #include "math.h"
 #include "math_private.h"
 
@@ -47,7 +49,13 @@ static char rcsid[] = "$NetBSD: s_ilogb.
 	    return ix;
 	}
 	else if (hx<0x7ff00000) return (hx>>20)-1023;
-	else return FP_ILOGBNAN;
+	else if (FP_ILOGBNAN != INT_MAX) {
+	    /* ISO C99 requires ilogb(+-Inf) == INT_MAX.  */
+	    GET_LOW_WORD(lx,x);
+	    if(((hx^0x7ff00000)|lx) == 0)
+		return INT_MAX;
+	}
+	return FP_ILOGBNAN;
 }
 weak_alias (__ilogb, ilogb)
 #ifdef NO_LONG_DOUBLE
--- libc/sysdeps/ieee754/flt-32/s_ilogbf.c.jj	Wed Jul 14 02:01:28 1999
+++ libc/sysdeps/ieee754/flt-32/s_ilogbf.c	Mon Jun  4 12:32:43 2001
@@ -17,6 +17,7 @@
 static char rcsid[] = "$NetBSD: s_ilogbf.c,v 1.4 1995/05/10 20:47:31 jtc Exp $";
 #endif
 
+#include <limits.h>
 #include "math.h"
 #include "math_private.h"
 
@@ -39,6 +40,11 @@ static char rcsid[] = "$NetBSD: s_ilogbf
 	    return ix;
 	}
 	else if (hx<0x7f800000) return (hx>>23)-127;
-	else return FP_ILOGBNAN;
+	else if (FP_ILOGBNAN != INT_MAX) {
+	    /* ISO C99 requires ilogbf(+-Inf) == INT_MAX.  */
+	    if (hx==0x7f800000)
+		return INT_MAX;
+	}
+	return FP_ILOGBNAN;
 }
 weak_alias (__ilogbf, ilogbf)
--- libc/sysdeps/ieee754/ldbl-128/s_ilogbl.c.jj	Wed Jul 14 02:08:52 1999
+++ libc/sysdeps/ieee754/ldbl-128/s_ilogbl.c	Mon Jun  4 12:38:18 2001
@@ -19,8 +19,9 @@ static char rcsid[] = "$NetBSD: $";
 
 /* ilogbl(long double x)
  * return the binary exponent of non-zero x
- * ilogbl(0) = 0x80000001
- * ilogbl(inf/NaN) = 0x7fffffff (no signal is raised)
+ * ilogbl(0) = FP_ILOGB0
+ * ilogbl(NaN) = FP_ILOGBNAN (no signal is raised)
+ * ilogbl(+-Inf) = INT_MAX (no signal is raised)
  */
 
 #include "math.h"
@@ -50,6 +51,11 @@ static char rcsid[] = "$NetBSD: $";
 	    return ix;
 	}
 	else if (hx<0x7fff000000000000LL) return (hx>>48)-0x3fff;
-	else return FP_ILOGBNAN;
+	else if (FP_ILOGBNAN != INT_MAX) {
+	    /* ISO C99 requires ilogbl(+-Inf) == INT_MAX.  */
+	    if (((hx^0x7fff000000000000LL)|lx) == 0)
+		return INT_MAX;
+	}
+	return FP_ILOGBNAN;
 }
 weak_alias (__ilogbl, ilogbl)
--- libc/sysdeps/ieee754/ldbl-96/s_ilogbl.c.jj	Wed Jul 14 02:13:51 1999
+++ libc/sysdeps/ieee754/ldbl-96/s_ilogbl.c	Mon Jun  4 12:35:43 2001
@@ -20,10 +20,12 @@ static char rcsid[] = "$NetBSD: $";
 
 /* ilogbl(long double x)
  * return the binary exponent of non-zero x
- * ilogbl(0) = 0x80000001
- * ilogbl(inf/NaN) = 0x7fffffff (no signal is raised)
+ * ilogbl(0) = FP_ILOGB0
+ * ilogbl(NaN) = FP_ILOGBNAN (no signal is raised)
+ * ilogbl(+-Inf) = INT_MAX (no signal is raised)
  */
 
+#include <limits.h>
 #include "math.h"
 #include "math_private.h"
 
@@ -51,6 +53,9 @@ static char rcsid[] = "$NetBSD: $";
 	    return ix;
 	}
 	else if (es<0x7fff) return es-0x3fff;
-	else return FP_ILOGBNAN;
+	else if (FP_ILOGBNAN != INT_MAX && (hx|lx) == 0)
+	    /* ISO C99 requires ilogbl(+-Inf) == INT_MAX.  */
+	    return INT_MAX;
+	return FP_ILOGBNAN;
 }
 weak_alias (__ilogbl, ilogbl)

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]