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 
23 long double _Complex
24 __divtc3(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
classify(long double _Complex x)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 
test__divtc3(long double a,long double b,long double c,long double d)52 int 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 
204 long 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 
main()362 int 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