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-finite.h> |
21 | |
22 | .section .rodata.cst8,"aM" ,@progbits,8 |
23 | |
24 | .p2align 3 |
25 | .type one,@object |
26 | one: .double 1.0 |
27 | ASM_SIZE_DIRECTIVE(one) |
28 | .type limit,@object |
29 | limit: .double 0.29 |
30 | ASM_SIZE_DIRECTIVE(limit) |
31 | |
32 | #ifdef PIC |
33 | #define MO(op) op##@GOTOFF(%edx) |
34 | #else |
35 | #define MO(op) op |
36 | #endif |
37 | |
38 | .text |
39 | ENTRY(__ieee754_acosh) |
40 | movl 8(%esp), %ecx |
41 | cmpl $0x3ff00000, %ecx |
42 | jl 5f // < 1 => invalid |
43 | fldln2 // log(2) |
44 | fldl 4(%esp) // x : log(2) |
45 | cmpl $0x41b00000, %ecx |
46 | ja 3f // x > 2^28 |
47 | #ifdef PIC |
48 | LOAD_PIC_REG (dx) |
49 | #endif |
50 | cmpl $0x40000000, %ecx |
51 | ja 4f // x > 2 |
52 | |
53 | // 1 <= x <= 2 => y = log1p(x-1+sqrt(2*(x-1)+(x-1)^2)) |
54 | fsubl MO(one) // x-1 : log(2) |
55 | fabs // acosh(1) is +0 in all rounding modes |
56 | fld %st // x-1 : x-1 : log(2) |
57 | fmul %st(1) // (x-1)^2 : x-1 : log(2) |
58 | fadd %st(1) // x-1+(x-1)^2 : x-1 : log(2) |
59 | fadd %st(1) // 2*(x-1)+(x-1)^2 : x-1 : log(2) |
60 | fsqrt // sqrt(2*(x-1)+(x-1)^2) : x-1 : log(2) |
61 | faddp // x-1+sqrt(2*(x-1)+(x-1)^2) : log(2) |
62 | fcoml MO(limit) |
63 | fnstsw |
64 | sahf |
65 | ja 2f |
66 | fyl2xp1 // log1p(x-1+sqrt(2*(x-1)+(x-1)^2)) |
67 | ret |
68 | |
69 | 2: faddl MO(one) // x+sqrt(2*(x-1)+(x-1)^2) : log(2) |
70 | fyl2x // log(x+sqrt(2*(x-1)+(x-1)^2)) |
71 | ret |
72 | |
73 | // x > 2^28 => y = log(x) + log(2) |
74 | .align ALIGNARG(4) |
75 | 3: fyl2x // log(x) |
76 | fldln2 // log(2) : log(x) |
77 | faddp // log(x)+log(2) |
78 | ret |
79 | |
80 | // 2^28 > x > 2 => y = log(2*x - 1/(x+sqrt(x*x-1))) |
81 | .align ALIGNARG(4) |
82 | 4: fld %st // x : x : log(2) |
83 | fadd %st, %st(1) // x : 2*x : log(2) |
84 | fld %st // x : x : 2*x : log(2) |
85 | fmul %st(1) // x^2 : x : 2*x : log(2) |
86 | fsubl MO(one) // x^2-1 : x : 2*x : log(2) |
87 | fsqrt // sqrt(x^2-1) : x : 2*x : log(2) |
88 | faddp // x+sqrt(x^2-1) : 2*x : log(2) |
89 | fdivrl MO(one) // 1/(x+sqrt(x^2-1)) : 2*x : log(2) |
90 | fsubrp // 2*x+1/(x+sqrt(x^2)-1) : log(2) |
91 | fyl2x // log(2*x+1/(x+sqrt(x^2-1))) |
92 | ret |
93 | |
94 | // x < 1 (or -NaN) => NaN |
95 | .align ALIGNARG(4) |
96 | 5: fldl 4(%esp) |
97 | fsub %st |
98 | fdiv %st, %st(0) |
99 | ret |
100 | END(__ieee754_acosh) |
101 | libm_alias_finite (__ieee754_acosh, __acosh) |
102 | |