This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Fix ilogb exception and errno (bug 6794)
- From: Adhemerval Zanella <azanella at linux dot vnet dot ibm dot com>
- To: "GNU C. Library" <libc-alpha at sourceware dot org>
- Date: Wed, 11 Apr 2012 16:30:13 -0300
- Subject: [PATCH] Fix ilogb exception and errno (bug 6794)
Following Joseph comments about bug 6794, here is a proposed fix. It turned out
to be a large fix mainly because I had to move some file along to follow libm
files/names conventions.
Basically I have added wrappers (w_ilogb.c, w_ilogbf.c, w_ilogbl.c) that now calls
the symbol '__ieee754_ilogb'. The wrappers checks for '__ieee754_ilogb' output and
set the errno and raise exceptions as expected.
The '__ieee754_ilogb' is implemented in sysdeps. I have moved the 's_ilogb[f|l]' files
to e_ilogb[f|l] and renamed the '__ilogb[f|l]' to '__ieee754_ilogb[f|l]'.
I also found out a bug in i386 and x86-64 assembly coded ilogb implementation where
it raises a FE_DIVBYZERO when argument is '0.0'. I corrected this issue as well.
Finally I added the errno and FE_INVALID tests for 0.0, NaN and +-InF argument. Tested
on i386, x86-64, ppc32 and ppc64.
---
2012-04-11 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
[BZ #6794]
* math/Makefile: Add e_ilogb and w_ilogb, remove s_logb.
* math/libm-test.inc: Add ilogb errno and exception tests.
* math/w_ilogb.c: New file: ilogb wrapper.
* math/w_ilogbf.c: New file: ilogbf wrapper.
* math/w_ilogbl.c: New file: ilogbl wrapper.
* sysdeps/generic/math_private.h: Add __ieee754_ilogb[l|f] prototypes.
* sysdeps/i386/fpu/s_ilogb.S: Moved to ...
* sysdeps/i386/fpu/e_ilogb.S: ... here. Also fixed a FE_DIVBYZERO
exception being thrown with 0.0 as argument.
* sysdeps/i386/fpu/s_ilogbf.S: Moved to ...
* sysdeps/i386/fpu/e_ilogbf.S: ... here. Also fixed a FE_DIVBYZERO
exception being thrown with 0.0 as argument.
* sysdeps/i386/fpu/s_ilogbl.S: Moved to ...
* sysdeps/i386/fpu/e_ilogbl.S: ... here. Also fixed a FE_DIVBYZERO
exception being thrown with 0.0 as argument.
* sysdeps/x86_64/fpu/s_ilogbl.S: Moved to ...
* sysdeps/x86_64/fpu/e_ilogbl.S: ... here. Also fixed a FE_DIVBYZERO
exception being thrown with 0.0 as argument.
* sysdeps/ieee754/dbl-64/s_ilogb.c: Moved to ...
* sysdeps/ieee754/dbl-64/e_ilogb.c: ... here.
* sysdeps/ieee754/flt-32/e_ilogbf.c: Moved to ...
* sysdeps/ieee754/flt-32/e_ilogbf.c: ... here.
* sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c: Moved to ...
* sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c: ... here.
* sysdeps/ieee754/ldbl-opt/s_ilogb.c: Moved to ...
* sysdeps/ieee754/ldbl-opt/w_ilogb.c: ... here.
* sysdeps/ieee754/ldbl-opt/w_ilogbl.c: New file: ilogbl wrapper.
diff --git a/math/Makefile b/math/Makefile
index 3a671aa..abeba7a 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -42,14 +42,16 @@ libm-support = k_standard s_lib_version s_matherr s_signgam \
libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod \
e_hypot e_j0 e_j1 e_jn e_lgamma_r e_log e_log10 e_pow \
e_rem_pio2 e_remainder e_scalb e_sinh e_sqrt e_gamma_r \
+ e_ilogb \
k_cos k_rem_pio2 k_sin k_tan s_asinh s_atan s_cbrt \
s_ceil s_cos s_erf s_expm1 s_fabs \
- s_floor s_ilogb s_log1p s_logb \
+ s_floor s_log1p s_logb \
s_nextafter s_nexttoward s_rint s_scalbln \
s_significand s_sin s_tan s_tanh w_acos w_acosh w_asin \
w_atan2 w_atanh w_cosh w_drem w_exp w_exp2 w_exp10 w_fmod \
w_tgamma w_hypot w_j0 w_j1 w_jn w_lgamma w_lgamma_r \
w_log w_log10 w_pow w_remainder w_scalb w_sinh w_sqrt \
+ w_ilogb \
s_fpclassify s_fmax s_fmin s_fdim s_nan s_trunc \
s_remquo e_log2 e_exp2 s_round s_nearbyint s_sincos \
conj cimag creal cabs carg s_cexp s_csinh s_ccosh s_clog \
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 2809d57..94d60bf 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -3802,13 +3802,22 @@ ilogb_test (void)
TEST_f_i (ilogb, 1024, 10);
TEST_f_i (ilogb, -2000, 10);
- /* XXX We have a problem here: the standard does not tell us whether
- exceptions are allowed/required. ignore them for now. */
-
- 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);
+ /* ilogb (0.0) == FP_ILOGB0 plus invalid exception */
+ errno = 0;
+ TEST_f_i (ilogb, 0.0, FP_ILOGB0, INVALID_EXCEPTION);
+ check_int ("errno for ilogb(0.0) unchanged", errno, EDOM, 0, 0, 0);
+ /* ilogb (NaN) == FP_ILOGBNAN plus invalid exception */
+ errno = 0;
+ TEST_f_i (ilogb, nan_value, FP_ILOGBNAN, INVALID_EXCEPTION);
+ check_int ("errno for ilogb(NaN) unchanged", errno, EDOM, 0, 0, 0);
+ /* ilogb (inf) == INT_MAX plus invalid exception */
+ errno = 0;
+ TEST_f_i (ilogb, plus_infty, INT_MAX, INVALID_EXCEPTION);
+ check_int ("errno for ilogb(Inf) unchanged", errno, EDOM, 0, 0, 0);
+ /* ilogb (-inf) == INT_MAX plus invalid exception */
+ errno = 0;
+ TEST_f_i (ilogb, minus_infty, INT_MAX, INVALID_EXCEPTION);
+ check_int ("errno for ilogb(-Inf) unchanged", errno, EDOM, 0, 0, 0);
END (ilogb);
}
diff --git a/math/w_ilogb.c b/math/w_ilogb.c
new file mode 100644
index 0000000..c87b517
--- /dev/null
+++ b/math/w_ilogb.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Adhemerval Zanella <azanella@linux.vnet.ibm.com>, 2011.
+
+ 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 <errno.h>
+#include <math_private.h>
+
+/* wrapper ilogb */
+int
+__ilogb (double x)
+{
+ int r = __ieee754_ilogb (x);
+ if (__builtin_expect (r == FP_ILOGB0, 0)
+ || __builtin_expect (r == FP_ILOGBNAN, 0)
+ || __builtin_expect (r == INT_MAX, 0))
+ {
+ __set_errno (EDOM);
+ feraiseexcept (FE_INVALID);
+ }
+ return r;
+}
+
+weak_alias (__ilogb, ilogb)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__ilogb, __ilogbl)
+weak_alias (__ilogb, ilogbl)
+#endif
diff --git a/math/w_ilogbf.c b/math/w_ilogbf.c
new file mode 100644
index 0000000..ae3574a
--- /dev/null
+++ b/math/w_ilogbf.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Adhemerval Zanella <azanella@linux.vnet.ibm.com>, 2011.
+
+ 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 <errno.h>
+#include <math_private.h>
+
+/* wrapper ilogbf */
+int
+__ilogbf (float x)
+{
+ int r = __ieee754_ilogbf (x);
+ if (__builtin_expect (r == FP_ILOGB0, 0)
+ || __builtin_expect (r == FP_ILOGBNAN, 0)
+ || __builtin_expect (r == INT_MAX, 0))
+ {
+ __set_errno (EDOM);
+ feraiseexcept (FE_INVALID);
+ }
+ return r;
+}
+
+weak_alias (__ilogbf, ilogbf)
diff --git a/math/w_ilogbl.c b/math/w_ilogbl.c
new file mode 100644
index 0000000..8c30caa
--- /dev/null
+++ b/math/w_ilogbl.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Adhemerval Zanella <azanella@linux.vnet.ibm.com>, 2011.
+
+ 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 <errno.h>
+#include <math_private.h>
+
+/* wrapper ilogbl */
+int
+__ilogbl (long double x)
+{
+ int r = __ieee754_ilogbl (x);
+ if (__builtin_expect (r == FP_ILOGB0, 0)
+ || __builtin_expect (r == FP_ILOGBNAN, 0)
+ || __builtin_expect (r == INT_MAX, 0))
+ {
+ __set_errno (EDOM);
+ feraiseexcept (FE_INVALID);
+ }
+ return r;
+}
+weak_alias (__ilogbl, ilogbl)
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h
index e217224..5267ec3 100644
--- a/sysdeps/generic/math_private.h
+++ b/sysdeps/generic/math_private.h
@@ -213,6 +213,7 @@ extern double __ieee754_yn (int,double);
extern double __ieee754_remainder (double,double);
extern int32_t __ieee754_rem_pio2 (double,double*);
extern double __ieee754_scalb (double,double);
+extern int __ieee754_ilogb (double);
/* fdlibm kernel function */
extern double __kernel_standard (double,double,int);
@@ -260,6 +261,7 @@ extern float __ieee754_ynf (int,float);
extern float __ieee754_remainderf (float,float);
extern int32_t __ieee754_rem_pio2f (float,float*);
extern float __ieee754_scalbf (float,float);
+extern int __ieee754_ilogbf (float);
/* float versions of fdlibm kernel functions */
@@ -305,6 +307,7 @@ extern long double __ieee754_ynl (int,long double);
extern long double __ieee754_remainderl (long double,long double);
extern int __ieee754_rem_pio2l (long double,long double*);
extern long double __ieee754_scalbl (long double,long double);
+extern int __ieee754_ilogbl (long double);
/* long double versions of fdlibm kernel functions */
extern long double __kernel_sinl (long double,long double,int);
diff --git a/sysdeps/i386/fpu/e_ilogb.S b/sysdeps/i386/fpu/e_ilogb.S
new file mode 100644
index 0000000..4fb6350
--- /dev/null
+++ b/sysdeps/i386/fpu/e_ilogb.S
@@ -0,0 +1,43 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ilogb.S,v 1.5 1995/10/12 15:53:09 jtc Exp $")
+
+ENTRY(__ieee754_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. */
+ cmpb $0x40, %dh
+ je 2f /* Is +-0, jump. */
+
+ fxtract
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ fstp %st
+
+ fistpl (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+
+ ret
+
+1: fstp %st
+ movl $0x7fffffff, %eax
+ ret
+2: fstp %st
+ movl $0x80000000, %eax /* FP_ILOGB0 */
+ ret
+END (__ieee754_ilogb)
+weak_alias (__ieee754_ilogb, __ilogb_finite)
diff --git a/sysdeps/i386/fpu/e_ilogbf.S b/sysdeps/i386/fpu/e_ilogbf.S
new file mode 100644
index 0000000..fbb50be
--- /dev/null
+++ b/sysdeps/i386/fpu/e_ilogbf.S
@@ -0,0 +1,43 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ilogbf.S,v 1.4 1995/10/22 20:32:43 pk Exp $")
+
+ENTRY(__ieee754_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. */
+ cmpb $0x40, %dh
+ je 2f /* Is +-0, jump. */
+
+ fxtract
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ fstp %st
+
+ fistpl (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+
+ ret
+
+1: fstp %st
+ movl $0x7fffffff, %eax
+ ret
+2: fstp %st
+ movl $0x80000000, %eax /* FP_ILOGB0 */
+ ret
+END (__ieee754_ilogbf)
+weak_alias (__ieee754_ilogbf, __ilogbf_finite)
diff --git a/sysdeps/i386/fpu/e_ilogbl.S b/sysdeps/i386/fpu/e_ilogbl.S
new file mode 100644
index 0000000..6e2be9a
--- /dev/null
+++ b/sysdeps/i386/fpu/e_ilogbl.S
@@ -0,0 +1,44 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ieee754_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. */
+ cmpb $0x40, %dh
+ je 2f /* Is +-0, jump. */
+
+ fxtract
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ fstp %st
+
+ fistpl (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+
+ ret
+
+1: fstp %st
+ movl $0x7fffffff, %eax
+ ret
+2: fstp %st
+ movl $0x80000000, %eax /* FP_ILOGB0 */
+ ret
+END (__ieee754_ilogbl)
+weak_alias (__ieee754_ilogbl, __ilogbl_finite)
diff --git a/sysdeps/i386/fpu/s_ilogb.S b/sysdeps/i386/fpu/s_ilogb.S
deleted file mode 100644
index 0cf1ad7..0000000
--- a/sysdeps/i386/fpu/s_ilogb.S
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Written by J.T. Conklin <jtc@netbsd.org>.
- * Public domain.
- */
-
-#include <machine/asm.h>
-
-RCSID("$NetBSD: s_ilogb.S,v 1.5 1995/10/12 15:53:09 jtc Exp $")
-
-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
- cfi_adjust_cfa_offset (4)
- fstp %st
-
- fistpl (%esp)
- fwait
- popl %eax
- cfi_adjust_cfa_offset (-4)
-
- ret
-
-1: fstp %st
- movl $0x7fffffff, %eax
- ret
-END (__ilogb)
-weak_alias (__ilogb, ilogb)
diff --git a/sysdeps/i386/fpu/s_ilogbf.S b/sysdeps/i386/fpu/s_ilogbf.S
deleted file mode 100644
index 99e53ed..0000000
--- a/sysdeps/i386/fpu/s_ilogbf.S
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Written by J.T. Conklin <jtc@netbsd.org>.
- * Public domain.
- */
-
-#include <machine/asm.h>
-
-RCSID("$NetBSD: s_ilogbf.S,v 1.4 1995/10/22 20:32:43 pk Exp $")
-
-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
- cfi_adjust_cfa_offset (4)
- fstp %st
-
- fistpl (%esp)
- fwait
- popl %eax
- cfi_adjust_cfa_offset (-4)
-
- ret
-
-1: fstp %st
- movl $0x7fffffff, %eax
- ret
-END (__ilogbf)
-weak_alias (__ilogbf, ilogbf)
diff --git a/sysdeps/i386/fpu/s_ilogbl.S b/sysdeps/i386/fpu/s_ilogbl.S
deleted file mode 100644
index 1f559b3..0000000
--- a/sysdeps/i386/fpu/s_ilogbl.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Written by J.T. Conklin <jtc@netbsd.org>.
- * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
- * Public domain.
- */
-
-#include <machine/asm.h>
-
-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
- cfi_adjust_cfa_offset (4)
- fstp %st
-
- fistpl (%esp)
- fwait
- popl %eax
- cfi_adjust_cfa_offset (-4)
-
- ret
-
-1: fstp %st
- movl $0x7fffffff, %eax
- ret
-END (__ilogbl)
-weak_alias (__ilogbl, ilogbl)
diff --git a/sysdeps/ieee754/dbl-64/e_ilogb.c b/sysdeps/ieee754/dbl-64/e_ilogb.c
new file mode 100644
index 0000000..7772880
--- /dev/null
+++ b/sysdeps/ieee754/dbl-64/e_ilogb.c
@@ -0,0 +1,55 @@
+/* @(#)s_ilogb.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * 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: s_ilogb.c,v 1.9 1995/05/10 20:47:28 jtc Exp $";
+#endif
+
+/* ilogb(double x)
+ * return the binary exponent of non-zero x
+ * 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>
+
+int __ieee754_ilogb(double x)
+{
+ int32_t hx,lx,ix;
+
+ GET_HIGH_WORD(hx,x);
+ hx &= 0x7fffffff;
+ if(hx<0x00100000) {
+ GET_LOW_WORD(lx,x);
+ if((hx|lx)==0)
+ return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */
+ else /* subnormal x */
+ if(hx==0) {
+ for (ix = -1043; lx>0; lx<<=1) ix -=1;
+ } else {
+ for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
+ }
+ return ix;
+ }
+ else if (hx<0x7ff00000) return (hx>>20)-1023;
+ 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;
+}
+strong_alias (__ieee754_ilogb, __ilogb_finite)
diff --git a/sysdeps/ieee754/dbl-64/s_ilogb.c b/sysdeps/ieee754/dbl-64/s_ilogb.c
deleted file mode 100644
index 05c66d7..0000000
--- a/sysdeps/ieee754/dbl-64/s_ilogb.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* @(#)s_ilogb.c 5.1 93/09/24 */
-/*
- * ====================================================
- * 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: s_ilogb.c,v 1.9 1995/05/10 20:47:28 jtc Exp $";
-#endif
-
-/* ilogb(double x)
- * return the binary exponent of non-zero x
- * 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>
-
-int __ilogb(double x)
-{
- int32_t hx,lx,ix;
-
- GET_HIGH_WORD(hx,x);
- hx &= 0x7fffffff;
- if(hx<0x00100000) {
- GET_LOW_WORD(lx,x);
- if((hx|lx)==0)
- return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */
- else /* subnormal x */
- if(hx==0) {
- for (ix = -1043; lx>0; lx<<=1) ix -=1;
- } else {
- for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
- }
- return ix;
- }
- else if (hx<0x7ff00000) return (hx>>20)-1023;
- 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
-strong_alias (__ilogb, __ilogbl)
-weak_alias (__ilogb, ilogbl)
-#endif
diff --git a/sysdeps/ieee754/flt-32/e_ilogbf.c b/sysdeps/ieee754/flt-32/e_ilogbf.c
new file mode 100644
index 0000000..c7441a8
--- /dev/null
+++ b/sysdeps/ieee754/flt-32/e_ilogbf.c
@@ -0,0 +1,45 @@
+/* s_ilogbf.c -- float version of s_ilogb.c.
+ * 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: 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>
+
+int __ieee754_ilogbf(float x)
+{
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ hx &= 0x7fffffff;
+ if(hx<0x00800000) {
+ if(hx==0)
+ return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */
+ else /* subnormal x */
+ for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1;
+ return ix;
+ }
+ else if (hx<0x7f800000) return (hx>>23)-127;
+ else if (FP_ILOGBNAN != INT_MAX) {
+ /* ISO C99 requires ilogbf(+-Inf) == INT_MAX. */
+ if (hx==0x7f800000)
+ return INT_MAX;
+ }
+ return FP_ILOGBNAN;
+}
+strong_alias (__ieee754_ilogbf, __ilogbf_finite)
diff --git a/sysdeps/ieee754/flt-32/s_ilogbf.c b/sysdeps/ieee754/flt-32/s_ilogbf.c
deleted file mode 100644
index 21f9cd9..0000000
--- a/sysdeps/ieee754/flt-32/s_ilogbf.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* s_ilogbf.c -- float version of s_ilogb.c.
- * 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: 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>
-
-int __ilogbf(float x)
-{
- int32_t hx,ix;
-
- GET_FLOAT_WORD(hx,x);
- hx &= 0x7fffffff;
- if(hx<0x00800000) {
- if(hx==0)
- return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */
- else /* subnormal x */
- for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1;
- return ix;
- }
- else if (hx<0x7f800000) return (hx>>23)-127;
- 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)
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c b/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c
new file mode 100644
index 0000000..55f87ed
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c
@@ -0,0 +1,57 @@
+/* s_ilogbl.c -- long double version of s_ilogb.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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
+
+/* ilogbl(long double x)
+ * return the binary exponent of non-zero x
+ * 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>
+#include <math_ldbl_opt.h>
+
+int __ieee754_ilogbl(long double x)
+{
+ int64_t hx,lx;
+ int ix;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ hx &= 0x7fffffffffffffffLL;
+ if(hx <= 0x0010000000000000LL) {
+ if((hx|(lx&0x7fffffffffffffffLL))==0)
+ return FP_ILOGB0; /* ilogbl(0) = FP_ILOGB0 */
+ else /* subnormal x */
+ if(hx==0) {
+ for (ix = -1043; lx>0; lx<<=1) ix -=1;
+ } else {
+ for (ix = -1022, hx<<=11; hx>0; hx<<=1) ix -=1;
+ }
+ return ix;
+ }
+ else if (hx<0x7ff0000000000000LL) return (hx>>52)-0x3ff;
+ else if (FP_ILOGBNAN != INT_MAX) {
+ /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */
+ if (((hx^0x7ff0000000000000LL)|lx) == 0)
+ return INT_MAX;
+ }
+ return FP_ILOGBNAN;
+}
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c b/sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c
deleted file mode 100644
index a6f0e1e..0000000
--- a/sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* s_ilogbl.c -- long double version of s_ilogb.c.
- * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
- */
-
-/*
- * ====================================================
- * 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
-
-/* ilogbl(long double x)
- * return the binary exponent of non-zero x
- * 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>
-#include <math_ldbl_opt.h>
-
-int __ilogbl(long double x)
-{
- int64_t hx,lx;
- int ix;
-
- GET_LDOUBLE_WORDS64(hx,lx,x);
- hx &= 0x7fffffffffffffffLL;
- if(hx <= 0x0010000000000000LL) {
- if((hx|(lx&0x7fffffffffffffffLL))==0)
- return FP_ILOGB0; /* ilogbl(0) = FP_ILOGB0 */
- else /* subnormal x */
- if(hx==0) {
- for (ix = -1043; lx>0; lx<<=1) ix -=1;
- } else {
- for (ix = -1022, hx<<=11; hx>0; hx<<=1) ix -=1;
- }
- return ix;
- }
- else if (hx<0x7ff0000000000000LL) return (hx>>52)-0x3ff;
- else if (FP_ILOGBNAN != INT_MAX) {
- /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */
- if (((hx^0x7ff0000000000000LL)|lx) == 0)
- return INT_MAX;
- }
- return FP_ILOGBNAN;
-}
-long_double_symbol (libm, __ilogbl, ilogbl);
diff --git a/sysdeps/ieee754/ldbl-opt/s_ilogb.c b/sysdeps/ieee754/ldbl-opt/s_ilogb.c
deleted file mode 100644
index 3a6ccbd..0000000
--- a/sysdeps/ieee754/ldbl-opt/s_ilogb.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#include <math_ldbl_opt.h>
-#include <sysdeps/ieee754/dbl-64/s_ilogb.c>
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
-compat_symbol (libm, __ilogb, ilogbl, GLIBC_2_0);
-#endif
diff --git a/sysdeps/ieee754/ldbl-opt/w_ilogb.c b/sysdeps/ieee754/ldbl-opt/w_ilogb.c
new file mode 100644
index 0000000..f518087
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/w_ilogb.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_ilogb.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __ilogb, ilogbl, GLIBC_2_0);
+#endif
diff --git a/sysdeps/ieee754/ldbl-opt/w_ilogbl.c b/sysdeps/ieee754/ldbl-opt/w_ilogbl.c
new file mode 100644
index 0000000..36f83f6
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/w_ilogbl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_ilogbl.c>
+long_double_symbol (libm, __ilogbl, ilogbl);
diff --git a/sysdeps/x86_64/fpu/e_ilogbl.S b/sysdeps/x86_64/fpu/e_ilogbl.S
new file mode 100644
index 0000000..ea06f3b
--- /dev/null
+++ b/sysdeps/x86_64/fpu/e_ilogbl.S
@@ -0,0 +1,40 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__ieee754_ilogbl)
+ fldt 8(%rsp)
+/* 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. */
+ cmpb $0x40, %dh
+ je 2f /* Is +-Inf, jump. */
+
+ fxtract
+ fstp %st
+
+ fistpl -4(%rsp)
+ fwait
+ movl -4(%rsp),%eax
+
+ ret
+
+1: fstp %st
+ movl $0x7fffffff, %eax
+ ret
+2: fstp %st
+ movl $0x80000000, %eax /* FP_ILOGB0 */
+ ret
+END (__ieee754_ilogbl)
+weak_alias (__ieee754_ilogbl, __ilogbl_finite)
diff --git a/sysdeps/x86_64/fpu/s_ilogbl.S b/sysdeps/x86_64/fpu/s_ilogbl.S
deleted file mode 100644
index f59040c..0000000
--- a/sysdeps/x86_64/fpu/s_ilogbl.S
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Written by J.T. Conklin <jtc@netbsd.org>.
- * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
- * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
- * Public domain.
- */
-
-#include <machine/asm.h>
-
-ENTRY(__ilogbl)
- fldt 8(%rsp)
-/* 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
- fstp %st
-
- fistpl -4(%rsp)
- fwait
- movl -4(%rsp),%eax
-
- ret
-
-1: fstp %st
- movl $0x7fffffff, %eax
- ret
-END (__ilogbl)
-weak_alias (__ilogbl, ilogbl)
--
1.7.4.1
--
Adhemerval Zanella Netto
Software Engineer
Linux Technology Center Brazil
Toolchain / GLIBC on Power Architecture
azanella@linux.vnet.ibm.com / azanella@br.ibm.com
+55 61 8642-9890