summary refs log tree commit diff
path: root/sysdeps/i386/fpu/s_expm1.S
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-06-22 21:06:19 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-06-22 21:06:19 +0000
commit554edb23ffc7a953ca86309cc5f02dbd1a63abe0 (patch)
tree35ceb89ac22f1987f944539728fda653acd418f2 /sysdeps/i386/fpu/s_expm1.S
parent6b142b3a1d007d7e6f50c26710de7177bc4aca74 (diff)
downloadglibc-554edb23ffc7a953ca86309cc5f02dbd1a63abe0.tar.gz
glibc-554edb23ffc7a953ca86309cc5f02dbd1a63abe0.tar.xz
glibc-554edb23ffc7a953ca86309cc5f02dbd1a63abe0.zip
Fix expm1 missing underflows (bug 16353).
Similar to various other bugs in this area, some expm1 implementations
do not raise the underflow exception for subnormal arguments, when the
result is tiny and inexact.  This patch forces the exception in a
similar way to previous fixes.

(The issue does not apply to the ldbl-* implementations or to those
for x86 / x86_64 long double.  The change to
sysdeps/ieee754/dbl-64/wordsize-64/e_cosh.c is one I missed when
previously fixing bug 16354; the bug in that implementation was
previously latent, but the expm1 fixes stopped it being latent and so
required it to be fixed to avoid spurious underflows from cosh.)

Tested for x86_64 and x86.

	[BZ #16353]
	* sysdeps/i386/fpu/s_expm1.S (dbl_min): New object.
	(__expm1): Force underflow exception for arguments with small
	absolute value.
	* sysdeps/i386/fpu/s_expm1f.S (flt_min): New object.
	(__expm1f): Force underflow exception for arguments with small
	absolute value.
	* sysdeps/ieee754/dbl-64/s_expm1.c: Include <float.h>.
	(__expm1): Force underflow exception for arguments with small
	absolute value.
	* sysdeps/ieee754/flt-32/s_expm1f.c: Include <float.h>.
	(__expm1f): Force underflow exception for arguments with small
	absolute value.
	* sysdeps/ieee754/dbl-64/wordsize-64/e_cosh.c (__ieee754_cosh):
	Check for small arguments before calling __expm1.
	* math/auto-libm-test-in: Do not mark underflow exceptions as
	possibly missing for bug 16353.
	* math/auto-libm-test-out: Regenerated.
Diffstat (limited to 'sysdeps/i386/fpu/s_expm1.S')
-rw-r--r--sysdeps/i386/fpu/s_expm1.S22
1 files changed, 22 insertions, 0 deletions
diff --git a/sysdeps/i386/fpu/s_expm1.S b/sysdeps/i386/fpu/s_expm1.S
index 65426c5984..05e5285d7b 100644
--- a/sysdeps/i386/fpu/s_expm1.S
+++ b/sysdeps/i386/fpu/s_expm1.S
@@ -37,6 +37,13 @@ one:	.double 1.0
 l2e:	.tfloat 1.442695040888963407359924681002
 	ASM_SIZE_DIRECTIVE(l2e)
 
+	.section .rodata.cst8,"aM",@progbits,8
+
+	.p2align 3
+	.type dbl_min,@object
+dbl_min:	.byte 0, 0, 0, 0, 0, 0, 0x10, 0
+	ASM_SIZE_DIRECTIVE(dbl_min)
+
 #ifdef PIC
 #define MO(op) op##@GOTOFF(%edx)
 #else
@@ -74,6 +81,21 @@ ENTRY(__expm1)
 #ifdef	PIC
 	LOAD_PIC_REG (dx)
 #endif
+	fld	%st
+	fabs
+	fcoml	MO(dbl_min)
+	fstp	%st
+	fnstsw
+	sahf
+	jae	5f
+	subl	$8, %esp
+	cfi_adjust_cfa_offset (8)
+	fld	%st(0)
+	fmul	%st(0)
+	fstpl	(%esp)
+	addl	$8, %esp
+	cfi_adjust_cfa_offset (-8)
+	ret
 
 5:	fldt	MO(l2e)		// log2(e) : x
 	fmulp			// log2(e)*x