aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/i386
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-05-06 18:23:44 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-05-06 18:23:44 +0000
commitd8b82cad1b525bdcbfff88d218c7c45032e4a3af (patch)
tree77e88bf7642e69d74d4df3d771ffbb4274937b31 /sysdeps/i386
parent6c23e11c4dd036e65073d4e4d6bc971a445deaea (diff)
downloadglibc-d8b82cad1b525bdcbfff88d218c7c45032e4a3af.tar
glibc-d8b82cad1b525bdcbfff88d218c7c45032e4a3af.tar.gz
glibc-d8b82cad1b525bdcbfff88d218c7c45032e4a3af.tar.bz2
glibc-d8b82cad1b525bdcbfff88d218c7c45032e4a3af.zip
Fix exp10 inaccuracy and exceptions (bugs 13884, 13914).
Diffstat (limited to 'sysdeps/i386')
-rw-r--r--sysdeps/i386/fpu/e_exp10l.S41
-rw-r--r--sysdeps/i386/fpu/e_expl.S37
2 files changed, 31 insertions, 47 deletions
diff --git a/sysdeps/i386/fpu/e_exp10l.S b/sysdeps/i386/fpu/e_exp10l.S
index 04ec8001d9..d843e2b5e8 100644
--- a/sysdeps/i386/fpu/e_exp10l.S
+++ b/sysdeps/i386/fpu/e_exp10l.S
@@ -1,39 +1,2 @@
-/*
- * Written by Ulrich Drepper <drepper@cygnus.com>.
- */
-
-#include <machine/asm.h>
-
-/* 10^x = 2^(x * log2l(10)) */
-ENTRY(__ieee754_exp10l)
- fldt 4(%esp)
-/* I added the following ugly construct because expl(+-Inf) resulted
- in NaN. The ugliness results from the bright minds at Intel.
- For the i686 the code can be written better.
- -- drepper@cygnus.com. */
- fxam /* Is NaN or +-Inf? */
- fstsw %ax
- movb $0x45, %dh
- andb %ah, %dh
- cmpb $0x05, %dh
- je 1f /* Is +-Inf, jump. */
- fldl2t
- fmulp /* x * log2(10) */
- fld %st
- frndint /* int(x * log2(10)) */
- fsubr %st,%st(1) /* fract(x * log2(10)) */
- fxch
- f2xm1 /* 2^(fract(x * log2(10))) - 1 */
- fld1
- faddp /* 2^(fract(x * log2(10))) */
- fscale /* e^x */
- fstp %st(1)
- ret
-
-1: testl $0x200, %eax /* Test sign. */
- jz 2f /* If positive, jump. */
- fstp %st
- fldz /* Set result to 0. */
-2: ret
-END (__ieee754_exp10l)
-strong_alias (__ieee754_exp10l, __exp10l_finite)
+#define USE_AS_EXP10L
+#include <e_expl.S>
diff --git a/sysdeps/i386/fpu/e_expl.S b/sysdeps/i386/fpu/e_expl.S
index 45c4d07539..9adf2a489e 100644
--- a/sysdeps/i386/fpu/e_expl.S
+++ b/sysdeps/i386/fpu/e_expl.S
@@ -24,9 +24,29 @@
#include <machine/asm.h>
+#ifdef USE_AS_EXP10L
+# define IEEE754_EXPL __ieee754_exp10l
+# define EXPL_FINITE __exp10l_finite
+# define FLDLOG fldl2t
+#else
+# define IEEE754_EXPL __ieee754_expl
+# define EXPL_FINITE __expl_finite
+# define FLDLOG fldl2e
+#endif
+
.section .rodata.cst16,"aM",@progbits,16
.p2align 4
+#ifdef USE_AS_EXP10L
+ ASM_TYPE_DIRECTIVE(c0,@object)
+c0: .byte 0, 0, 0, 0, 0, 0, 0x9a, 0xd4, 0x00, 0x40
+ .byte 0, 0, 0, 0, 0, 0
+ ASM_SIZE_DIRECTIVE(c0)
+ ASM_TYPE_DIRECTIVE(c1,@object)
+c1: .byte 0x58, 0x92, 0xfc, 0x15, 0x37, 0x9a, 0x97, 0xf0, 0xef, 0x3f
+ .byte 0, 0, 0, 0, 0, 0
+ ASM_SIZE_DIRECTIVE(c1)
+#else
ASM_TYPE_DIRECTIVE(c0,@object)
c0: .byte 0, 0, 0, 0, 0, 0, 0xaa, 0xb8, 0xff, 0x3f
.byte 0, 0, 0, 0, 0, 0
@@ -35,6 +55,7 @@ c0: .byte 0, 0, 0, 0, 0, 0, 0xaa, 0xb8, 0xff, 0x3f
c1: .byte 0x20, 0xfa, 0xee, 0xc2, 0x5f, 0x70, 0xa5, 0xec, 0xed, 0x3f
.byte 0, 0, 0, 0, 0, 0
ASM_SIZE_DIRECTIVE(c1)
+#endif
ASM_TYPE_DIRECTIVE(csat,@object)
csat: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40
.byte 0, 0, 0, 0, 0, 0
@@ -47,7 +68,7 @@ csat: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40
#endif
.text
-ENTRY(__ieee754_expl)
+ENTRY(IEEE754_EXPL)
fldt 4(%esp)
/* I added the following ugly construct because expl(+-Inf) resulted
in NaN. The ugliness results from the bright minds at Intel.
@@ -75,8 +96,8 @@ ENTRY(__ieee754_expl)
andb $2, %ah
jz 3f
fchs
-3: fldl2e /* 1 log2(e) */
- fmul %st(1), %st /* 1 x log2(e) */
+3: FLDLOG /* 1 log2(base) */
+ fmul %st(1), %st /* 1 x log2(base) */
frndint /* 1 i */
fld %st(1) /* 2 x */
frndint /* 2 xi */
@@ -92,11 +113,11 @@ ENTRY(__ieee754_expl)
fldt MO(c1) /* 4 */
fmul %st(4), %st /* 4 c1 * x */
faddp %st, %st(1) /* 3 f = f + c1 * x */
- f2xm1 /* 3 2^(fract(x * log2(e))) - 1 */
+ f2xm1 /* 3 2^(fract(x * log2(base))) - 1 */
fld1 /* 4 1.0 */
- faddp /* 3 2^(fract(x * log2(e))) */
+ faddp /* 3 2^(fract(x * log2(base))) */
fstp %st(1) /* 2 */
- fscale /* 2 scale factor is st(1); e^x */
+ fscale /* 2 scale factor is st(1); base^x */
fstp %st(1) /* 1 */
fstp %st(1) /* 0 */
jmp 2f
@@ -105,5 +126,5 @@ ENTRY(__ieee754_expl)
fstp %st
fldz /* Set result to 0. */
2: ret
-END(__ieee754_expl)
-strong_alias (__ieee754_expl, __expl_finite)
+END(IEEE754_EXPL)
+strong_alias (IEEE754_EXPL, EXPL_FINITE)