Blame sysdeps/x86_64/fpu/e_log2l.S

Packit Service 82fcde
/*
Packit Service 82fcde
 * Written by J.T. Conklin <jtc@netbsd.org>.
Packit Service 82fcde
 * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
Packit Service 82fcde
 * Public domain.
Packit Service 82fcde
 *
Packit Service 82fcde
 * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
Packit Service 82fcde
 * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
#include <machine/asm.h>
Packit Service 82fcde
Packit Service 82fcde
	.section .rodata.cst8,"aM",@progbits,8
Packit Service 82fcde
Packit Service 82fcde
	.p2align 3
Packit Service 82fcde
	.type one,@object
Packit Service 82fcde
one:	.double 1.0
Packit Service 82fcde
	ASM_SIZE_DIRECTIVE(one)
Packit Service 82fcde
	/* It is not important that this constant is precise.  It is only
Packit Service 82fcde
	   a value which is known to be on the safe side for using the
Packit Service 82fcde
	   fyl2xp1 instruction.  */
Packit Service 82fcde
	.type limit,@object
Packit Service 82fcde
limit:	.double 0.29
Packit Service 82fcde
	ASM_SIZE_DIRECTIVE(limit)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
#ifdef PIC
Packit Service 82fcde
# define MO(op) op##(%rip)
Packit Service 82fcde
#else
Packit Service 82fcde
# define MO(op) op
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
	.text
Packit Service 82fcde
ENTRY(__ieee754_log2l)
Packit Service 82fcde
	fldl	MO(one)
Packit Service 82fcde
	fldt	8(%rsp)		// x : 1
Packit Service 82fcde
	fxam
Packit Service 82fcde
	fnstsw
Packit Service 82fcde
	fld	%st		// x : x : 1
Packit Service 82fcde
	testb	$1, %ah
Packit Service 82fcde
	jnz	3f		// in case x is NaN or ±Inf
Packit Service 82fcde
4:	fsub	%st(2), %st	// x-1 : x : 1
Packit Service 82fcde
	fld	%st		// x-1 : x-1 : x : 1
Packit Service 82fcde
	fabs			// |x-1| : x-1 : x : 1
Packit Service 82fcde
	fcompl	MO(limit)	// x-1 : x : 1
Packit Service 82fcde
	fnstsw			// x-1 : x : 1
Packit Service 82fcde
	andb	$0x45, %ah
Packit Service 82fcde
	jz	2f
Packit Service 82fcde
	fxam
Packit Service 82fcde
	fnstsw
Packit Service 82fcde
	andb	$0x45, %ah
Packit Service 82fcde
	cmpb	$0x40, %ah
Packit Service 82fcde
	jne	5f
Packit Service 82fcde
	fabs			// log2(1) is +0 in all rounding modes.
Packit Service 82fcde
5:	fstp	%st(1)		// x-1 : 1
Packit Service 82fcde
	fyl2xp1			// log(x)
Packit Service 82fcde
	ret
Packit Service 82fcde
Packit Service 82fcde
2:	fstp	%st(0)		// x : 1
Packit Service 82fcde
	fyl2x			// log(x)
Packit Service 82fcde
	ret
Packit Service 82fcde
Packit Service 82fcde
3:	testb	$4, %ah
Packit Service 82fcde
	jnz	4b		// in case x is ±Inf
Packit Service 82fcde
	fstp	%st(1)
Packit Service 82fcde
	fstp	%st(1)
Packit Service 82fcde
	fadd	%st(0)
Packit Service 82fcde
	ret
Packit Service 82fcde
END (__ieee754_log2l)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
ENTRY(__log2l_finite)
Packit Service 82fcde
	fldl	MO(one)
Packit Service 82fcde
	fldt	8(%rsp)		// x : 1
Packit Service 82fcde
	fld	%st		// x : x : 1
Packit Service 82fcde
	fsub	%st(2), %st	// x-1 : x : 1
Packit Service 82fcde
	fld	%st		// x-1 : x-1 : x : 1
Packit Service 82fcde
	fabs			// |x-1| : x-1 : x : 1
Packit Service 82fcde
	fcompl	MO(limit)	// x-1 : x : 1
Packit Service 82fcde
	fnstsw			// x-1 : x : 1
Packit Service 82fcde
	andb	$0x45, %ah
Packit Service 82fcde
	jz	2b
Packit Service 82fcde
	fxam
Packit Service 82fcde
	fnstsw
Packit Service 82fcde
	andb	$0x45, %ah
Packit Service 82fcde
	cmpb	$0x40, %ah
Packit Service 82fcde
	jne	6f
Packit Service 82fcde
	fabs			// log2(1) is +0 in all rounding modes.
Packit Service 82fcde
6:	fstp	%st(1)		// x-1 : 1
Packit Service 82fcde
	fyl2xp1			// log(x)
Packit Service 82fcde
	ret
Packit Service 82fcde
END (__log2l_finite)