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