1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 *
5 * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
6 */
7
8#include <machine/asm.h>
9
10RCSID("$NetBSD: e_log.S,v 1.4 1995/05/08 23:48:39 jtc Exp $")
11
12#ifdef __ELF__
13	.section .rodata
14#else
15	.text
16#endif
17	.align ALIGNARG(4)
18	ASM_TYPE_DIRECTIVE(one,@object)
19one:	.double 1.0
20	ASM_SIZE_DIRECTIVE(one)
21	/* It is not important that this constant is precise.  It is only
22	   a value which is known to be on the safe side for using the
23	   fyl2xp1 instruction.  */
24	ASM_TYPE_DIRECTIVE(limit,@object)
25limit:	.double 0.29
26	ASM_SIZE_DIRECTIVE(limit)
27
28
29#ifdef PIC
30#define MO(op) op##@GOTOFF(%edx)
31#else
32#define MO(op) op
33#endif
34
35	.text
36ENTRY(__ieee754_log)
37	fldln2			// log(2)
38	fldl	4(%esp)		// x : log(2)
39#ifdef PIC
40	call	1f
411:	popl	%edx
42	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
43#endif
44	fld	%st		// x : x : log(2)
45	fsubl	MO(one)		// x-1 : x : log(2)
46	fld	%st		// x-1 : x-1 : x : log(2)
47	fabs			// |x-1| : x-1 : x : log(2)
48	fcompl	MO(limit)	// x-1 : x : log(2)
49	fnstsw			// x-1 : x : log(2)
50	andb	$0x45, %ah
51	jz	2f
52	fstp	%st(1)		// x-1 : log(2)
53	fyl2xp1			// log(x)
54	ret
55
562:	fstp	%st(0)		// x : log(2)
57	fyl2x			// log(x)
58	ret
59END (__ieee754_log)
60