1 //===-- divdc3_test.c - Test __divdc3 -------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file tests __divdc3 for the compiler_rt library.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "int_lib.h"
15 #include <math.h>
16 #include <complex.h>
17 #include <stdio.h>
18
19 // Returns: the quotient of (a + ib) / (c + id)
20
21 double _Complex __divdc3(double __a, double __b, double __c, double __d);
22
23 enum {zero, non_zero, inf, NaN, non_zero_nan};
24
25 int
classify(double _Complex x)26 classify(double _Complex x)
27 {
28 if (x == 0)
29 return zero;
30 if (isinf(creal(x)) || isinf(cimag(x)))
31 return inf;
32 if (isnan(creal(x)) && isnan(cimag(x)))
33 return NaN;
34 if (isnan(creal(x)))
35 {
36 if (cimag(x) == 0)
37 return NaN;
38 return non_zero_nan;
39 }
40 if (isnan(cimag(x)))
41 {
42 if (creal(x) == 0)
43 return NaN;
44 return non_zero_nan;
45 }
46 return non_zero;
47 }
48
test__divdc3(double a,double b,double c,double d)49 int test__divdc3(double a, double b, double c, double d)
50 {
51 double _Complex r = __divdc3(a, b, c, d);
52 // printf("test__divdc3(%f, %f, %f, %f) = %f + I%f\n",
53 // a, b, c, d, creal(r), cimag(r));
54 double _Complex dividend;
55 double _Complex divisor;
56
57 __real__ dividend = a;
58 __imag__ dividend = b;
59 __real__ divisor = c;
60 __imag__ divisor = d;
61
62 switch (classify(dividend))
63 {
64 case zero:
65 switch (classify(divisor))
66 {
67 case zero:
68 if (classify(r) != NaN)
69 return 1;
70 break;
71 case non_zero:
72 if (classify(r) != zero)
73 return 1;
74 break;
75 case inf:
76 if (classify(r) != zero)
77 return 1;
78 break;
79 case NaN:
80 if (classify(r) != NaN)
81 return 1;
82 break;
83 case non_zero_nan:
84 if (classify(r) != NaN)
85 return 1;
86 break;
87 }
88 break;
89 case non_zero:
90 switch (classify(divisor))
91 {
92 case zero:
93 if (classify(r) != inf)
94 return 1;
95 break;
96 case non_zero:
97 if (classify(r) != non_zero)
98 return 1;
99 {
100 double _Complex z = (a * c + b * d) / (c * c + d * d)
101 + (b * c - a * d) / (c * c + d * d) * _Complex_I;
102 if (cabs((r-z)/r) > 1.e-6)
103 return 1;
104 }
105 break;
106 case inf:
107 if (classify(r) != zero)
108 return 1;
109 break;
110 case NaN:
111 if (classify(r) != NaN)
112 return 1;
113 break;
114 case non_zero_nan:
115 if (classify(r) != NaN)
116 return 1;
117 break;
118 }
119 break;
120 case inf:
121 switch (classify(divisor))
122 {
123 case zero:
124 if (classify(r) != inf)
125 return 1;
126 break;
127 case non_zero:
128 if (classify(r) != inf)
129 return 1;
130 break;
131 case inf:
132 if (classify(r) != NaN)
133 return 1;
134 break;
135 case NaN:
136 if (classify(r) != NaN)
137 return 1;
138 break;
139 case non_zero_nan:
140 if (classify(r) != NaN)
141 return 1;
142 break;
143 }
144 break;
145 case NaN:
146 switch (classify(divisor))
147 {
148 case zero:
149 if (classify(r) != NaN)
150 return 1;
151 break;
152 case non_zero:
153 if (classify(r) != NaN)
154 return 1;
155 break;
156 case inf:
157 if (classify(r) != NaN)
158 return 1;
159 break;
160 case NaN:
161 if (classify(r) != NaN)
162 return 1;
163 break;
164 case non_zero_nan:
165 if (classify(r) != NaN)
166 return 1;
167 break;
168 }
169 break;
170 case non_zero_nan:
171 switch (classify(divisor))
172 {
173 case zero:
174 if (classify(r) != inf)
175 return 1;
176 break;
177 case non_zero:
178 if (classify(r) != NaN)
179 return 1;
180 break;
181 case inf:
182 if (classify(r) != NaN)
183 return 1;
184 break;
185 case NaN:
186 if (classify(r) != NaN)
187 return 1;
188 break;
189 case non_zero_nan:
190 if (classify(r) != NaN)
191 return 1;
192 break;
193 }
194 break;
195 }
196
197 return 0;
198 }
199
200 double x[][2] =
201 {
202 { 1.e-6, 1.e-6},
203 {-1.e-6, 1.e-6},
204 {-1.e-6, -1.e-6},
205 { 1.e-6, -1.e-6},
206
207 { 1.e+6, 1.e-6},
208 {-1.e+6, 1.e-6},
209 {-1.e+6, -1.e-6},
210 { 1.e+6, -1.e-6},
211
212 { 1.e-6, 1.e+6},
213 {-1.e-6, 1.e+6},
214 {-1.e-6, -1.e+6},
215 { 1.e-6, -1.e+6},
216
217 { 1.e+6, 1.e+6},
218 {-1.e+6, 1.e+6},
219 {-1.e+6, -1.e+6},
220 { 1.e+6, -1.e+6},
221
222 {NAN, NAN},
223 {-INFINITY, NAN},
224 {-2, NAN},
225 {-1, NAN},
226 {-0.5, NAN},
227 {-0., NAN},
228 {+0., NAN},
229 {0.5, NAN},
230 {1, NAN},
231 {2, NAN},
232 {INFINITY, NAN},
233
234 {NAN, -INFINITY},
235 {-INFINITY, -INFINITY},
236 {-2, -INFINITY},
237 {-1, -INFINITY},
238 {-0.5, -INFINITY},
239 {-0., -INFINITY},
240 {+0., -INFINITY},
241 {0.5, -INFINITY},
242 {1, -INFINITY},
243 {2, -INFINITY},
244 {INFINITY, -INFINITY},
245
246 {NAN, -2},
247 {-INFINITY, -2},
248 {-2, -2},
249 {-1, -2},
250 {-0.5, -2},
251 {-0., -2},
252 {+0., -2},
253 {0.5, -2},
254 {1, -2},
255 {2, -2},
256 {INFINITY, -2},
257
258 {NAN, -1},
259 {-INFINITY, -1},
260 {-2, -1},
261 {-1, -1},
262 {-0.5, -1},
263 {-0., -1},
264 {+0., -1},
265 {0.5, -1},
266 {1, -1},
267 {2, -1},
268 {INFINITY, -1},
269
270 {NAN, -0.5},
271 {-INFINITY, -0.5},
272 {-2, -0.5},
273 {-1, -0.5},
274 {-0.5, -0.5},
275 {-0., -0.5},
276 {+0., -0.5},
277 {0.5, -0.5},
278 {1, -0.5},
279 {2, -0.5},
280 {INFINITY, -0.5},
281
282 {NAN, -0.},
283 {-INFINITY, -0.},
284 {-2, -0.},
285 {-1, -0.},
286 {-0.5, -0.},
287 {-0., -0.},
288 {+0., -0.},
289 {0.5, -0.},
290 {1, -0.},
291 {2, -0.},
292 {INFINITY, -0.},
293
294 {NAN, 0.},
295 {-INFINITY, 0.},
296 {-2, 0.},
297 {-1, 0.},
298 {-0.5, 0.},
299 {-0., 0.},
300 {+0., 0.},
301 {0.5, 0.},
302 {1, 0.},
303 {2, 0.},
304 {INFINITY, 0.},
305
306 {NAN, 0.5},
307 {-INFINITY, 0.5},
308 {-2, 0.5},
309 {-1, 0.5},
310 {-0.5, 0.5},
311 {-0., 0.5},
312 {+0., 0.5},
313 {0.5, 0.5},
314 {1, 0.5},
315 {2, 0.5},
316 {INFINITY, 0.5},
317
318 {NAN, 1},
319 {-INFINITY, 1},
320 {-2, 1},
321 {-1, 1},
322 {-0.5, 1},
323 {-0., 1},
324 {+0., 1},
325 {0.5, 1},
326 {1, 1},
327 {2, 1},
328 {INFINITY, 1},
329
330 {NAN, 2},
331 {-INFINITY, 2},
332 {-2, 2},
333 {-1, 2},
334 {-0.5, 2},
335 {-0., 2},
336 {+0., 2},
337 {0.5, 2},
338 {1, 2},
339 {2, 2},
340 {INFINITY, 2},
341
342 {NAN, INFINITY},
343 {-INFINITY, INFINITY},
344 {-2, INFINITY},
345 {-1, INFINITY},
346 {-0.5, INFINITY},
347 {-0., INFINITY},
348 {+0., INFINITY},
349 {0.5, INFINITY},
350 {1, INFINITY},
351 {2, INFINITY},
352 {INFINITY, INFINITY}
353
354 };
355
main()356 int main()
357 {
358 const unsigned N = sizeof(x) / sizeof(x[0]);
359 unsigned i, j;
360 for (i = 0; i < N; ++i)
361 {
362 for (j = 0; j < N; ++j)
363 {
364 if (test__divdc3(x[i][0], x[i][1], x[j][0], x[j][1]))
365 return 1;
366 }
367 }
368
369 return 0;
370 }
371