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