29de387716c49aab566c6b1aa89fc51037f5e259
[dragonfly.git] / lib / libm / arch / i386 / e_expf.S
1 /*
2  * Written by J.T. Conklin <jtc@NetBSD.org>.
3  * Public domain.
4  *
5  * $NetBSD: e_expf.S,v 1.6 2008/06/24 17:27:56 drochner Exp $ $
6  */
7
8 #include <machine/asm.h>
9
10 #include "abi.h"
11
12 /* e^x = 2^(x * log2(e)) */
13 ENTRY(expf)
14         XMM_ONE_ARG_FLOAT_PROLOGUE
15
16         /*
17          * catch +/-Inf and NaN arguments
18          */
19         movl    ARG_FLOAT_ONE,%eax
20         andl    $0x7fffffff,%eax
21         cmpl    $0x7f800000,%eax
22         jae     x_Inf_or_NaN
23
24         flds    ARG_FLOAT_ONE
25         fldl2e
26         fmulp                           /* x * log2(e) */
27         fld     %st(0)
28         frndint                         /* int(x * log2(e)) */
29         fsubr   %st(0),%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         XMM_FLOAT_EPILOGUE
37         ret
38
39 x_Inf_or_NaN:
40         /*
41          * Return 0 if x is -Inf.  Otherwise just return x, although the
42          * C version would return (x + x) (Real Indefinite) if x is a NaN.
43          */
44         movl    ARG_FLOAT_ONE,%eax
45         cmpl    $0xff800000,%eax
46         jne     x_not_minus_Inf
47         fldz
48         XMM_FLOAT_EPILOGUE
49         ret
50
51 x_not_minus_Inf:
52         flds    ARG_FLOAT_ONE
53         XMM_FLOAT_EPILOGUE
54         ret
55 END(expf)