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