about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-11-05 21:56:31 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-11-05 21:56:31 +0000
commit01189b083b8ce54fc568fd2ab0dd433d869ede0e (patch)
tree15620545ab980f008bdec41540a43f1efea79ed0 /sysdeps
parent939fdd1c36dde8884543bc9c3b8506e76c9ff0e4 (diff)
downloadglibc-01189b083b8ce54fc568fd2ab0dd433d869ede0e.tar.gz
glibc-01189b083b8ce54fc568fd2ab0dd433d869ede0e.tar.xz
glibc-01189b083b8ce54fc568fd2ab0dd433d869ede0e.zip
Fix i386/x86_64 log* (1) zero sign for -ffinite-math-only (bug 19213).
For the -ffinite-math-only versions of various x86_64 and x86 log*
functions, a zero result from log* (1) is returned with incorrect sign
in round-downward mode.  This patch fixes this in a similar way to the
previous fixes for the non-*_finite versions of the functions.

Tested for x86_64 and x86 (including an i586 build), together with a
patch that will be applied separately to enable the main libm-test.inc
tests for the finite-math-only functions.

	[BZ #19213]
	* sysdeps/i386/fpu/e_log.S (__log_finite): Ensure +0 is always
	returned for argument 1.
	* sysdeps/i386/fpu/e_logf.S (__logf_finite): Likewise.
	* sysdeps/i386/fpu/e_logl.S (__logl_finite): Likewise.
	* sysdeps/i386/i686/fpu/e_logl.S (__logl_finite): Likewise.
	* sysdeps/x86_64/fpu/e_log10l.S (__log10l_finite): Likewise.
	* sysdeps/x86_64/fpu/e_log2l.S (__log2l_finite): Likewise.
	* sysdeps/x86_64/fpu/e_logl.S (__logl_finite): Likewise.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/i386/fpu/e_log.S8
-rw-r--r--sysdeps/i386/fpu/e_logf.S8
-rw-r--r--sysdeps/i386/fpu/e_logl.S8
-rw-r--r--sysdeps/i386/i686/fpu/e_logl.S8
-rw-r--r--sysdeps/x86_64/fpu/e_log10l.S8
-rw-r--r--sysdeps/x86_64/fpu/e_log2l.S8
-rw-r--r--sysdeps/x86_64/fpu/e_logl.S8
7 files changed, 49 insertions, 7 deletions
diff --git a/sysdeps/i386/fpu/e_log.S b/sysdeps/i386/fpu/e_log.S
index 3fa32aad3c..335df22577 100644
--- a/sysdeps/i386/fpu/e_log.S
+++ b/sysdeps/i386/fpu/e_log.S
@@ -80,7 +80,13 @@ ENTRY(__log_finite)
 	fnstsw			// x-1 : x : log(2)
 	andb	$0x45, %ah
 	jz	2b
-	fstp	%st(1)		// x-1 : log(2)
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	6f
+	fabs			// log(1) is +0 in all rounding modes.
+6:	fstp	%st(1)		// x-1 : log(2)
 	fyl2xp1			// log(x)
 	ret
 END(__log_finite)
diff --git a/sysdeps/i386/fpu/e_logf.S b/sysdeps/i386/fpu/e_logf.S
index ca83d39cef..de967a31f5 100644
--- a/sysdeps/i386/fpu/e_logf.S
+++ b/sysdeps/i386/fpu/e_logf.S
@@ -81,7 +81,13 @@ ENTRY(__logf_finite)
 	fnstsw			// x-1 : x : log(2)
 	andb	$0x45, %ah
 	jz	2b
-	fstp	%st(1)		// x-1 : log(2)
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	6f
+	fabs			// log(1) is +0 in all rounding modes.
+6:	fstp	%st(1)		// x-1 : log(2)
 	fyl2xp1			// log(x)
 	ret
 END(__logf_finite)
diff --git a/sysdeps/i386/fpu/e_logl.S b/sysdeps/i386/fpu/e_logl.S
index 828e98aa8d..7a6d370e8f 100644
--- a/sysdeps/i386/fpu/e_logl.S
+++ b/sysdeps/i386/fpu/e_logl.S
@@ -84,7 +84,13 @@ ENTRY(__logl_finite)
 	fnstsw			// x-1 : x : log(2)
 	andb	$0x45, %ah
 	jz	2b
-	fstp	%st(1)		// x-1 : log(2)
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	7f
+	fabs			// log(1) is +0 in all rounding modes.
+7:	fstp	%st(1)		// x-1 : log(2)
 	fyl2xp1			// log(x)
 	ret
 END(__logl_finite)
diff --git a/sysdeps/i386/i686/fpu/e_logl.S b/sysdeps/i386/i686/fpu/e_logl.S
index 0ccc8fc71e..e9ecbcd472 100644
--- a/sysdeps/i386/i686/fpu/e_logl.S
+++ b/sysdeps/i386/i686/fpu/e_logl.S
@@ -81,7 +81,13 @@ ENTRY(__logl_finite)
 	fcomip	%st(1)		// |x-1| : x-1 : x : log(2)
 	fstp	%st(0)		// x-1 : x : log(2)
 	jc	2b
-	fstp	%st(1)		// x-1 : log(2)
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	6f
+	fabs			// log(1) is +0 in all rounding modes.
+6:	fstp	%st(1)		// x-1 : log(2)
 	fyl2xp1			// log(x)
 	ret
 END(__logl_finite)
diff --git a/sysdeps/x86_64/fpu/e_log10l.S b/sysdeps/x86_64/fpu/e_log10l.S
index 2607ad199b..8fa61644c1 100644
--- a/sysdeps/x86_64/fpu/e_log10l.S
+++ b/sysdeps/x86_64/fpu/e_log10l.S
@@ -79,7 +79,13 @@ ENTRY(__log10l_finite)
 	fnstsw			// x-1 : x : log10(2)
 	andb	$0x45, %ah
 	jz	2b
-	fstp	%st(1)		// x-1 : log10(2)
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	6f
+	fabs			// log10(1) is +0 in all rounding modes.
+6:	fstp	%st(1)		// x-1 : log10(2)
 	fyl2xp1			// log10(x)
 	ret
 END(__log10l_finite)
diff --git a/sysdeps/x86_64/fpu/e_log2l.S b/sysdeps/x86_64/fpu/e_log2l.S
index c12906d456..a063255ddd 100644
--- a/sysdeps/x86_64/fpu/e_log2l.S
+++ b/sysdeps/x86_64/fpu/e_log2l.S
@@ -78,7 +78,13 @@ ENTRY(__log2l_finite)
 	fnstsw			// x-1 : x : 1
 	andb	$0x45, %ah
 	jz	2b
-	fstp	%st(1)		// x-1 : 1
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	6f
+	fabs			// log2(1) is +0 in all rounding modes.
+6:	fstp	%st(1)		// x-1 : 1
 	fyl2xp1			// log(x)
 	ret
 END (__log2l_finite)
diff --git a/sysdeps/x86_64/fpu/e_logl.S b/sysdeps/x86_64/fpu/e_logl.S
index 047b8db88a..dbe6fd59dc 100644
--- a/sysdeps/x86_64/fpu/e_logl.S
+++ b/sysdeps/x86_64/fpu/e_logl.S
@@ -81,7 +81,13 @@ ENTRY(__logl_finite)
 	fnstsw			// x-1 : x : log(2)
 	andb	$0x45, %ah
 	jz	2b
-	fstp	%st(1)		// x-1 : log(2)
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	jne	7f
+	fabs			// log(1) is +0 in all rounding modes.
+7:	fstp	%st(1)		// x-1 : log(2)
 	fyl2xp1			// log(x)
 	ret
 END (__logl_finite)