1 /* ix87 specific implementation of complex exponential function for double.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
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.
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.
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. */
29 ASM_TYPE_DIRECTIVE(huge_nan_null_null,@object)
31 .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
32 .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
35 .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
36 .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
38 .byte 0, 0, 0, 0, 0, 0, 0, 0x80
39 ASM_SIZE_DIRECTIVE(huge_nan_null_null)
41 ASM_TYPE_DIRECTIVE(twopi,@object)
43 .byte 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0xf, 0xc9, 0x1, 0x40
44 .byte 0, 0, 0, 0, 0, 0
45 ASM_SIZE_DIRECTIVE(twopi)
47 ASM_TYPE_DIRECTIVE(l2e,@object)
49 .byte 0xbc, 0xf0, 0x17, 0x5c, 0x29, 0x3b, 0xaa, 0xb8, 0xff, 0x3f
50 .byte 0, 0, 0, 0, 0, 0
51 ASM_SIZE_DIRECTIVE(l2e)
53 ASM_TYPE_DIRECTIVE(one,@object)
55 ASM_SIZE_DIRECTIVE(one)
59 #define MO(op) op##@GOTOFF(%ecx)
60 #define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
63 #define MOX(op,x,f) op(,x,f)
71 fldl 16(%esp) /* y : x */
75 addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
80 je 1f /* Jump if real part is +-Inf */
82 je 2f /* Jump if real part is NaN */
86 /* If the imaginary part is not finite we return NaN+i NaN, as
87 for the case when the real part is NaN. A test for +-Inf and
88 NaN would be necessary. But since we know the stack register
89 we applied `fxam' to is not empty we can simply use one test.
90 Check your FPU manual for more information. */
95 /* We have finite numbers in the real and imaginary part. Do
98 fldt MO(l2e) /* log2(e) : x : y */
99 fmulp /* x * log2(e) : y */
100 fld %st /* x * log2(e) : x * log2(e) : y */
101 frndint /* int(x * log2(e)) : x * log2(e) : y */
102 fsubr %st, %st(1) /* int(x * log2(e)) : frac(x * log2(e)) : y */
103 fxch /* frac(x * log2(e)) : int(x * log2(e)) : y */
104 f2xm1 /* 2^frac(x * log2(e))-1 : int(x * log2(e)) : y */
105 faddl MO(one) /* 2^frac(x * log2(e)) : int(x * log2(e)) : y */
106 fscale /* e^x : int(x * log2(e)) : y */
107 fst %st(1) /* e^x : e^x : y */
108 fxch %st(2) /* y : e^x : e^x */
109 fsincos /* cos(y) : sin(y) : e^x : e^x */
113 fmulp %st, %st(3) /* sin(y) : e^x : e^x * cos(y) */
114 fmulp %st, %st(1) /* e^x * sin(y) : e^x * cos(y) */
115 movl 4(%esp), %eax /* Pointer to memory for result. */
120 /* We have to reduce the argument to fsincos. */
122 7: fldt MO(twopi) /* 2*pi : y : e^x : e^x */
123 fxch /* y : 2*pi : e^x : e^x */
124 8: fprem1 /* y%(2*pi) : 2*pi : e^x : e^x */
128 fstp %st(1) /* y%(2*pi) : e^x : e^x */
129 fsincos /* cos(y) : sin(y) : e^x : e^x */
132 movl 4(%esp), %eax /* Pointer to memory for result. */
137 /* The real part is +-inf. We must make further differences. */
142 andb $0x01, %ah /* See above why 0x01 is usable here. */
147 /* The real part is +-Inf and the imaginary part is finite. */
149 cmpb $0x40, %dl /* Imaginary part == 0? */
154 fstp %st(0) /* y */ /* Drop the real part. */
155 andl $16, %edx /* This puts the sign bit of the real part
156 in bit 4. So we can use it to index a
157 small array to select 0 or Inf. */
158 fsincos /* cos(y) : sin(y) */
162 fldl MOX(huge_nan_null_null,%edx,1)
163 movl 4(%esp), %edx /* Pointer to memory for result. */
169 andl $0x80000000, %eax
175 andl $0x80000000, %eax
179 /* We must reduce the argument to fsincos. */
189 fldl MOX(huge_nan_null_null,%edx,1)
190 movl 4(%esp), %edx /* Pointer to memory for result. */
196 andl $0x80000000, %eax
202 andl $0x80000000, %eax
207 /* The real part is +-Inf and the imaginary part is +-0. So return
210 4: movl 4(%esp), %eax /* Pointer to memory for result. */
215 fldl MOX(huge_nan_null_null,%edx,1)
219 /* The real part is +-Inf, the imaginary is also is not finite. */
222 fstp %st(0) /* <empty> */
229 movl 4(%esp), %eax /* Pointer to memory for result. */
231 fldl MOX(huge_nan_null_null,%edx,1)
232 fldl MOX(huge_nan_null_null+8,%edx,1)
237 /* The real part is NaN. */
241 movl 4(%esp), %eax /* Pointer to memory for result. */
242 fldl MO(huge_nan_null_null+8)
248 weak_alias (__cexp, cexp)