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