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

source code of glibc/sysdeps/i386/fpu/e_logl.S