]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/i386/fpu/s_asinhf.S
2.5-18.1
[thirdparty/glibc.git] / sysdeps / i386 / fpu / s_asinhf.S
1 /* ix87 specific implementation of arcsinh.
2 Copyright (C) 1996, 1997, 1999, 2005 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)
31 huge: .double 1e+36
32 ASM_SIZE_DIRECTIVE(huge)
33 ASM_TYPE_DIRECTIVE(one,@object)
34 one: .double 1.0
35 ASM_SIZE_DIRECTIVE(one)
36 ASM_TYPE_DIRECTIVE(limit,@object)
37 limit: .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
47 ENTRY(__asinhf)
48 movl 4(%esp), %ecx
49 movl $0x7fffffff, %eax
50 andl %ecx, %eax
51 andl $0x80000000, %ecx
52 movl %eax, %edx
53 orl $0x807fffff, %edx
54 incl %edx
55 jz 7f // x in ±Inf or NaN
56 xorl %ecx, 4(%esp)
57 flds 4(%esp) // |x|
58 cmpl $0x38000000, %eax
59 jb 2f // |x| < 2^-14
60 fldln2 // log(2) : |x|
61 cmpl $0x47000000, %eax
62 fxch // |x| : log(2)
63 ja 3f // |x| > 2^14
64 #ifdef PIC
65 LOAD_PIC_REG (dx)
66 #endif
67 cmpl $0x40000000, %eax
68 ja 5f // |x| > 2
69
70 // 2^-14 <= |x| <= 2 => y = sign(x)*log1p(|x|+|x|^2/(1+sqrt(1+|x|^2)))
71 fld %st // |x| : |x| : log(2)
72 fmul %st(1) // |x|^2 : |x| : log(2)
73 fld %st // |x|^2 : |x|^2 : |x| : log(2)
74 faddl MO(one) // 1+|x|^2 : |x|^2 : |x| : log(2)
75 fsqrt // sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
76 faddl MO(one) // 1+sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
77 fdivrp // |x|^2/(1+sqrt(1+|x|^2)) : |x| : log(2)
78 faddp // |x|+|x|^2/(1+sqrt(1+|x|^2)) : log(2)
79 fcoml MO(limit)
80 fnstsw
81 sahf
82 ja 6f
83 fyl2xp1
84 jecxz 4f
85 fchs
86 4: ret
87
88 7: flds 4(%esp)
89 ret
90
91 6: faddl MO(one)
92 fyl2x
93 jecxz 4f
94 fchs
95 4: ret
96
97 // |x| < 2^-14 => y = x (inexact iff |x| != 0.0)
98 .align ALIGNARG(4)
99 2:
100 #ifdef PIC
101 LOAD_PIC_REG (dx)
102 #endif
103 jecxz 4f
104 fchs // x
105 4: fld %st // x : x
106 faddl MO(huge) // huge+x : x
107 fstp %st(0) // x
108 ret
109
110 // |x| > 2^14 => y = sign(x) * (log(|x|) + log(2))
111 .align ALIGNARG(4)
112 3: fyl2x // log(|x|)
113 fldln2 // log(2) : log(|x|)
114 faddp // log(|x|)+log(2)
115 jecxz 4f
116 fchs
117 4: ret
118
119 // |x| > 2 => y = sign(x) * log(2*|x| + 1/(|x|+sqrt(x*x+1)))
120 .align ALIGNARG(4)
121 5: fld %st // |x| : |x| : log(2)
122 fadd %st, %st(1) // |x| : 2*|x| : log(2)
123 fld %st // |x| : |x| : 2*|x| : log(2)
124 fmul %st(1) // |x|^2 : |x| : 2*|x| : log(2)
125 faddl MO(one) // 1+|x|^2 : |x| : 2*|x| : log(2)
126 fsqrt // sqrt(1+|x|^2) : |x| : 2*|x| : log(2)
127 faddp // |x|+sqrt(1+|x|^2) : 2*|x| : log(2)
128 fdivrl MO(one) // 1/(|x|+sqrt(1+|x|^2)) : 2*|x| : log(2)
129 faddp // 2*|x|+1/(|x|+sqrt(1+|x|^2)) : log(2)
130 fyl2x // log(2*|x|+1/(|x|+sqrt(1+|x|^2)))
131 jecxz 4f
132 fchs
133 4: ret
134 END(__asinhf)
135 weak_alias (__asinhf, asinhf)