Blame sysdeps/i386/fpu/e_acoshl.S

Packit 6c4009
/* ix87 specific implementation of arcsinh.
Packit 6c4009
   Copyright (C) 1996-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <machine/asm.h>
Packit 6c4009
Packit 6c4009
	.section .rodata.cst8,"aM",@progbits,8
Packit 6c4009
Packit 6c4009
	.p2align 3
Packit 6c4009
	/* Please note that we use double value for 1.0.  This number
Packit 6c4009
	   has an exact representation and so we don't get accuracy
Packit 6c4009
	   problems.  The advantage is that the code is simpler.  */
Packit 6c4009
	.type one,@object
Packit 6c4009
one:	.double 1.0
Packit 6c4009
	ASM_SIZE_DIRECTIVE(one)
Packit 6c4009
	/* It is not important that this constant is precise.  It is only
Packit 6c4009
	   a value which is known to be on the safe side for using the
Packit 6c4009
	   fyl2xp1 instruction.  */
Packit 6c4009
	.type limit,@object
Packit 6c4009
limit:	.double 0.29
Packit 6c4009
	ASM_SIZE_DIRECTIVE(limit)
Packit 6c4009
Packit 6c4009
#ifdef PIC
Packit 6c4009
#define MO(op) op##@GOTOFF(%edx)
Packit 6c4009
#else
Packit 6c4009
#define MO(op) op
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
	.text
Packit 6c4009
ENTRY(__ieee754_acoshl)
Packit 6c4009
	movl	12(%esp), %ecx
Packit 6c4009
	andl	$0xffff, %ecx
Packit 6c4009
	cmpl	$0x3fff, %ecx
Packit 6c4009
	jl	5f			// < 1 => invalid
Packit 6c4009
	fldln2				// log(2)
Packit 6c4009
	fldt	4(%esp)			// x : log(2)
Packit 6c4009
	cmpl	$0x4020, %ecx
Packit 6c4009
	ja	3f			// x > 2^34
Packit 6c4009
#ifdef	PIC
Packit 6c4009
	LOAD_PIC_REG (dx)
Packit 6c4009
#endif
Packit 6c4009
	cmpl	$0x4000, %ecx
Packit 6c4009
	ja	4f			// x > 2
Packit 6c4009
Packit 6c4009
	// 1 <= x <= 2 => y = log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
Packit 6c4009
	fsubl	MO(one)			// x-1 : log(2)
Packit 6c4009
	fabs				// acosh(1) is +0 in all rounding modes
Packit 6c4009
	fld	%st			// x-1 : x-1 : log(2)
Packit 6c4009
	fmul	%st(1)			// (x-1)^2 : x-1 : log(2)
Packit 6c4009
	fadd	%st(1)			// x-1+(x-1)^2 : x-1 : log(2)
Packit 6c4009
	fadd	%st(1)			// 2*(x-1)+(x-1)^2 : x-1 : log(2)
Packit 6c4009
	fsqrt				// sqrt(2*(x-1)+(x-1)^2) : x-1 : log(2)
Packit 6c4009
	faddp				// x-1+sqrt(2*(x-1)+(x-1)^2) : log(2)
Packit 6c4009
	fcoml	MO(limit)
Packit 6c4009
	fnstsw
Packit 6c4009
	sahf
Packit 6c4009
	ja	2f
Packit 6c4009
	fyl2xp1				// log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
Packit 6c4009
	ret
Packit 6c4009
Packit 6c4009
2:	faddl	MO(one)			// x+sqrt(2*(x-1)+(x-1)^2) : log(2)
Packit 6c4009
	fyl2x				// log(x+sqrt(2*(x-1)+(x-1)^2))
Packit 6c4009
	ret
Packit 6c4009
Packit 6c4009
	// x > 2^34 => y = log(x) + log(2)
Packit 6c4009
	.align ALIGNARG(4)
Packit 6c4009
3:	fyl2x				// log(x)
Packit 6c4009
	fldln2				// log(2) : log(x)
Packit 6c4009
	faddp				// log(x)+log(2)
Packit 6c4009
	ret
Packit 6c4009
Packit 6c4009
	// 2^34 > x > 2 => y = log(2*x - 1/(x+sqrt(x*x-1)))
Packit 6c4009
	.align ALIGNARG(4)
Packit 6c4009
4:	fld	%st			// x : x : log(2)
Packit 6c4009
	fadd	%st, %st(1)		// x : 2*x : log(2)
Packit 6c4009
	fld	%st			// x : x : 2*x : log(2)
Packit 6c4009
	fmul	%st(1)			// x^2 : x : 2*x : log(2)
Packit 6c4009
	fsubl	MO(one)			// x^2-1 : x : 2*x : log(2)
Packit 6c4009
	fsqrt				// sqrt(x^2-1) : x : 2*x : log(2)
Packit 6c4009
	faddp				// x+sqrt(x^2-1) : 2*x : log(2)
Packit 6c4009
	fdivrl	MO(one)			// 1/(x+sqrt(x^2-1)) : 2*x : log(2)
Packit 6c4009
	fsubrp				// 2*x+1/(x+sqrt(x^2)-1) : log(2)
Packit 6c4009
	fyl2x				// log(2*x+1/(x+sqrt(x^2-1)))
Packit 6c4009
	ret
Packit 6c4009
Packit 6c4009
	// x < 1 => NaN
Packit 6c4009
	.align ALIGNARG(4)
Packit 6c4009
5:	fldz
Packit 6c4009
	fdiv	%st, %st(0)
Packit 6c4009
	ret
Packit 6c4009
END(__ieee754_acoshl)
Packit 6c4009
strong_alias (__ieee754_acoshl, __acoshl_finite)