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_log10l)
31	fldlg2			// log10(2)
32	fldt	8(%rsp)		// x : log10(2)
33	fxam
34	fnstsw
35	fld	%st		// x : x : log10(2)
36	testb	$1, %ah
37	jnz	3f		// in case x is NaN or �Inf
384:	fsubl	MO(one)		// x-1 : x : log10(2)
39	fld	%st		// x-1 : x-1 : x : log10(2)
40	fabs			// |x-1| : x-1 : x : log10(2)
41	fcompl	MO(limit)	// x-1 : x : log10(2)
42	fnstsw			// x-1 : x : log10(2)
43	andb	$0x45, %ah
44	jz	2f
45	fxam
46	fnstsw
47	andb	$0x45, %ah
48	cmpb	$0x40, %ah
49	jne	5f
50	fabs			// log10(1) is +0 in all rounding modes.
515:	fstp	%st(1)		// x-1 : log10(2)
52	fyl2xp1			// log10(x)
53	ret
54
552:	fstp	%st(0)		// x : log10(2)
56	fyl2x			// log10(x)
57	ret
58
593:	testb	$4, %ah
60	jnz	4b		// in case x is �Inf
61	fstp	%st(1)
62	fstp	%st(1)
63	fadd	%st(0)
64	ret
65END(__ieee754_log10l)
66
67
68ENTRY(__log10l_finite)
69	fldlg2			// log10(2)
70	fldt	8(%rsp)		// x : log10(2)
71	fld	%st		// x : x : log10(2)
724:	fsubl	MO(one)		// x-1 : x : log10(2)
73	fld	%st		// x-1 : x-1 : x : log10(2)
74	fabs			// |x-1| : x-1 : x : log10(2)
75	fcompl	MO(limit)	// x-1 : x : log10(2)
76	fnstsw			// x-1 : x : log10(2)
77	andb	$0x45, %ah
78	jz	2b
79	fxam
80	fnstsw
81	andb	$0x45, %ah
82	cmpb	$0x40, %ah
83	jne	6f
84	fabs			// log10(1) is +0 in all rounding modes.
856:	fstp	%st(1)		// x-1 : log10(2)
86	fyl2xp1			// log10(x)
87	ret
88END(__log10l_finite)
89libm_alias_finite (__log10l_finite, __log10l)
90