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