about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--NEWS2
-rw-r--r--math/libm-test.inc4
-rw-r--r--sysdeps/i386/fpu/e_log2.S8
-rw-r--r--sysdeps/i386/fpu/e_log2f.S8
-rw-r--r--sysdeps/i386/fpu/e_log2l.S8
-rw-r--r--sysdeps/i386/fpu/libm-test-ulps16
-rw-r--r--sysdeps/ieee754/ldbl-128/e_log2l.c3
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/e_log2l.c3
-rw-r--r--sysdeps/x86_64/fpu/e_log2l.S8
-rw-r--r--sysdeps/x86_64/fpu/libm-test-ulps22
11 files changed, 91 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 0ace298b9e..9055159cf0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2014-06-10  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #17042]
+	* sysdeps/i386/fpu/e_log2.S (__ieee754_log2): Take absolete value
+	when x - 1 is zero.
+	* sysdeps/i386/fpu/e_log2f.S (__ieee754_log2f): Likewise.
+	* sysdeps/i386/fpu/e_log2l.S (__ieee754_log2l): Likewise.
+	* sysdeps/ieee754/ldbl-128/e_log2l.c (__ieee754_log2l): Return
+	0.0L for an argument of 1.0L.
+	* sysdeps/ieee754/ldbl-128ibm/e_log2l.c (__ieee754_log2l):
+	Likewise.
+	* sysdeps/x86_64/fpu/e_log2l.S (__ieee754_log2l): Take absolute
+	value when x - 1 is zero.
+	* math/libm-test.inc (log2_test): Use ALL_RM_TEST.
+	* sysdeps/i386/fpu/libm-test-ulps: Update.
+	* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
 2014-06-09  Bernard Ogden  <bernie.ogden@linaro.org>
 
 	[BZ #15119]
diff --git a/NEWS b/NEWS
index 622cdbf21d..ca3ef633b0 100644
--- a/NEWS
+++ b/NEWS
@@ -19,7 +19,7 @@ Version 2.20
   16791, 16796, 16799, 16800, 16815, 16823, 16824, 16831, 16838, 16849,
   16854, 16876, 16877, 16878, 16882, 16885, 16888, 16890, 16912, 16915,
   16916, 16917, 16922, 16927, 16928, 16932, 16943, 16958, 16965, 16966,
-  16967, 16977, 16978, 16984, 16990, 17009.
+  16967, 16977, 16978, 16984, 16990, 17009, 17042.
 
 * The minimum Linux kernel version that this version of the GNU C Library
   can be used with is 2.6.32.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 0d467a2195..fa8e2385dc 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -7840,9 +7840,7 @@ static const struct test_f_f_data log2_test_data[] =
 static void
 log2_test (void)
 {
-  START (log2, 0);
-  RUN_TEST_LOOP_f_f (log2, log2_test_data, );
-  END;
+  ALL_RM_TEST (log2, 0, log2_test_data, RUN_TEST_LOOP_f_f, END);
 }
 
 
diff --git a/sysdeps/i386/fpu/e_log2.S b/sysdeps/i386/fpu/e_log2.S
index a202bc731d..73ff0fffd3 100644
--- a/sysdeps/i386/fpu/e_log2.S
+++ b/sysdeps/i386/fpu/e_log2.S
@@ -47,7 +47,13 @@ ENTRY(__ieee754_log2)
 	fnstsw			// x-1 : x : 1
 	andb	$0x45, %ah
 	jz	2f
-	fstp	%st(1)		// x-1 : 1
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	5f
+	fabs			// log2(1) is +0 in all rounding modes.
+5:	fstp	%st(1)		// x-1 : 1
 	fyl2xp1			// log(x)
 	ret
 
diff --git a/sysdeps/i386/fpu/e_log2f.S b/sysdeps/i386/fpu/e_log2f.S
index f4f9a8c3bf..344eeb495e 100644
--- a/sysdeps/i386/fpu/e_log2f.S
+++ b/sysdeps/i386/fpu/e_log2f.S
@@ -47,7 +47,13 @@ ENTRY(__ieee754_log2f)
 	fnstsw			// x-1 : x : 1
 	andb	$0x45, %ah
 	jz	2f
-	fstp	%st(1)		// x-1 : 1
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	5f
+	fabs			// log2(1) is +0 in all rounding modes.
+5:	fstp	%st(1)		// x-1 : 1
 	fyl2xp1			// log(x)
 	ret
 
diff --git a/sysdeps/i386/fpu/e_log2l.S b/sysdeps/i386/fpu/e_log2l.S
index bd51b5651e..0f5f7e5789 100644
--- a/sysdeps/i386/fpu/e_log2l.S
+++ b/sysdeps/i386/fpu/e_log2l.S
@@ -47,7 +47,13 @@ ENTRY(__ieee754_log2l)
 	fnstsw			// x-1 : x : 1
 	andb	$0x45, %ah
 	jz	2f
-	fstp	%st(1)		// x-1 : 1
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	5f
+	fabs			// log2(1) is +0 in all rounding modes.
+5:	fstp	%st(1)		// x-1 : 1
 	fyl2xp1			// log(x)
 	ret
 
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index 1e89284455..d7424a6f86 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -1588,6 +1588,22 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 
+Function: "log2_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log2_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
 Function: "log_downward":
 ildouble: 1
 ldouble: 1
diff --git a/sysdeps/ieee754/ldbl-128/e_log2l.c b/sysdeps/ieee754/ldbl-128/e_log2l.c
index 6c7da0e44b..991a3b73e2 100644
--- a/sysdeps/ieee754/ldbl-128/e_log2l.c
+++ b/sysdeps/ieee754/ldbl-128/e_log2l.c
@@ -188,6 +188,9 @@ __ieee754_log2l (x)
   if (hx >= 0x7fff000000000000LL)
     return (x + x);
 
+  if (x == 1.0L)
+    return 0.0L;
+
 /* separate mantissa from exponent */
 
 /* Note, frexp is used so that denormal numbers
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_log2l.c b/sysdeps/ieee754/ldbl-128ibm/e_log2l.c
index 323ded0c0f..442ad97254 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_log2l.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_log2l.c
@@ -190,6 +190,9 @@ __ieee754_log2l (x)
   if (hx >= 0x7ff0000000000000LL)
     return (x + x);
 
+  if (x == 1.0L)
+    return 0.0L;
+
 /* separate mantissa from exponent */
 
 /* Note, frexp is used so that denormal numbers
diff --git a/sysdeps/x86_64/fpu/e_log2l.S b/sysdeps/x86_64/fpu/e_log2l.S
index 956489fc3e..c12906d456 100644
--- a/sysdeps/x86_64/fpu/e_log2l.S
+++ b/sysdeps/x86_64/fpu/e_log2l.S
@@ -45,7 +45,13 @@ ENTRY(__ieee754_log2l)
 	fnstsw			// x-1 : x : 1
 	andb	$0x45, %ah
 	jz	2f
-	fstp	%st(1)		// x-1 : 1
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	5f
+	fabs			// log2(1) is +0 in all rounding modes.
+5:	fstp	%st(1)		// x-1 : 1
 	fyl2xp1			// log(x)
 	ret
 
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index bb549d2b0d..92fef5a134 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -1665,6 +1665,28 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 
+Function: "log2_downward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: "log2_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log2_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
 Function: "log_downward":
 float: 1
 ifloat: 1