1/* ix87 specific implementation of arctanh function. 2 Copyright (C) 1996-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19#include <machine/asm.h> 20#include <i386-math-asm.h> 21#include <libm-alias-finite.h> 22 23 .section .rodata 24 25 .align ALIGNARG(4) 26 .type half,@object 27half: .double 0.5 28 ASM_SIZE_DIRECTIVE(half) 29 .type one,@object 30one: .double 1.0 31 ASM_SIZE_DIRECTIVE(one) 32 .type limit,@object 33limit: .double 0.29 34 ASM_SIZE_DIRECTIVE(limit) 35 .type ln2_2,@object 36ln2_2: .tfloat 0.3465735902799726547086160 37 ASM_SIZE_DIRECTIVE(ln2_2) 38 39DEFINE_DBL_MIN 40 41#ifdef PIC 42#define MO(op) op##@GOTOFF(%edx) 43#else 44#define MO(op) op 45#endif 46 47 .text 48ENTRY(__ieee754_atanh) 49 movl 8(%esp), %ecx 50 51 movl %ecx, %eax 52 andl $0x7fffffff, %eax 53 cmpl $0x7ff00000, %eax 54 jae 5f 557: 56 57#ifdef PIC 58 LOAD_PIC_REG (dx) 59#endif 60 61 andl $0x80000000, %ecx // ECX == 0 iff X >= 0 62 63 fldt MO(ln2_2) // 0.5*ln2 64 xorl %ecx, 8(%esp) 65 fldl 4(%esp) // |x| : 0.5*ln2 66 fcoml MO(half) // |x| : 0.5*ln2 67 fld %st // |x| : |x| : 0.5*ln2 68 fnstsw // |x| : |x| : 0.5*ln2 69 sahf 70 jae 2f 71 fadd %st, %st(1) // |x| : 2*|x| : 0.5*ln2 72 fld %st // |x| : |x| : 2*|x| : 0.5*ln2 73 fsubrl MO(one) // 1-|x| : |x| : 2*|x| : 0.5*ln2 74 fxch // |x| : 1-|x| : 2*|x| : 0.5*ln2 75 fmul %st(2) // 2*|x|^2 : 1-|x| : 2*|x| : 0.5*ln2 76 fdivp // (2*|x|^2)/(1-|x|) : 2*|x| : 0.5*ln2 77 faddp // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2 78 fcoml MO(limit) // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2 79 fnstsw // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2 80 sahf 81 jae 4f 82 fyl2xp1 // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|)) 83 DBL_CHECK_FORCE_UFLOW_NONNEG 84 jecxz 3f 85 fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x)) 863: ret 87 88 .align ALIGNARG(4) 894: faddl MO(one) // 1+2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2 90 fyl2x // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|)) 91 jecxz 3f 92 fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x)) 933: ret 94 95 .align ALIGNARG(4) 962: faddl MO(one) // 1+|x| : |x| : 0.5*ln2 97 fxch // |x| : 1+|x| : 0.5*ln2 98 fsubrl MO(one) // 1-|x| : 1+|x| : 0.5*ln2 99 fdivrp // (1+|x|)/(1-|x|) : 0.5*ln2 100 fyl2x // 0.5*ln2*ld((1+|x|)/(1-|x|)) 101 jecxz 3f 102 fchs // 0.5*ln2*ld((1+x)/(1-x)) 1033: ret 104 105 // x == NaN or �Inf 1065: ja 6f 107 cmpl $0, 4(%esp) 108 je 7b 1096: fldl 4(%esp) 110 ret 111END(__ieee754_atanh) 112libm_alias_finite (__ieee754_atanh, __atanh) 113