1 //===-- mulxc3_test.c - Test __mulxc3 -------------------------------------===//
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 __mulxc3 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 product of a + ib and c + id
22 
23 long double _Complex
24 __mulxc3(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__mulxc3(long double a,long double b,long double c,long double d)52 int test__mulxc3(long double a, long double b, long double c, long double d)
53 {
54     long double _Complex r = __mulxc3(a, b, c, d);
55 //     printf("test__mulxc3(%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) != zero)
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) != NaN)
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) != zero)
97                 return 1;
98             break;
99         case non_zero:
100             if (classify(r) != non_zero)
101                 return 1;
102             if (r != a * c - b * d + _Complex_I*(a * d + b * c))
103                 return 1;
104             break;
105         case inf:
106             if (classify(r) != inf)
107                 return 1;
108             break;
109         case NaN:
110             if (classify(r) != NaN)
111                 return 1;
112             break;
113         case non_zero_nan:
114             if (classify(r) != NaN)
115                 return 1;
116             break;
117         }
118         break;
119     case inf:
120         switch (classify(divisor))
121         {
122         case zero:
123             if (classify(r) != NaN)
124                 return 1;
125             break;
126         case non_zero:
127             if (classify(r) != inf)
128                 return 1;
129             break;
130         case inf:
131             if (classify(r) != inf)
132                 return 1;
133             break;
134         case NaN:
135             if (classify(r) != NaN)
136                 return 1;
137             break;
138         case non_zero_nan:
139             if (classify(r) != inf)
140                 return 1;
141             break;
142         }
143         break;
144     case NaN:
145         switch (classify(divisor))
146         {
147         case zero:
148             if (classify(r) != NaN)
149                 return 1;
150             break;
151         case non_zero:
152             if (classify(r) != NaN)
153                 return 1;
154             break;
155         case inf:
156             if (classify(r) != NaN)
157                 return 1;
158             break;
159         case NaN:
160             if (classify(r) != NaN)
161                 return 1;
162             break;
163         case non_zero_nan:
164             if (classify(r) != NaN)
165                 return 1;
166             break;
167         }
168         break;
169     case non_zero_nan:
170         switch (classify(divisor))
171         {
172         case zero:
173             if (classify(r) != NaN)
174                 return 1;
175             break;
176         case non_zero:
177             if (classify(r) != NaN)
178                 return 1;
179             break;
180         case inf:
181             if (classify(r) != inf)
182                 return 1;
183             break;
184         case NaN:
185             if (classify(r) != NaN)
186                 return 1;
187             break;
188         case non_zero_nan:
189             if (classify(r) != NaN)
190                 return 1;
191             break;
192         }
193         break;
194     }
195 
196     return 0;
197 }
198 
199 long double x[][2] =
200 {
201     { 1.e-6,  1.e-6},
202     {-1.e-6,  1.e-6},
203     {-1.e-6, -1.e-6},
204     { 1.e-6, -1.e-6},
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     {NAN, NAN},
222     {-INFINITY, NAN},
223     {-2, NAN},
224     {-1, NAN},
225     {-0.5, NAN},
226     {-0., NAN},
227     {+0., NAN},
228     {0.5, NAN},
229     {1, NAN},
230     {2, NAN},
231     {INFINITY, NAN},
232 
233     {NAN, -INFINITY},
234     {-INFINITY, -INFINITY},
235     {-2, -INFINITY},
236     {-1, -INFINITY},
237     {-0.5, -INFINITY},
238     {-0., -INFINITY},
239     {+0., -INFINITY},
240     {0.5, -INFINITY},
241     {1, -INFINITY},
242     {2, -INFINITY},
243     {INFINITY, -INFINITY},
244 
245     {NAN, -2},
246     {-INFINITY, -2},
247     {-2, -2},
248     {-1, -2},
249     {-0.5, -2},
250     {-0., -2},
251     {+0., -2},
252     {0.5, -2},
253     {1, -2},
254     {2, -2},
255     {INFINITY, -2},
256 
257     {NAN, -1},
258     {-INFINITY, -1},
259     {-2, -1},
260     {-1, -1},
261     {-0.5, -1},
262     {-0., -1},
263     {+0., -1},
264     {0.5, -1},
265     {1, -1},
266     {2, -1},
267     {INFINITY, -1},
268 
269     {NAN, -0.5},
270     {-INFINITY, -0.5},
271     {-2, -0.5},
272     {-1, -0.5},
273     {-0.5, -0.5},
274     {-0., -0.5},
275     {+0., -0.5},
276     {0.5, -0.5},
277     {1, -0.5},
278     {2, -0.5},
279     {INFINITY, -0.5},
280 
281     {NAN, -0.},
282     {-INFINITY, -0.},
283     {-2, -0.},
284     {-1, -0.},
285     {-0.5, -0.},
286     {-0., -0.},
287     {+0., -0.},
288     {0.5, -0.},
289     {1, -0.},
290     {2, -0.},
291     {INFINITY, -0.},
292 
293     {NAN, 0.},
294     {-INFINITY, 0.},
295     {-2, 0.},
296     {-1, 0.},
297     {-0.5, 0.},
298     {-0., 0.},
299     {+0., 0.},
300     {0.5, 0.},
301     {1, 0.},
302     {2, 0.},
303     {INFINITY, 0.},
304 
305     {NAN, 0.5},
306     {-INFINITY, 0.5},
307     {-2, 0.5},
308     {-1, 0.5},
309     {-0.5, 0.5},
310     {-0., 0.5},
311     {+0., 0.5},
312     {0.5, 0.5},
313     {1, 0.5},
314     {2, 0.5},
315     {INFINITY, 0.5},
316 
317     {NAN, 1},
318     {-INFINITY, 1},
319     {-2, 1},
320     {-1, 1},
321     {-0.5, 1},
322     {-0., 1},
323     {+0., 1},
324     {0.5, 1},
325     {1, 1},
326     {2, 1},
327     {INFINITY, 1},
328 
329     {NAN, 2},
330     {-INFINITY, 2},
331     {-2, 2},
332     {-1, 2},
333     {-0.5, 2},
334     {-0., 2},
335     {+0., 2},
336     {0.5, 2},
337     {1, 2},
338     {2, 2},
339     {INFINITY, 2},
340 
341     {NAN, INFINITY},
342     {-INFINITY, INFINITY},
343     {-2, INFINITY},
344     {-1, INFINITY},
345     {-0.5, INFINITY},
346     {-0., INFINITY},
347     {+0., INFINITY},
348     {0.5, INFINITY},
349     {1, INFINITY},
350     {2, INFINITY},
351     {INFINITY, INFINITY}
352 
353 };
354 
355 #endif
356 
main()357 int main()
358 {
359 #if !_ARCH_PPC
360     const unsigned N = sizeof(x) / sizeof(x[0]);
361     unsigned i, j;
362     for (i = 0; i < N; ++i)
363     {
364         for (j = 0; j < N; ++j)
365         {
366             if (test__mulxc3(x[i][0], x[i][1], x[j][0], x[j][1]))
367                 return 1;
368         }
369     }
370 
371 #else
372     printf("skipped\n");
373 #endif
374     return 0;
375 }
376