Blame sysdeps/i386/fpu/e_atanhl.S

Packit Service 82fcde
/* ix87 specific implementation of arctanh function.
Packit Service 82fcde
   Copyright (C) 1996-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <machine/asm.h>
Packit Service 82fcde
Packit Service 82fcde
	.section .rodata
Packit Service 82fcde
Packit Service 82fcde
	.align ALIGNARG(4)
Packit Service 82fcde
	/* Please note that we use double values for 0.5 and 1.0.  These
Packit Service 82fcde
	   numbers have exact representations and so we don't get accuracy
Packit Service 82fcde
	   problems.  The advantage is that the code is simpler.  */
Packit Service 82fcde
	.type half,@object
Packit Service 82fcde
half:	.double 0.5
Packit Service 82fcde
	ASM_SIZE_DIRECTIVE(half)
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
	.align ALIGNARG(4)
Packit Service 82fcde
	.type ln2_2,@object
Packit Service 82fcde
ln2_2:	.tfloat 0.3465735902799726547086160
Packit Service 82fcde
	ASM_SIZE_DIRECTIVE(ln2_2)
Packit Service 82fcde
Packit Service 82fcde
#ifdef PIC
Packit Service 82fcde
#define MO(op) op##@GOTOFF(%edx)
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_atanhl)
Packit Service 82fcde
	movl	12(%esp), %ecx
Packit Service 82fcde
Packit Service 82fcde
	movl	%ecx, %eax
Packit Service 82fcde
	andl	$0x7fff, %eax
Packit Service 82fcde
	cmpl	$0x7fff, %eax
Packit Service 82fcde
	je	5f
Packit Service 82fcde
	cmpl	$0x3fdf, %eax
Packit Service 82fcde
	jge	7f
Packit Service 82fcde
	// Exponent below -32; return x, with underflow if subnormal.
Packit Service 82fcde
	fldt	4(%esp)
Packit Service 82fcde
	cmpl	$0, %eax
Packit Service 82fcde
	jne	8f
Packit Service 82fcde
	fld	%st(0)
Packit Service 82fcde
	fmul	%st(0)
Packit Service 82fcde
	fstp	%st(0)
Packit Service 82fcde
8:	ret
Packit Service 82fcde
7:
Packit Service 82fcde
Packit Service 82fcde
#ifdef PIC
Packit Service 82fcde
	LOAD_PIC_REG (dx)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
	andl	$0x8000, %ecx	// ECX == 0 iff X >= 0
Packit Service 82fcde
Packit Service 82fcde
	fldt	MO(ln2_2)	// 0.5*ln2
Packit Service 82fcde
	xorl	%ecx, 12(%esp)
Packit Service 82fcde
	fldt	4(%esp)		// |x| : 0.5*ln2
Packit Service 82fcde
	fcoml	MO(half)	// |x| : 0.5*ln2
Packit Service 82fcde
	fld	%st(0)		// |x| : |x| : 0.5*ln2
Packit Service 82fcde
	fnstsw			// |x| : |x| : 0.5*ln2
Packit Service 82fcde
	sahf
Packit Service 82fcde
	jae	2f
Packit Service 82fcde
	fadd	%st, %st(1)	// |x| : 2*|x| : 0.5*ln2
Packit Service 82fcde
	fld	%st		// |x| : |x| : 2*|x| : 0.5*ln2
Packit Service 82fcde
	fsubrl	MO(one)		// 1-|x| : |x| : 2*|x| : 0.5*ln2
Packit Service 82fcde
	fxch			// |x| : 1-|x| : 2*|x| : 0.5*ln2
Packit Service 82fcde
	fmul	%st(2)		// 2*|x|^2 : 1-|x| : 2*|x| : 0.5*ln2
Packit Service 82fcde
	fdivp			// (2*|x|^2)/(1-|x|) : 2*|x| : 0.5*ln2
Packit Service 82fcde
	faddp			// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
Packit Service 82fcde
	fcoml	MO(limit)	// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
Packit Service 82fcde
	fnstsw			// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
Packit Service 82fcde
	sahf
Packit Service 82fcde
	jae	4f
Packit Service 82fcde
	fyl2xp1			// 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
Packit Service 82fcde
	jecxz	3f
Packit Service 82fcde
	fchs			// 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
Packit Service 82fcde
3:	ret
Packit Service 82fcde
Packit Service 82fcde
	.align ALIGNARG(4)
Packit Service 82fcde
4:	faddl	MO(one)		// 1+2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
Packit Service 82fcde
	fyl2x			// 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
Packit Service 82fcde
	jecxz	3f
Packit Service 82fcde
	fchs			// 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
Packit Service 82fcde
3:	ret
Packit Service 82fcde
Packit Service 82fcde
	.align ALIGNARG(4)
Packit Service 82fcde
2:	faddl	MO(one)		// 1+|x| : |x| : 0.5*ln2
Packit Service 82fcde
	fxch			// |x| : 1+|x| : 0.5*ln2
Packit Service 82fcde
	fsubrl	MO(one)		// 1-|x| : 1+|x| : 0.5*ln2
Packit Service 82fcde
	fdivrp			// (1+|x|)/(1-|x|) : 0.5*ln2
Packit Service 82fcde
	fyl2x			// 0.5*ln2*ld((1+|x|)/(1-|x|))
Packit Service 82fcde
	jecxz	3f
Packit Service 82fcde
	fchs			// 0.5*ln2*ld((1+x)/(1-x))
Packit Service 82fcde
3:	ret
Packit Service 82fcde
Packit Service 82fcde
	// x == NaN or ±Inf
Packit Service 82fcde
5:	cmpl	$0x80000000, 8(%esp)
Packit Service 82fcde
	ja	6f
Packit Service 82fcde
	cmpl	$0, 4(%esp)
Packit Service 82fcde
	je	7b
Packit Service 82fcde
6:	fldt	4(%esp)
Packit Service 82fcde
	fadd	%st(0)
Packit Service 82fcde
	ret
Packit Service 82fcde
END(__ieee754_atanhl)
Packit Service 82fcde
strong_alias (__ieee754_atanhl, __atanhl_finite)