1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 *
5 * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
6 *
7 * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
8 * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
9 */
10
11#include <machine/asm.h>
12#include <libm-alias-finite.h>
13
14 .section .rodata.cst8,"aM",@progbits,8
15
16 .p2align 3
17 .type one,@object
18one: .double 1.0
19 ASM_SIZE_DIRECTIVE(one)
20 /* It is not important that this constant is precise. It is only
21 a value which is known to be on the safe side for using the
22 fyl2xp1 instruction. */
23 .type limit,@object
24limit: .double 0.29
25 ASM_SIZE_DIRECTIVE(limit)
26
27
28#ifdef PIC
29# define MO(op) op##(%rip)
30#else
31# define MO(op) op
32#endif
33
34 .text
35ENTRY(__ieee754_log10l)
36 fldlg2 // log10(2)
37 fldt 8(%rsp) // x : log10(2)
38 fxam
39 fnstsw
40 fld %st // x : x : log10(2)
41 testb $1, %ah
42 jnz 3f // in case x is NaN or ħInf
434: fsubl MO(one) // x-1 : x : log10(2)
44 fld %st // x-1 : x-1 : x : log10(2)
45 fabs // |x-1| : x-1 : x : log10(2)
46 fcompl MO(limit) // x-1 : x : log10(2)
47 fnstsw // x-1 : x : log10(2)
48 andb $0x45, %ah
49 jz 2f
50 fxam
51 fnstsw
52 andb $0x45, %ah
53 cmpb $0x40, %ah
54 jne 5f
55 fabs // log10(1) is +0 in all rounding modes.
565: fstp %st(1) // x-1 : log10(2)
57 fyl2xp1 // log10(x)
58 ret
59
602: fstp %st(0) // x : log10(2)
61 fyl2x // log10(x)
62 ret
63
643: testb $4, %ah
65 jnz 4b // in case x is ħInf
66 fstp %st(1)
67 fstp %st(1)
68 fadd %st(0)
69 ret
70END(__ieee754_log10l)
71
72
73ENTRY(__log10l_finite)
74 fldlg2 // log10(2)
75 fldt 8(%rsp) // x : log10(2)
76 fld %st // x : x : log10(2)
774: fsubl MO(one) // x-1 : x : log10(2)
78 fld %st // x-1 : x-1 : x : log10(2)
79 fabs // |x-1| : x-1 : x : log10(2)
80 fcompl MO(limit) // x-1 : x : log10(2)
81 fnstsw // x-1 : x : log10(2)
82 andb $0x45, %ah
83 jz 2b
84 fxam
85 fnstsw
86 andb $0x45, %ah
87 cmpb $0x40, %ah
88 jne 6f
89 fabs // log10(1) is +0 in all rounding modes.
906: fstp %st(1) // x-1 : log10(2)
91 fyl2xp1 // log10(x)
92 ret
93END(__log10l_finite)
94libm_alias_finite (__log10l_finite, __log10l)
95