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##(%rip) 25#else 26# define MO(op) op 27#endif 28 29 .text 30ENTRY(__ieee754_logl) 31 fldln2 // log(2) 32 fldt 8(%rsp) // x : log(2) 33 fxam 34 fnstsw 35 fld %st // x : x : log(2) 36 testb $1, %ah 37 jnz 3f // in case x is NaN or +-Inf 38 movzwl 8+8(%rsp), %eax 39 cmpl $0xc000, %eax 40 jae 6f // x <= -2, avoid overflow from -LDBL_MAX - 1. 414: fsubl MO(one) // x-1 : x : log(2) 426: fld %st // x-1 : x-1 : x : log(2) 43 fabs // |x-1| : x-1 : x : log(2) 44 fcompl MO(limit) // x-1 : x : log(2) 45 fnstsw // x-1 : x : log(2) 46 andb $0x45, %ah 47 jz 2f 48 fxam 49 fnstsw 50 andb $0x45, %ah 51 cmpb $0x40, %ah 52 jne 5f 53 fabs // log(1) is +0 in all rounding modes. 545: fstp %st(1) // x-1 : log(2) 55 fyl2xp1 // log(x) 56 ret 57 582: fstp %st(0) // x : log(2) 59 fyl2x // log(x) 60 ret 61 623: testb $4, %ah 63 jnz 4b // in case x is +-Inf 64 fstp %st(1) 65 fstp %st(1) 66 fadd %st(0) 67 ret 68END (__ieee754_logl) 69 70 71ENTRY(__logl_finite) 72 fldln2 // log(2) 73 fldt 8(%rsp) // x : log(2) 74 fld %st // x : x : log(2) 75 fsubl MO(one) // x-1 : x : log(2) 76 fld %st // x-1 : x-1 : x : log(2) 77 fabs // |x-1| : x-1 : x : log(2) 78 fcompl MO(limit) // x-1 : x : log(2) 79 fnstsw // x-1 : x : log(2) 80 andb $0x45, %ah 81 jz 2b 82 fxam 83 fnstsw 84 andb $0x45, %ah 85 cmpb $0x40, %ah 86 jne 7f 87 fabs // log(1) is +0 in all rounding modes. 887: fstp %st(1) // x-1 : log(2) 89 fyl2xp1 // log(x) 90 ret 91END (__logl_finite) 92libm_alias_finite (__logl_finite, __logl) 93