1
/* ix87 specific implementation of complex exponential function for double.
2
Copyright (C) 1997, 2005 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 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, write to the Free
18
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
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 */
79
je 1f /* Jump if real part is +-Inf */
81
je 2f /* Jump if real part is NaN */
85
/* If the imaginary part is not finite we return NaN+i NaN, as
86
for the case when the real part is NaN. A test for +-Inf and
87
NaN would be necessary. But since we know the stack register
88
we applied `fxam' to is not empty we can simply use one test.
89
Check your FPU manual for more information. */
94
/* We have finite numbers in the real and imaginary part. Do
97
fldt MO(l2e) /* log2(e) : x : y */
98
fmulp /* x * log2(e) : y */
99
fld %st /* x * log2(e) : x * log2(e) : y */
100
frndint /* int(x * log2(e)) : x * log2(e) : y */
101
fsubr %st, %st(1) /* int(x * log2(e)) : frac(x * log2(e)) : y */
102
fxch /* frac(x * log2(e)) : int(x * log2(e)) : y */
103
f2xm1 /* 2^frac(x * log2(e))-1 : int(x * log2(e)) : y */
104
faddl MO(one) /* 2^frac(x * log2(e)) : int(x * log2(e)) : y */
105
fscale /* e^x : int(x * log2(e)) : y */
106
fst %st(1) /* e^x : e^x : y */
107
fxch %st(2) /* y : e^x : e^x */
108
fsincos /* cos(y) : sin(y) : e^x : e^x */
112
fmulp %st, %st(3) /* sin(y) : e^x : e^x * cos(y) */
113
fmulp %st, %st(1) /* e^x * sin(y) : e^x * cos(y) */
114
movl 4(%esp), %eax /* Pointer to memory for result. */
119
/* We have to reduce the argument to fsincos. */
121
7: fldt MO(twopi) /* 2*pi : y : e^x : e^x */
122
fxch /* y : 2*pi : e^x : e^x */
123
8: fprem1 /* y%(2*pi) : 2*pi : e^x : e^x */
127
fstp %st(1) /* y%(2*pi) : e^x : e^x */
128
fsincos /* cos(y) : sin(y) : e^x : e^x */
131
movl 4(%esp), %eax /* Pointer to memory for result. */
136
/* The real part is +-inf. We must make further differences. */
141
testb $0x01, %ah /* See above why 0x01 is usable here. */
145
/* The real part is +-Inf and the imaginary part is finite. */
147
cmpb $0x40, %dl /* Imaginary part == 0? */
152
fstp %st(0) /* y */ /* Drop the real part. */
153
andl $16, %edx /* This puts the sign bit of the real part
154
in bit 4. So we can use it to index a
155
small array to select 0 or Inf. */
156
fsincos /* cos(y) : sin(y) */
160
fldl MOX(huge_nan_null_null,%edx,1)
161
movl 4(%esp), %edx /* Pointer to memory for result. */
167
andl $0x80000000, %eax
173
andl $0x80000000, %eax
177
/* We must reduce the argument to fsincos. */
187
fldl MOX(huge_nan_null_null,%edx,1)
188
movl 4(%esp), %edx /* Pointer to memory for result. */
194
andl $0x80000000, %eax
200
andl $0x80000000, %eax
205
/* The real part is +-Inf and the imaginary part is +-0. So return
208
4: movl 4(%esp), %eax /* Pointer to memory for result. */
213
fldl MOX(huge_nan_null_null,%edx,1)
217
/* The real part is +-Inf, the imaginary is also is not finite. */
220
fstp %st(0) /* <empty> */
225
fldl MO(infinity) /* Raise invalid exception. */
234
movl 4(%esp), %eax /* Pointer to memory for result. */
236
fldl MOX(huge_nan_null_null,%edx,1)
237
fldl MOX(huge_nan_null_null+8,%edx,1)
243
/* The real part is NaN. */
245
20: fldl MO(infinity) /* Raise invalid exception. */
250
movl 4(%esp), %eax /* Pointer to memory for result. */
251
fldl MO(huge_nan_null_null+8)
257
weak_alias (__cexp, cexp)