1 // RUN: %clang_builtins %s %librt -o %t && %run %t
2 //===-- multc3_test.c - Test __multc3 -------------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file tests __multc3 for the compiler_rt library.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include <stdio.h>
16 
17 #if _ARCH_PPC || __aarch64__
18 
19 #include "int_lib.h"
20 #include <math.h>
21 #include <complex.h>
22 
23 // Returns: the product of a + ib and c + id
24 
25 COMPILER_RT_ABI long double _Complex
26 __multc3(long double __a, long double __b, long double __c, long double __d);
27 
28 enum {zero, non_zero, inf, NaN, non_zero_nan};
29 
30 int
31 classify(long double _Complex x)
32 {
33     if (x == 0)
34         return zero;
35     if (isinf(creall(x)) || isinf(cimagl(x)))
36         return inf;
37     if (isnan(creall(x)) && isnan(cimagl(x)))
38         return NaN;
39     if (isnan(creall(x)))
40     {
41         if (cimagl(x) == 0)
42             return NaN;
43         return non_zero_nan;
44     }
45     if (isnan(cimagl(x)))
46     {
47         if (creall(x) == 0)
48             return NaN;
49         return non_zero_nan;
50     }
51     return non_zero;
52 }
53 
54 int test__multc3(long double a, long double b, long double c, long double d)
55 {
56     long double _Complex r = __multc3(a, b, c, d);
57 //     printf("test__multc3(%Lf, %Lf, %Lf, %Lf) = %Lf + I%Lf\n",
58 //             a, b, c, d, creall(r), cimagl(r));
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) != zero)
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) != NaN)
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) != zero)
99                 return 1;
100             break;
101         case non_zero:
102             if (classify(r) != non_zero)
103                 return 1;
104             if (r != a * c - b * d + _Complex_I*(a * d + b * c))
105                 return 1;
106             break;
107         case inf:
108             if (classify(r) != inf)
109                 return 1;
110             break;
111         case NaN:
112             if (classify(r) != NaN)
113                 return 1;
114             break;
115         case non_zero_nan:
116             if (classify(r) != NaN)
117                 return 1;
118             break;
119         }
120         break;
121     case inf:
122         switch (classify(divisor))
123         {
124         case zero:
125             if (classify(r) != NaN)
126                 return 1;
127             break;
128         case non_zero:
129             if (classify(r) != inf)
130                 return 1;
131             break;
132         case inf:
133             if (classify(r) != inf)
134                 return 1;
135             break;
136         case NaN:
137             if (classify(r) != NaN)
138                 return 1;
139             break;
140         case non_zero_nan:
141             if (classify(r) != inf)
142                 return 1;
143             break;
144         }
145         break;
146     case NaN:
147         switch (classify(divisor))
148         {
149         case zero:
150             if (classify(r) != NaN)
151                 return 1;
152             break;
153         case non_zero:
154             if (classify(r) != NaN)
155                 return 1;
156             break;
157         case inf:
158             if (classify(r) != NaN)
159                 return 1;
160             break;
161         case NaN:
162             if (classify(r) != NaN)
163                 return 1;
164             break;
165         case non_zero_nan:
166             if (classify(r) != NaN)
167                 return 1;
168             break;
169         }
170         break;
171     case non_zero_nan:
172         switch (classify(divisor))
173         {
174         case zero:
175             if (classify(r) != NaN)
176                 return 1;
177             break;
178         case non_zero:
179             if (classify(r) != NaN)
180                 return 1;
181             break;
182         case inf:
183             if (classify(r) != inf)
184                 return 1;
185             break;
186         case NaN:
187             if (classify(r) != NaN)
188                 return 1;
189             break;
190         case non_zero_nan:
191             if (classify(r) != NaN)
192                 return 1;
193             break;
194         }
195         break;
196     }
197 
198     return 0;
199 }
200 
201 long double x[][2] =
202 {
203     { 1.e-6,  1.e-6},
204     {-1.e-6,  1.e-6},
205     {-1.e-6, -1.e-6},
206     { 1.e-6, -1.e-6},
207 
208     { 1.e+6,  1.e-6},
209     {-1.e+6,  1.e-6},
210     {-1.e+6, -1.e-6},
211     { 1.e+6, -1.e-6},
212 
213     { 1.e-6,  1.e+6},
214     {-1.e-6,  1.e+6},
215     {-1.e-6, -1.e+6},
216     { 1.e-6, -1.e+6},
217 
218     { 1.e+6,  1.e+6},
219     {-1.e+6,  1.e+6},
220     {-1.e+6, -1.e+6},
221     { 1.e+6, -1.e+6},
222 
223     {NAN, NAN},
224     {-INFINITY, NAN},
225     {-2, NAN},
226     {-1, NAN},
227     {-0.5, NAN},
228     {-0., NAN},
229     {+0., NAN},
230     {0.5, NAN},
231     {1, NAN},
232     {2, NAN},
233     {INFINITY, NAN},
234 
235     {NAN, -INFINITY},
236     {-INFINITY, -INFINITY},
237     {-2, -INFINITY},
238     {-1, -INFINITY},
239     {-0.5, -INFINITY},
240     {-0., -INFINITY},
241     {+0., -INFINITY},
242     {0.5, -INFINITY},
243     {1, -INFINITY},
244     {2, -INFINITY},
245     {INFINITY, -INFINITY},
246 
247     {NAN, -2},
248     {-INFINITY, -2},
249     {-2, -2},
250     {-1, -2},
251     {-0.5, -2},
252     {-0., -2},
253     {+0., -2},
254     {0.5, -2},
255     {1, -2},
256     {2, -2},
257     {INFINITY, -2},
258 
259     {NAN, -1},
260     {-INFINITY, -1},
261     {-2, -1},
262     {-1, -1},
263     {-0.5, -1},
264     {-0., -1},
265     {+0., -1},
266     {0.5, -1},
267     {1, -1},
268     {2, -1},
269     {INFINITY, -1},
270 
271     {NAN, -0.5},
272     {-INFINITY, -0.5},
273     {-2, -0.5},
274     {-1, -0.5},
275     {-0.5, -0.5},
276     {-0., -0.5},
277     {+0., -0.5},
278     {0.5, -0.5},
279     {1, -0.5},
280     {2, -0.5},
281     {INFINITY, -0.5},
282 
283     {NAN, -0.},
284     {-INFINITY, -0.},
285     {-2, -0.},
286     {-1, -0.},
287     {-0.5, -0.},
288     {-0., -0.},
289     {+0., -0.},
290     {0.5, -0.},
291     {1, -0.},
292     {2, -0.},
293     {INFINITY, -0.},
294 
295     {NAN, 0.},
296     {-INFINITY, 0.},
297     {-2, 0.},
298     {-1, 0.},
299     {-0.5, 0.},
300     {-0., 0.},
301     {+0., 0.},
302     {0.5, 0.},
303     {1, 0.},
304     {2, 0.},
305     {INFINITY, 0.},
306 
307     {NAN, 0.5},
308     {-INFINITY, 0.5},
309     {-2, 0.5},
310     {-1, 0.5},
311     {-0.5, 0.5},
312     {-0., 0.5},
313     {+0., 0.5},
314     {0.5, 0.5},
315     {1, 0.5},
316     {2, 0.5},
317     {INFINITY, 0.5},
318 
319     {NAN, 1},
320     {-INFINITY, 1},
321     {-2, 1},
322     {-1, 1},
323     {-0.5, 1},
324     {-0., 1},
325     {+0., 1},
326     {0.5, 1},
327     {1, 1},
328     {2, 1},
329     {INFINITY, 1},
330 
331     {NAN, 2},
332     {-INFINITY, 2},
333     {-2, 2},
334     {-1, 2},
335     {-0.5, 2},
336     {-0., 2},
337     {+0., 2},
338     {0.5, 2},
339     {1, 2},
340     {2, 2},
341     {INFINITY, 2},
342 
343     {NAN, INFINITY},
344     {-INFINITY, INFINITY},
345     {-2, INFINITY},
346     {-1, INFINITY},
347     {-0.5, INFINITY},
348     {-0., INFINITY},
349     {+0., INFINITY},
350     {0.5, INFINITY},
351     {1, INFINITY},
352     {2, INFINITY},
353     {INFINITY, INFINITY}
354 
355 };
356 
357 #endif
358 
359 int main()
360 {
361 #if _ARCH_PPC || __aarch64__
362     const unsigned N = sizeof(x) / sizeof(x[0]);
363     unsigned i, j;
364     for (i = 0; i < N; ++i)
365     {
366         for (j = 0; j < N; ++j)
367         {
368             if (test__multc3(x[i][0], x[i][1], x[j][0], x[j][1]))
369                 return 1;
370         }
371     }
372 #else
373     printf("skipped\n");
374 #endif
375     return 0;
376 }
377