1 //===-- muldc3_test.c - Test __muldc3 -------------------------------------===//
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 __muldc3 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 product of a + ib and c + id
20 
21 double _Complex __muldc3(double __a, double __b, double __c, double __d);
22 
23 enum {zero, non_zero, inf, NaN, non_zero_nan};
24 
25 int
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 
49 int test__muldc3(double a, double b, double c, double d)
50 {
51     double _Complex r = __muldc3(a, b, c, d);
52 //     printf("test__muldc3(%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) != zero)
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) != NaN)
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) != zero)
94                 return 1;
95             break;
96         case non_zero:
97             if (classify(r) != non_zero)
98                 return 1;
99             if (r != a * c - b * d + _Complex_I*(a * d + b * c))
100                 return 1;
101             break;
102         case inf:
103             if (classify(r) != inf)
104                 return 1;
105             break;
106         case NaN:
107             if (classify(r) != NaN)
108                 return 1;
109             break;
110         case non_zero_nan:
111             if (classify(r) != NaN)
112                 return 1;
113             break;
114         }
115         break;
116     case inf:
117         switch (classify(divisor))
118         {
119         case zero:
120             if (classify(r) != NaN)
121                 return 1;
122             break;
123         case non_zero:
124             if (classify(r) != inf)
125                 return 1;
126             break;
127         case inf:
128             if (classify(r) != inf)
129                 return 1;
130             break;
131         case NaN:
132             if (classify(r) != NaN)
133                 return 1;
134             break;
135         case non_zero_nan:
136             if (classify(r) != inf)
137                 return 1;
138             break;
139         }
140         break;
141     case NaN:
142         switch (classify(divisor))
143         {
144         case zero:
145             if (classify(r) != NaN)
146                 return 1;
147             break;
148         case non_zero:
149             if (classify(r) != NaN)
150                 return 1;
151             break;
152         case inf:
153             if (classify(r) != NaN)
154                 return 1;
155             break;
156         case NaN:
157             if (classify(r) != NaN)
158                 return 1;
159             break;
160         case non_zero_nan:
161             if (classify(r) != NaN)
162                 return 1;
163             break;
164         }
165         break;
166     case non_zero_nan:
167         switch (classify(divisor))
168         {
169         case zero:
170             if (classify(r) != NaN)
171                 return 1;
172             break;
173         case non_zero:
174             if (classify(r) != NaN)
175                 return 1;
176             break;
177         case inf:
178             if (classify(r) != inf)
179                 return 1;
180             break;
181         case NaN:
182             if (classify(r) != NaN)
183                 return 1;
184             break;
185         case non_zero_nan:
186             if (classify(r) != NaN)
187                 return 1;
188             break;
189         }
190         break;
191     }
192 
193     return 0;
194 }
195 
196 double x[][2] =
197 {
198     { 1.e-6,  1.e-6},
199     {-1.e-6,  1.e-6},
200     {-1.e-6, -1.e-6},
201     { 1.e-6, -1.e-6},
202 
203     { 1.e+6,  1.e-6},
204     {-1.e+6,  1.e-6},
205     {-1.e+6, -1.e-6},
206     { 1.e+6, -1.e-6},
207 
208     { 1.e-6,  1.e+6},
209     {-1.e-6,  1.e+6},
210     {-1.e-6, -1.e+6},
211     { 1.e-6, -1.e+6},
212 
213     { 1.e+6,  1.e+6},
214     {-1.e+6,  1.e+6},
215     {-1.e+6, -1.e+6},
216     { 1.e+6, -1.e+6},
217 
218     {NAN, NAN},
219     {-INFINITY, NAN},
220     {-2, NAN},
221     {-1, NAN},
222     {-0.5, NAN},
223     {-0., NAN},
224     {+0., NAN},
225     {0.5, NAN},
226     {1, NAN},
227     {2, NAN},
228     {INFINITY, NAN},
229 
230     {NAN, -INFINITY},
231     {-INFINITY, -INFINITY},
232     {-2, -INFINITY},
233     {-1, -INFINITY},
234     {-0.5, -INFINITY},
235     {-0., -INFINITY},
236     {+0., -INFINITY},
237     {0.5, -INFINITY},
238     {1, -INFINITY},
239     {2, -INFINITY},
240     {INFINITY, -INFINITY},
241 
242     {NAN, -2},
243     {-INFINITY, -2},
244     {-2, -2},
245     {-1, -2},
246     {-0.5, -2},
247     {-0., -2},
248     {+0., -2},
249     {0.5, -2},
250     {1, -2},
251     {2, -2},
252     {INFINITY, -2},
253 
254     {NAN, -1},
255     {-INFINITY, -1},
256     {-2, -1},
257     {-1, -1},
258     {-0.5, -1},
259     {-0., -1},
260     {+0., -1},
261     {0.5, -1},
262     {1, -1},
263     {2, -1},
264     {INFINITY, -1},
265 
266     {NAN, -0.5},
267     {-INFINITY, -0.5},
268     {-2, -0.5},
269     {-1, -0.5},
270     {-0.5, -0.5},
271     {-0., -0.5},
272     {+0., -0.5},
273     {0.5, -0.5},
274     {1, -0.5},
275     {2, -0.5},
276     {INFINITY, -0.5},
277 
278     {NAN, -0.},
279     {-INFINITY, -0.},
280     {-2, -0.},
281     {-1, -0.},
282     {-0.5, -0.},
283     {-0., -0.},
284     {+0., -0.},
285     {0.5, -0.},
286     {1, -0.},
287     {2, -0.},
288     {INFINITY, -0.},
289 
290     {NAN, 0.},
291     {-INFINITY, 0.},
292     {-2, 0.},
293     {-1, 0.},
294     {-0.5, 0.},
295     {-0., 0.},
296     {+0., 0.},
297     {0.5, 0.},
298     {1, 0.},
299     {2, 0.},
300     {INFINITY, 0.},
301 
302     {NAN, 0.5},
303     {-INFINITY, 0.5},
304     {-2, 0.5},
305     {-1, 0.5},
306     {-0.5, 0.5},
307     {-0., 0.5},
308     {+0., 0.5},
309     {0.5, 0.5},
310     {1, 0.5},
311     {2, 0.5},
312     {INFINITY, 0.5},
313 
314     {NAN, 1},
315     {-INFINITY, 1},
316     {-2, 1},
317     {-1, 1},
318     {-0.5, 1},
319     {-0., 1},
320     {+0., 1},
321     {0.5, 1},
322     {1, 1},
323     {2, 1},
324     {INFINITY, 1},
325 
326     {NAN, 2},
327     {-INFINITY, 2},
328     {-2, 2},
329     {-1, 2},
330     {-0.5, 2},
331     {-0., 2},
332     {+0., 2},
333     {0.5, 2},
334     {1, 2},
335     {2, 2},
336     {INFINITY, 2},
337 
338     {NAN, INFINITY},
339     {-INFINITY, INFINITY},
340     {-2, INFINITY},
341     {-1, INFINITY},
342     {-0.5, INFINITY},
343     {-0., INFINITY},
344     {+0., INFINITY},
345     {0.5, INFINITY},
346     {1, INFINITY},
347     {2, INFINITY},
348     {INFINITY, INFINITY}
349 
350 };
351 
352 int main()
353 {
354     const unsigned N = sizeof(x) / sizeof(x[0]);
355     unsigned i, j;
356     for (i = 0; i < N; ++i)
357     {
358         for (j = 0; j < N; ++j)
359         {
360             if (test__muldc3(x[i][0], x[i][1], x[j][0], x[j][1]))
361                 return 1;
362         }
363     }
364 
365     return 0;
366 }
367