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