about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/i386/fpu/e_exp.S53
-rw-r--r--sysdeps/i386/fpu/e_expf.S53
2 files changed, 102 insertions, 4 deletions
diff --git a/sysdeps/i386/fpu/e_exp.S b/sysdeps/i386/fpu/e_exp.S
index 2c331d9ed6..c00beedfe5 100644
--- a/sysdeps/i386/fpu/e_exp.S
+++ b/sysdeps/i386/fpu/e_exp.S
@@ -5,9 +5,25 @@
 
 #include <machine/asm.h>
 
+	.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(%ecx)
+#else
+# define MO(op) op
+#endif
+
+	.text
 /* e^x = 2^(x * log2(e)) */
 ENTRY(__ieee754_exp)
+#ifdef  PIC
+	LOAD_PIC_REG (cx)
+#endif
 	fldl	4(%esp)
 /* I added the following ugly construct because exp(+-Inf) resulted
    in NaN.  The ugliness results from the bright minds at Intel.
@@ -30,7 +46,22 @@ ENTRY(__ieee754_exp)
 	faddp				/* 2^(fract(x * log2(e))) */
 	fscale				/* e^x */
 	fstp	%st(1)
-	ret
+	fldl	MO(dbl_min)
+	fld	%st(1)
+	fucompp
+	fnstsw
+	sahf
+	jnc 3f
+	subl	$8, %esp
+	cfi_adjust_cfa_offset (8)
+	fld	%st(0)
+	fmul	%st(0)
+	fstpl	(%esp)
+	fstpl	(%esp)
+	fldl	(%esp)
+	addl	$8, %esp
+	cfi_adjust_cfa_offset (-8)
+3:	ret
 
 1:	testl	$0x200, %eax		/* Test sign.  */
 	jz	2f			/* If positive, jump.  */
@@ -41,6 +72,9 @@ END (__ieee754_exp)
 
 
 ENTRY(__exp_finite)
+#ifdef  PIC
+	LOAD_PIC_REG (cx)
+#endif
 	fldl2e
 	fmull	4(%esp)			/* x * log2(e) */
 	fld	%st
@@ -52,5 +86,20 @@ ENTRY(__exp_finite)
 	faddp				/* 2^(fract(x * log2(e))) */
 	fscale				/* e^x */
 	fstp	%st(1)
-	ret
+	fldl	MO(dbl_min)
+	fld	%st(1)
+	fucompp
+	fnstsw
+	sahf
+	jnc 4f
+	subl	$8, %esp
+	cfi_adjust_cfa_offset (8)
+	fld	%st(0)
+	fmul	%st(0)
+	fstpl	(%esp)
+	fstpl	(%esp)
+	fldl	(%esp)
+	addl	$8, %esp
+	cfi_adjust_cfa_offset (-8)
+4:	ret
 END(__exp_finite)
diff --git a/sysdeps/i386/fpu/e_expf.S b/sysdeps/i386/fpu/e_expf.S
index 4e4f6a0df7..306afd1122 100644
--- a/sysdeps/i386/fpu/e_expf.S
+++ b/sysdeps/i386/fpu/e_expf.S
@@ -6,9 +6,25 @@
 
 #include <machine/asm.h>
 
+	.section .rodata.cst4,"aM",@progbits,4
 
+	.p2align 2
+	.type flt_min,@object
+flt_min:	.byte 0, 0, 0x80, 0
+	ASM_SIZE_DIRECTIVE(flt_min)
+
+#ifdef PIC
+# define MO(op) op##@GOTOFF(%ecx)
+#else
+# define MO(op) op
+#endif
+
+	.text
 /* e^x = 2^(x * log2(e)) */
 ENTRY(__ieee754_expf)
+#ifdef  PIC
+	LOAD_PIC_REG (cx)
+#endif
 	flds	4(%esp)
 /* I added the following ugly construct because exp(+-Inf) resulted
    in NaN.  The ugliness results from the bright minds at Intel.
@@ -31,7 +47,22 @@ ENTRY(__ieee754_expf)
 	faddp				/* 2^(fract(x * log2(e))) */
 	fscale				/* e^x */
 	fstp	%st(1)
-	ret
+	flds	MO(flt_min)
+	fld	%st(1)
+	fucompp
+	fnstsw
+	sahf
+	jnc 3f
+	subl	$4, %esp
+	cfi_adjust_cfa_offset (4)
+	fld	%st(0)
+	fmul	%st(0)
+	fstps	(%esp)
+	fstps	(%esp)
+	flds	(%esp)
+	addl	$4, %esp
+	cfi_adjust_cfa_offset (-4)
+3:	ret
 
 1:	testl	$0x200, %eax		/* Test sign.  */
 	jz	2f			/* If positive, jump.  */
@@ -42,6 +73,9 @@ END (__ieee754_expf)
 
 
 ENTRY(__expf_finite)
+#ifdef  PIC
+	LOAD_PIC_REG (cx)
+#endif
 	fldl2e
 	fmuls	4(%esp)			/* x * log2(e) */
 	fld	%st
@@ -53,5 +87,20 @@ ENTRY(__expf_finite)
 	faddp				/* 2^(fract(x * log2(e))) */
 	fscale				/* e^x */
 	fstp	%st(1)
-	ret
+	flds	MO(flt_min)
+	fld	%st(1)
+	fucompp
+	fnstsw
+	sahf
+	jnc 4f
+	subl	$4, %esp
+	cfi_adjust_cfa_offset (4)
+	fld	%st(0)
+	fmul	%st(0)
+	fstps	(%esp)
+	fstps	(%esp)
+	flds	(%esp)
+	addl	$4, %esp
+	cfi_adjust_cfa_offset (-4)
+4:	ret
 END(__expf_finite)