1 | /* |
2 | * Public domain. |
3 | */ |
4 | |
5 | #include <machine/asm.h> |
6 | #include <i386-math-asm.h> |
7 | #include <libm-alias-finite.h> |
8 | |
9 | DEFINE_DBL_MIN |
10 | |
11 | #ifdef PIC |
12 | # define MO(op) op##@GOTOFF(%ecx) |
13 | #else |
14 | # define MO(op) op |
15 | #endif |
16 | |
17 | .text |
18 | /* e^x = 2^(x * log2(e)) */ |
19 | ENTRY(__ieee754_exp) |
20 | #ifdef PIC |
21 | LOAD_PIC_REG (cx) |
22 | #endif |
23 | fldl 4(%esp) |
24 | /* I added the following ugly construct because exp(+-Inf) resulted |
25 | in NaN. The ugliness results from the bright minds at Intel. |
26 | For the i686 the code can be written better. |
27 | -- drepper@cygnus.com. */ |
28 | fxam /* Is NaN or +-Inf? */ |
29 | fstsw %ax |
30 | movb $0x45, %dh |
31 | andb %ah, %dh |
32 | cmpb $0x05, %dh |
33 | je 1f /* Is +-Inf, jump. */ |
34 | fldl2e |
35 | fmulp /* x * log2(e) */ |
36 | fld %st |
37 | frndint /* int(x * log2(e)) */ |
38 | fsubr %st,%st(1) /* fract(x * log2(e)) */ |
39 | fxch |
40 | f2xm1 /* 2^(fract(x * log2(e))) - 1 */ |
41 | fld1 |
42 | faddp /* 2^(fract(x * log2(e))) */ |
43 | fscale /* e^x */ |
44 | fstp %st(1) |
45 | DBL_NARROW_EVAL_UFLOW_NONNEG_NAN |
46 | ret |
47 | |
48 | 1: testl $0x200, %eax /* Test sign. */ |
49 | jz 2f /* If positive, jump. */ |
50 | fstp %st |
51 | fldz /* Set result to 0. */ |
52 | 2: ret |
53 | END (__ieee754_exp) |
54 | |
55 | |
56 | ENTRY(__exp_finite) |
57 | #ifdef PIC |
58 | LOAD_PIC_REG (cx) |
59 | #endif |
60 | fldl2e |
61 | fmull 4(%esp) /* x * log2(e) */ |
62 | fld %st |
63 | frndint /* int(x * log2(e)) */ |
64 | fsubr %st,%st(1) /* fract(x * log2(e)) */ |
65 | fxch |
66 | f2xm1 /* 2^(fract(x * log2(e))) - 1 */ |
67 | fld1 |
68 | faddp /* 2^(fract(x * log2(e))) */ |
69 | fscale /* e^x */ |
70 | fstp %st(1) |
71 | DBL_NARROW_EVAL_UFLOW_NONNEG |
72 | ret |
73 | END(__exp_finite) |
74 | libm_alias_finite (__exp_finite, __exp) |
75 | |