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 
23 long double _Complex
24 __divxc3(long double __a, long double __b, long double __c, long double __d);
25 
26 enum {zero, non_zero, inf, NaN, non_zero_nan};
27 
28 int
29 classify(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 
52 int 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 
203 long 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 
361 int 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