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