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