1/* ix87 specific implementation of arcsinh. 2 Copyright (C) 1996, 1997 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library; if not, write to the Free 18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19 02111-1307 USA. */ 20 21#include <machine/asm.h> 22 23#ifdef __ELF__ 24 .section .rodata 25#else 26 .text 27#endif 28 29 .align ALIGNARG(4) 30 ASM_TYPE_DIRECTIVE(huge,@object) 31huge: .double 1e+300 32 ASM_SIZE_DIRECTIVE(huge) 33 ASM_TYPE_DIRECTIVE(one,@object) 34one: .double 1.0 35 ASM_SIZE_DIRECTIVE(one) 36 ASM_TYPE_DIRECTIVE(limit,@object) 37limit: .double 0.29 38 ASM_SIZE_DIRECTIVE(limit) 39 40#ifdef PIC 41#define MO(op) op##@GOTOFF(%edx) 42#else 43#define MO(op) op 44#endif 45 46 .text 47ENTRY(__asinh) 48 movl 8(%esp), %ecx 49 movl $0x7fffffff, %eax 50 andl %ecx, %eax 51 andl $0x80000000, %ecx 52 movl %eax, %edx 53 orl $0x800fffff, %edx 54 incl %edx 55 jz 7f // x in �Inf or NaN 56 xorl %ecx, 8(%esp) 57 fldl 4(%esp) // |x| 58 cmpl $0x3e300000, %eax 59 jb 2f // |x| < 2^-28 60 fldln2 // log(2) : |x| 61 cmpl $0x41b00000, %eax 62 fxch // |x| : log(2) 63 ja 3f // |x| > 2^28 64#ifdef PIC 65 call 1f 661: popl %edx 67 addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx 68#endif 69 cmpl $0x40000000, %eax 70 ja 5f // |x| > 2 71 72 // 2^-28 <= |x| <= 2 => y = sign(x)*log1p(|x|+|x|^2/(1+sqrt(1+|x|^2))) 73 fld %st // |x| : |x| : log(2) 74 fmul %st(1) // |x|^2 : |x| : log(2) 75 fld %st // |x|^2 : |x|^2 : |x| : log(2) 76 faddl MO(one) // 1+|x|^2 : |x|^2 : |x| : log(2) 77 fsqrt // sqrt(1+|x|^2) : |x|^2 : |x| : log(2) 78 faddl MO(one) // 1+sqrt(1+|x|^2) : |x|^2 : |x| : log(2) 79 fdivrp // |x|^2/(1+sqrt(1+|x|^2)) : |x| : log(2) 80 faddp // |x|+|x|^2/(1+sqrt(1+|x|^2)) : log(2) 81 fcoml MO(limit) 82 fnstsw 83 sahf 84 ja 6f 85 fyl2xp1 86 jecxz 4f 87 fchs 884: ret 89 907: fldl 4(%esp) 91 ret 92 936: faddl MO(one) 94 fyl2x 95 jecxz 4f 96 fchs 974: ret 98 99 // |x| < 2^-28 => y = x (inexact iff |x| != 0.0) 100 .align ALIGNARG(4) 1012: 102#ifdef PIC 103 call 1f 1041: popl %edx 105 addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx 106#endif 107 jecxz 4f 108 fchs // x 1094: fld %st // x : x 110 faddl MO(huge) // huge+x : x 111 fstp %st(0) // x 112 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) 139weak_alias (__asinh, asinh) 140