1/* ix87 specific implementation of arcsinh. 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 <libm-alias-double.h> 21 22 .section .rodata 23 24 .align ALIGNARG(4) 25 .type huge,@object 26huge: .double 1e+300 27 ASM_SIZE_DIRECTIVE(huge) 28 .type one,@object 29one: .double 1.0 30 ASM_SIZE_DIRECTIVE(one) 31 .type limit,@object 32limit: .double 0.29 33 ASM_SIZE_DIRECTIVE(limit) 34 35#ifdef PIC 36#define MO(op) op##@GOTOFF(%edx) 37#else 38#define MO(op) op 39#endif 40 41 .text 42ENTRY(__asinh) 43 movl 8(%esp), %ecx 44 movl $0x7fffffff, %eax 45 andl %ecx, %eax 46 andl $0x80000000, %ecx 47 movl %eax, %edx 48 orl $0x800fffff, %edx 49 incl %edx 50 jz 7f // x in �Inf or NaN 51 xorl %ecx, 8(%esp) 52 fldl 4(%esp) // |x| 53 cmpl $0x3e300000, %eax 54 jb 2f // |x| < 2^-28 55 fldln2 // log(2) : |x| 56 cmpl $0x41b00000, %eax 57 fxch // |x| : log(2) 58 ja 3f // |x| > 2^28 59#ifdef PIC 60 LOAD_PIC_REG (dx) 61#endif 62 cmpl $0x40000000, %eax 63 ja 5f // |x| > 2 64 65 // 2^-28 <= |x| <= 2 => y = sign(x)*log1p(|x|+|x|^2/(1+sqrt(1+|x|^2))) 66 fld %st // |x| : |x| : log(2) 67 fmul %st(1) // |x|^2 : |x| : log(2) 68 fld %st // |x|^2 : |x|^2 : |x| : log(2) 69 faddl MO(one) // 1+|x|^2 : |x|^2 : |x| : log(2) 70 fsqrt // sqrt(1+|x|^2) : |x|^2 : |x| : log(2) 71 faddl MO(one) // 1+sqrt(1+|x|^2) : |x|^2 : |x| : log(2) 72 fdivrp // |x|^2/(1+sqrt(1+|x|^2)) : |x| : log(2) 73 faddp // |x|+|x|^2/(1+sqrt(1+|x|^2)) : log(2) 74 fcoml MO(limit) 75 fnstsw 76 sahf 77 ja 6f 78 fyl2xp1 79 jecxz 4f 80 fchs 814: ret 82 837: fldl 4(%esp) 84 ret 85 866: faddl MO(one) 87 fyl2x 88 jecxz 4f 89 fchs 904: ret 91 92 // |x| < 2^-28 => y = x (inexact iff |x| != 0.0) 93 .align ALIGNARG(4) 942: 95#ifdef PIC 96 LOAD_PIC_REG (dx) 97#endif 98 jecxz 4f 99 fchs // x 1004: fld %st // x : x 101 faddl MO(huge) // huge+x : x 102 fstp %st(0) // x 103 cmpl $0x00100000, %eax 104 jae 8f 105 subl $8, %esp 106 cfi_adjust_cfa_offset (8) 107 fld %st(0) 108 fmul %st(0) 109 fstpl (%esp) 110 addl $8, %esp 111 cfi_adjust_cfa_offset (-8) 1128: ret 113 114 // |x| > 2^28 => y = sign(x) * (log(|x|) + log(2)) 115 .align ALIGNARG(4) 1163: fyl2x // log(|x|) 117 fldln2 // log(2) : log(|x|) 118 faddp // log(|x|)+log(2) 119 jecxz 4f 120 fchs 1214: ret 122 123 // |x| > 2 => y = sign(x) * log(2*|x| + 1/(|x|+sqrt(x*x+1))) 124 .align ALIGNARG(4) 1255: fld %st // |x| : |x| : log(2) 126 fadd %st, %st(1) // |x| : 2*|x| : log(2) 127 fld %st // |x| : |x| : 2*|x| : log(2) 128 fmul %st(1) // |x|^2 : |x| : 2*|x| : log(2) 129 faddl MO(one) // 1+|x|^2 : |x| : 2*|x| : log(2) 130 fsqrt // sqrt(1+|x|^2) : |x| : 2*|x| : log(2) 131 faddp // |x|+sqrt(1+|x|^2) : 2*|x| : log(2) 132 fdivrl MO(one) // 1/(|x|+sqrt(1+|x|^2)) : 2*|x| : log(2) 133 faddp // 2*|x|+1/(|x|+sqrt(1+|x|^2)) : log(2) 134 fyl2x // log(2*|x|+1/(|x|+sqrt(1+|x|^2))) 135 jecxz 4f 136 fchs 1374: ret 138END(__asinh) 139libm_alias_double (__asinh, asinh) 140