1 | /* |
2 | * Public domain. |
3 | */ |
4 | |
5 | #include <machine/asm.h> |
6 | #include <x86_64-math-asm.h> |
7 | #include <libm-alias-finite.h> |
8 | |
9 | DEFINE_LDBL_MIN |
10 | |
11 | #ifdef PIC |
12 | # define MO(op) op##(%rip) |
13 | #else |
14 | # define MO(op) op |
15 | #endif |
16 | |
17 | .text |
18 | ENTRY(__ieee754_exp2l) |
19 | fldt 8(%rsp) |
20 | /* I added the following ugly construct because exp(+-Inf) resulted |
21 | in NaN. The ugliness results from the bright minds at Intel. |
22 | For the i686 the code can be written better. |
23 | -- drepper@cygnus.com. */ |
24 | fxam /* Is NaN or +-Inf? */ |
25 | fstsw %ax |
26 | movb $0x45, %dh |
27 | andb %ah, %dh |
28 | cmpb $0x05, %dh |
29 | je 1f /* Is +-Inf, jump. */ |
30 | movzwl 8+8(%rsp), %eax |
31 | andl $0x7fff, %eax |
32 | cmpl $0x3fbe, %eax |
33 | jge 3f |
34 | /* Argument's exponent below -65, result rounds to 1. */ |
35 | fld1 |
36 | faddp |
37 | ret |
38 | 3: fld %st |
39 | frndint /* int(x) */ |
40 | fsubr %st,%st(1) /* fract(x) */ |
41 | fxch |
42 | f2xm1 /* 2^(fract(x)) - 1 */ |
43 | fld1 |
44 | faddp /* 2^(fract(x)) */ |
45 | fscale /* e^x */ |
46 | fstp %st(1) |
47 | LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN |
48 | ret |
49 | |
50 | 1: testl $0x200, %eax /* Test sign. */ |
51 | jz 2f /* If positive, jump. */ |
52 | fstp %st |
53 | fldz /* Set result to 0. */ |
54 | 2: ret |
55 | END (__ieee754_exp2l) |
56 | libm_alias_finite (__ieee754_exp2l, __exp2l) |
57 | |