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