Blame sysdeps/i386/fpu/e_acoshl.S

Packit Service 82fcde
/* ix87 specific implementation of arcsinh.
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.cst8,"aM",@progbits,8
Packit Service 82fcde
Packit Service 82fcde
	.p2align 3
Packit Service 82fcde
	/* Please note that we use double value for 1.0.  This number
Packit Service 82fcde
	   has an exact representation and so we don't get accuracy
Packit Service 82fcde
	   problems.  The advantage is that the code is simpler.  */
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
#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_acoshl)
Packit Service 82fcde
	movl	12(%esp), %ecx
Packit Service 82fcde
	andl	$0xffff, %ecx
Packit Service 82fcde
	cmpl	$0x3fff, %ecx
Packit Service 82fcde
	jl	5f			// < 1 => invalid
Packit Service 82fcde
	fldln2				// log(2)
Packit Service 82fcde
	fldt	4(%esp)			// x : log(2)
Packit Service 82fcde
	cmpl	$0x4020, %ecx
Packit Service 82fcde
	ja	3f			// x > 2^34
Packit Service 82fcde
#ifdef	PIC
Packit Service 82fcde
	LOAD_PIC_REG (dx)
Packit Service 82fcde
#endif
Packit Service 82fcde
	cmpl	$0x4000, %ecx
Packit Service 82fcde
	ja	4f			// x > 2
Packit Service 82fcde
Packit Service 82fcde
	// 1 <= x <= 2 => y = log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
Packit Service 82fcde
	fsubl	MO(one)			// x-1 : log(2)
Packit Service 82fcde
	fabs				// acosh(1) is +0 in all rounding modes
Packit Service 82fcde
	fld	%st			// x-1 : x-1 : log(2)
Packit Service 82fcde
	fmul	%st(1)			// (x-1)^2 : x-1 : log(2)
Packit Service 82fcde
	fadd	%st(1)			// x-1+(x-1)^2 : x-1 : log(2)
Packit Service 82fcde
	fadd	%st(1)			// 2*(x-1)+(x-1)^2 : x-1 : log(2)
Packit Service 82fcde
	fsqrt				// sqrt(2*(x-1)+(x-1)^2) : x-1 : log(2)
Packit Service 82fcde
	faddp				// x-1+sqrt(2*(x-1)+(x-1)^2) : log(2)
Packit Service 82fcde
	fcoml	MO(limit)
Packit Service 82fcde
	fnstsw
Packit Service 82fcde
	sahf
Packit Service 82fcde
	ja	2f
Packit Service 82fcde
	fyl2xp1				// log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
Packit Service 82fcde
	ret
Packit Service 82fcde
Packit Service 82fcde
2:	faddl	MO(one)			// x+sqrt(2*(x-1)+(x-1)^2) : log(2)
Packit Service 82fcde
	fyl2x				// log(x+sqrt(2*(x-1)+(x-1)^2))
Packit Service 82fcde
	ret
Packit Service 82fcde
Packit Service 82fcde
	// x > 2^34 => y = log(x) + log(2)
Packit Service 82fcde
	.align ALIGNARG(4)
Packit Service 82fcde
3:	fyl2x				// log(x)
Packit Service 82fcde
	fldln2				// log(2) : log(x)
Packit Service 82fcde
	faddp				// log(x)+log(2)
Packit Service 82fcde
	ret
Packit Service 82fcde
Packit Service 82fcde
	// 2^34 > x > 2 => y = log(2*x - 1/(x+sqrt(x*x-1)))
Packit Service 82fcde
	.align ALIGNARG(4)
Packit Service 82fcde
4:	fld	%st			// x : x : log(2)
Packit Service 82fcde
	fadd	%st, %st(1)		// x : 2*x : log(2)
Packit Service 82fcde
	fld	%st			// x : x : 2*x : log(2)
Packit Service 82fcde
	fmul	%st(1)			// x^2 : x : 2*x : log(2)
Packit Service 82fcde
	fsubl	MO(one)			// x^2-1 : x : 2*x : log(2)
Packit Service 82fcde
	fsqrt				// sqrt(x^2-1) : x : 2*x : log(2)
Packit Service 82fcde
	faddp				// x+sqrt(x^2-1) : 2*x : log(2)
Packit Service 82fcde
	fdivrl	MO(one)			// 1/(x+sqrt(x^2-1)) : 2*x : log(2)
Packit Service 82fcde
	fsubrp				// 2*x+1/(x+sqrt(x^2)-1) : log(2)
Packit Service 82fcde
	fyl2x				// log(2*x+1/(x+sqrt(x^2-1)))
Packit Service 82fcde
	ret
Packit Service 82fcde
Packit Service 82fcde
	// x < 1 => NaN
Packit Service 82fcde
	.align ALIGNARG(4)
Packit Service 82fcde
5:	fldz
Packit Service 82fcde
	fdiv	%st, %st(0)
Packit Service 82fcde
	ret
Packit Service 82fcde
END(__ieee754_acoshl)
Packit Service 82fcde
strong_alias (__ieee754_acoshl, __acoshl_finite)