]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/libm-i387/s_asinhf.S
Update.
[thirdparty/glibc.git] / sysdeps / libm-i387 / s_asinhf.S
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 Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 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 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 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, 8(%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 call 1f
66 1: popl %edx
67 addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
68 #endif
69 cmpl $0x40000000, %eax
70 ja 5f // |x| > 2
71
72 // 2^-14 <= |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
88 4: ret
89
90 7: flds 4(%esp)
91 ret
92
93 6: faddl MO(one)
94 fyl2x
95 jecxz 4f
96 fchs
97 4: ret
98
99 // |x| < 2^-14 => y = x (inexact iff |x| != 0.0)
100 .align ALIGNARG(4)
101 2:
102 #ifdef PIC
103 call 1f
104 1: popl %edx
105 addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
106 #endif
107 jecxz 4f
108 fchs // x
109 4: fld %st // x : x
110 faddl MO(huge) // huge+x : x
111 fstp %st(0) // x
112 ret
113
114 // |x| > 2^14 => y = sign(x) * (log(|x|) + log(2))
115 .align ALIGNARG(4)
116 3: fyl2x // log(|x|)
117 fldln2 // log(2) : log(|x|)
118 faddp // log(|x|)+log(2)
119 jecxz 4f
120 fchs
121 4: ret
122
123 // |x| > 2 => y = sign(x) * log(2*|x| + 1/(|x|+sqrt(x*x+1)))
124 .align ALIGNARG(4)
125 5: 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
137 4: ret
138 END(__asinhf)
139 weak_alias (__asinhf, asinhf)