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