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