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