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