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