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