1/* 2 * Public domain. 3 * 4 */ 5 6#include <machine/asm.h> 7#include <libm-alias-finite.h> 8 9 .section .rodata.cst8,"aM",@progbits,8 10 11 .p2align 3 12 .type one,@object 13one: .double 1.0 14 ASM_SIZE_DIRECTIVE(one) 15 /* It is not important that this constant is precise. It is only 16 a value which is known to be on the safe side for using the 17 fyl2xp1 instruction. */ 18 .type limit,@object 19limit: .double 0.29 20 ASM_SIZE_DIRECTIVE(limit) 21 22 23#ifdef PIC 24# define MO(op) op##@GOTOFF(%edx) 25#else 26# define MO(op) op 27#endif 28 29 .text 30ENTRY(__ieee754_logl) 31 fldln2 // log(2) 32 fldt 4(%esp) // x : log(2) 33 fxam 34 fnstsw 35#ifdef PIC 36 LOAD_PIC_REG (dx) 37#endif 38 fld %st // x : x : log(2) 39 sahf 40 jc 3f // in case x is NaN or +-Inf 41 movzwl 4+8(%esp), %eax 42 cmpl $0xc000, %eax 43 jae 6f // x <= -2, avoid overflow from -LDBL_MAX - 1. 444: fsubl MO(one) // x-1 : x : log(2) 456: fld %st // x-1 : x-1 : x : log(2) 46 fabs // |x-1| : x-1 : x : log(2) 47 fcompl MO(limit) // x-1 : x : log(2) 48 fnstsw // x-1 : x : log(2) 49 andb $0x45, %ah 50 jz 2f 51 fxam 52 fnstsw 53 andb $0x45, %ah 54 cmpb $0x40, %ah 55 jne 5f 56 fabs // log(1) is +0 in all rounding modes. 575: fstp %st(1) // x-1 : log(2) 58 fyl2xp1 // log(x) 59 ret 60 612: fstp %st(0) // x : log(2) 62 fyl2x // log(x) 63 ret 64 653: jp 4b // in case x is +-Inf 66 fstp %st(1) 67 fstp %st(1) 68 fadd %st(0) 69 ret 70END (__ieee754_logl) 71 72ENTRY(__logl_finite) 73 fldln2 // log(2) 74 fldt 4(%esp) // x : log(2) 75#ifdef PIC 76 LOAD_PIC_REG (dx) 77#endif 78 fld %st // x : x : log(2) 79 fsubl MO(one) // x-1 : x : log(2) 80 fld %st // x-1 : x-1 : x : log(2) 81 fabs // |x-1| : x-1 : x : log(2) 82 fcompl MO(limit) // x-1 : x : log(2) 83 fnstsw // x-1 : x : log(2) 84 andb $0x45, %ah 85 jz 2b 86 fxam 87 fnstsw 88 andb $0x45, %ah 89 cmpb $0x40, %ah 90 jne 7f 91 fabs // log(1) is +0 in all rounding modes. 927: fstp %st(1) // x-1 : log(2) 93 fyl2xp1 // log(x) 94 ret 95END(__logl_finite) 96libm_alias_finite (__logl_finite, __logl) 97