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