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
21double _Complex __muldc3(double __a, double __b, double __c, double __d);
22
23enum {zero, non_zero, inf, NaN, non_zero_nan};
24
25int
26classify(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
49int 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
196double 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
352int 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