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

source code of compiler-rt/test/builtins/Unit/multc3_test.c