| 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 | |