Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / i386 / fpu / s_asinhl.S
blob557613e65e80fdb0d035dc808c73e8f40b203e26
1 /* ix87 specific implementation of arcsinh.
2    Copyright (C) 1996-2014 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
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.
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.
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
20 #include <machine/asm.h>
22         .section .rodata
24         .align ALIGNARG(4)
25         .type huge,@object
26 huge:   .tfloat 1e+4930
27         ASM_SIZE_DIRECTIVE(huge)
28         .align ALIGNARG(4)
29         /* Please note that we use double value for 1.0.  This number
30            has an exact representation and so we don't get accuracy
31            problems.  The advantage is that the code is simpler.  */
32         .type one,@object
33 one:    .double 1.0
34         ASM_SIZE_DIRECTIVE(one)
35         /* It is not important that this constant is precise.  It is only
36            a value which is known to be on the safe side for using the
37            fyl2xp1 instruction.  */
38         .type limit,@object
39 limit:  .double 0.29
40         ASM_SIZE_DIRECTIVE(limit)
42 #ifdef PIC
43 #define MO(op) op##@GOTOFF(%edx)
44 #else
45 #define MO(op) op
46 #endif
48         .text
49 ENTRY(__asinhl)
50         movl    12(%esp), %ecx
51         movl    $0x7fff, %eax
52         andl    %ecx, %eax
53         andl    $0x8000, %ecx
54         movl    %eax, %edx
55         orl     $0xffff8000, %edx
56         incl    %edx
57         jz      7f                      // x in ±Inf or NaN
58         xorl    %ecx, 12(%esp)
59         fldt    4(%esp)                 // |x|
60         cmpl    $0x3fde, %eax
61         jb      2f                      // |x| < 2^-34
62         fldln2                          // log(2) : |x|
63         cmpl    $0x4020, %eax
64         fxch                            // |x| : log(2)
65         ja      3f                      // |x| > 2^34
66 #ifdef  PIC
67         LOAD_PIC_REG (dx)
68 #endif
69         cmpl    $0x4000, %eax
70         ja      5f                      // |x| > 2
72         // 2^-34 <= |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
90 7:      fldt    4(%esp)
91         ret
93 6:      faddl   MO(one)
94         fyl2x
95         jecxz   4f
96         fchs
97 4:      ret
99         // |x| < 2^-34 => y = x (inexact iff |x| != 0.0)
100         .align ALIGNARG(4)
102 #ifdef  PIC
103         LOAD_PIC_REG (dx)
104 #endif
105         jecxz   4f
106         fchs                            // x
107 4:      fld     %st                     // x : x
108         fldt    MO(huge)                // huge : x : x
109         faddp                           // huge+x : x
110         fstp    %st(0)                  // x
111         ret
113         // |x| > 2^34 => y = sign(x) * (log(|x|) + log(2))
114         .align ALIGNARG(4)
115 3:      fyl2x                           // log(|x|)
116         fldln2                          // log(2) : log(|x|)
117         faddp                           // log(|x|)+log(2)
118         jecxz   4f
119         fchs
120 4:      ret
122         // |x| > 2 => y = sign(x) * log(2*|x| + 1/(|x|+sqrt(x*x+1)))
123         .align ALIGNARG(4)
124 5:      fld     %st                     // |x| : |x| : log(2)
125         fadd    %st, %st(1)             // |x| : 2*|x| : log(2)
126         fld     %st                     // |x| : |x| : 2*|x| : log(2)
127         fmul    %st(1)                  // |x|^2 : |x| : 2*|x| : log(2)
128         faddl   MO(one)                 // 1+|x|^2 : |x| : 2*|x| : log(2)
129         fsqrt                           // sqrt(1+|x|^2) : |x| : 2*|x| : log(2)
130         faddp                           // |x|+sqrt(1+|x|^2) : 2*|x| : log(2)
131         fdivrl  MO(one)                 // 1/(|x|+sqrt(1+|x|^2)) : 2*|x| : log(2)
132         faddp                           // 2*|x|+1/(|x|+sqrt(1+|x|^2)) : log(2)
133         fyl2x                           // log(2*|x|+1/(|x|+sqrt(1+|x|^2)))
134         jecxz   4f
135         fchs
136 4:      ret
137 END(__asinhl)
138 weak_alias (__asinhl, asinhl)