expm1 implementation for 128-bit long double.
[glibc.git] / sysdeps / i386 / fpu / e_expl.S
blob2bcdf58c589f8180f44693911223f8d5c4186b78
1 /*
2  * Written by J.T. Conklin <jtc@netbsd.org>.
3  * Public domain.
4  *
5  * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
6  */
8 #include <machine/asm.h>
10 RCSID("$NetBSD: $")
12 /* e^x = 2^(x * log2l(e)) */
13 ENTRY(__ieee754_expl)
14         fldt    4(%esp)
15 /* I added the following ugly construct because expl(+-Inf) resulted
16    in NaN.  The ugliness results from the bright minds at Intel.
17    For the i686 the code can be written better.
18    -- drepper@cygnus.com.  */
19         fxam                            /* Is NaN or +-Inf?  */
20         fstsw   %ax
21         movb    $0x45, %dh
22         andb    %ah, %dh
23         cmpb    $0x05, %dh
24         je      1f                      /* Is +-Inf, jump.  */
25         fldl2e
26         fmulp                           /* x * log2(e) */
27         fld     %st
28         frndint                         /* int(x * log2(e)) */
29         fsubr   %st,%st(1)              /* fract(x * log2(e)) */
30         fxch
31         f2xm1                           /* 2^(fract(x * log2(e))) - 1 */
32         fld1
33         faddp                           /* 2^(fract(x * log2(e))) */
34         fscale                          /* e^x */
35         fstp    %st(1)
36         ret
38 1:      testl   $0x200, %eax            /* Test sign.  */
39         jz      2f                      /* If positive, jump.  */
40         fstp    %st
41         fldz                            /* Set result to 0.  */
42 2:      ret
43 END (__ieee754_expl)