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
36 .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
37 .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
39 .byte 0, 0, 0, 0, 0, 0, 0, 0x80
40 ASM_SIZE_DIRECTIVE(huge_nan_null_null)
42 ASM_TYPE_DIRECTIVE(twopi,@object)
44 .byte 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0xf, 0xc9, 0x1, 0x40
45 .byte 0, 0, 0, 0, 0, 0
46 ASM_SIZE_DIRECTIVE(twopi)
48 ASM_TYPE_DIRECTIVE(l2e,@object)
50 .byte 0xbc, 0xf0, 0x17, 0x5c, 0x29, 0x3b, 0xaa, 0xb8, 0xff, 0x3f
51 .byte 0, 0, 0, 0, 0, 0
52 ASM_SIZE_DIRECTIVE(l2e)
54 ASM_TYPE_DIRECTIVE(one,@object)
56 ASM_SIZE_DIRECTIVE(one)
60 #define MO(op) op##@GOTOFF(%ecx)
61 #define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
64 #define MOX(op,x,f) op(,x,f)
72 fldl 16(%esp) /* y : x */
76 addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
81 je 1f /* Jump if real part is +-Inf */
83 je 2f /* Jump if real part is NaN */
87 /* If the imaginary part is not finite we return NaN+i NaN, as
88 for the case when the real part is NaN. A test for +-Inf and
89 NaN would be necessary. But since we know the stack register
90 we applied `fxam' to is not empty we can simply use one test.
91 Check your FPU manual for more information. */
96 /* We have finite numbers in the real and imaginary part. Do
99 fldt MO(l2e) /* log2(e) : x : y */
100 fmulp /* x * log2(e) : y */
101 fld %st /* x * log2(e) : x * log2(e) : y */
102 frndint /* int(x * log2(e)) : x * log2(e) : y */
103 fsubr %st, %st(1) /* int(x * log2(e)) : frac(x * log2(e)) : y */
104 fxch /* frac(x * log2(e)) : int(x * log2(e)) : y */
105 f2xm1 /* 2^frac(x * log2(e))-1 : int(x * log2(e)) : y */
106 faddl MO(one) /* 2^frac(x * log2(e)) : int(x * log2(e)) : y */
107 fscale /* e^x : int(x * log2(e)) : y */
108 fst %st(1) /* e^x : e^x : y */
109 fxch %st(2) /* y : e^x : e^x */
110 fsincos /* cos(y) : sin(y) : e^x : e^x */
114 fmulp %st, %st(3) /* sin(y) : e^x : e^x * cos(y) */
115 fmulp %st, %st(1) /* e^x * sin(y) : e^x * cos(y) */
116 movl 4(%esp), %eax /* Pointer to memory for result. */
121 /* We have to reduce the argument to fsincos. */
123 7: fldt MO(twopi) /* 2*pi : y : e^x : e^x */
124 fxch /* y : 2*pi : e^x : e^x */
125 8: fprem1 /* y%(2*pi) : 2*pi : e^x : e^x */
129 fstp %st(1) /* y%(2*pi) : e^x : e^x */
130 fsincos /* cos(y) : sin(y) : e^x : e^x */
133 movl 4(%esp), %eax /* Pointer to memory for result. */
138 /* The real part is +-inf. We must make further differences. */
143 testb $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> */
227 fldl MO(infinity) /* Raise invalid exception. */
236 movl 4(%esp), %eax /* Pointer to memory for result. */
238 fldl MOX(huge_nan_null_null,%edx,1)
239 fldl MOX(huge_nan_null_null+8,%edx,1)
245 /* The real part is NaN. */
247 20: fldl MO(infinity) /* Raise invalid exception. */
252 movl 4(%esp), %eax /* Pointer to memory for result. */
253 fldl MO(huge_nan_null_null+8)
259 weak_alias (__cexp, cexp)