2 // Copyright (C) 2001-2003 by Digital Mars
6 // Runtime support for complex arithmetic code generation
10 * Modified by Sean Kelly for use with the D Runtime Project
15 private import core.stdc.math;
19 /****************************
20 * Multiply two complex floating point numbers, x and y.
33 // p.re = x.re * y.re - x.im * y.im;
34 // p.im = x.im * y.re + x.re * y.im;
38 fmul ST,ST(4) ; // ST0 = x.re * y.re
41 fmul ST,ST(4) ; // ST0 = x.im * y.im
43 fsubp ST(1),ST ; // ST0 = x.re * y.re - x.im * y.im
46 fmul ST,ST(3) ; // ST0 = x.im * y.re
49 fmul ST,ST(3) ; // ST0 = x.re * y.im
51 faddp ST(1),ST ; // ST0 = x.im * y.re + x.re * y.im
63 if (isnan(x) && isnan(y))
65 // Recover infinities that computed as NaN+ iNaN ...
67 if ( isinf( a) || isinf( b) )
69 // "Box" the infinity and change NaNs in the other factor to 0
70 a = copysignl( isinf( a) ? 1.0 : 0.0, a);
71 b = copysignl( isinf( b) ? 1.0 : 0.0, b);
72 if (isnan( c)) c = copysignl( 0.0, c);
73 if (isnan( d)) d = copysignl( 0.0, d);
76 if (isinf(c) || isinf(d))
78 // "Box" the infinity and change NaNs in the other factor to 0
79 c = copysignl( isinf( c) ? 1.0 : 0.0, c);
80 d = copysignl( isinf( d) ? 1.0 : 0.0, d);
81 if (isnan( a)) a = copysignl( 0.0, a);
82 if (isnan( b)) b = copysignl( 0.0, b);
85 if (!recalc && (isinf(ac) || isinf(bd) ||
86 isinf(ad) || isinf(bc)))
88 // Recover infinities from overflow by changing NaNs to 0 ...
89 if (isnan( a)) a = copysignl( 0.0, a);
90 if (isnan( b)) b = copysignl( 0.0, b);
91 if (isnan( c)) c = copysignl( 0.0, c);
92 if (isnan( d)) d = copysignl( 0.0, d);
97 x = INFINITY * (a * c - b * d);
98 y = INFINITY * (a * d + b * c);
104 /****************************
105 * Divide two complex floating point numbers, x / y.
132 if (fabs(y_re) < fabs(y_im))
135 den = y_im + r * y_re;
136 q_re = (x_re * r + x_im) / den;
137 q_im = (x_im * r - x_re) / den;
142 den = y_re + r * y_im;
143 q_re = (x_re + r * x_im) / den;
144 q_im = (x_im - r * x_re) / den;
146 //printf("q.re = %g, q.im = %g\n", (double)q_re, (double)q_im);
148 if (isnan(q_re) && isnan(q_im))
150 real denom = y_re * y_re + y_im * y_im;
153 if (denom == 0.0 && (!isnan(x_re) || !isnan(x_im)))
155 q_re = copysignl(INFINITY, y_re) * x_re;
156 q_im = copysignl(INFINITY, y_re) * x_im;
159 else if ((isinf(x_re) || isinf(x_im)) && isfinite(y_re) && isfinite(y_im))
161 x_re = copysignl(isinf(x_re) ? 1.0 : 0.0, x_re);
162 x_im = copysignl(isinf(x_im) ? 1.0 : 0.0, x_im);
163 q_re = INFINITY * (x_re * y_re + x_im * y_im);
164 q_im = INFINITY * (x_im * y_re - x_re * y_im);
167 else if (isinf(logbw) && isfinite(x_re) && isfinite(x_im))
169 y_re = copysignl(isinf(y_re) ? 1.0 : 0.0, y_re);
170 y_im = copysignl(isinf(y_im) ? 1.0 : 0.0, y_im);
171 q_re = 0.0 * (x_re * y_re + x_im * y_im);
172 q_im = 0.0 * (x_im * y_re - x_re * y_im);
175 return q_re + q_im * 1.0i;
184 /****************************
185 * Compare two complex floating point numbers, x and y.
192 * 8087 stack is cleared
200 fucomp ST(2) ; // compare x.im and y.im
204 jp L1 ; // jmp if NAN
205 fucomp ST(2) ; // compare x.re and y.re