1 // RUN: %clang_builtins %s %librt -lm -o %t && %run %t
2 // REQUIRES: librt_has_divtc3
3 // REQUIRES: c99-complex
7 // XFAIL: sparc-target-arch
16 // Returns: the quotient of (a + ib) / (c + id)
18 COMPILER_RT_ABI Qcomplex
__divtc3(tf_float __a
, tf_float __b
, tf_float __c
,
21 enum {zero
, non_zero
, inf
, NaN
, non_zero_nan
};
23 static int classify(Qcomplex x
) {
24 tf_float real
= COMPLEXTF_REAL(x
);
25 tf_float imag
= COMPLEXTF_IMAGINARY(x
);
26 if (real
== 0.0 && imag
== 0.0)
28 if (crt_isinf(real
) || crt_isinf(imag
))
30 if (crt_isnan(real
) && crt_isnan(imag
))
32 if (crt_isnan(real
)) {
37 if (crt_isnan(imag
)) {
45 static int test__divtc3(tf_float a
, tf_float b
, tf_float c
, tf_float d
) {
46 Qcomplex r
= __divtc3(a
, b
, c
, d
);
50 COMPLEXTF_REAL(dividend
) = a
;
51 COMPLEXTF_IMAGINARY(dividend
) = b
;
52 COMPLEXTF_REAL(divisor
) = c
;
53 COMPLEXTF_IMAGINARY(divisor
) = d
;
55 switch (classify(dividend
)) {
57 switch (classify(divisor
)) {
59 if (classify(r
) != NaN
)
63 if (classify(r
) != zero
)
67 if (classify(r
) != zero
)
71 if (classify(r
) != NaN
)
75 if (classify(r
) != NaN
)
81 switch (classify(divisor
)) {
83 if (classify(r
) != inf
)
87 if (classify(r
) != non_zero
)
90 tf_float zReal
= (a
* c
+ b
* d
) / (c
* c
+ d
* d
);
91 tf_float zImag
= (b
* c
- a
* d
) / (c
* c
+ d
* d
);
93 __divtc3(COMPLEXTF_REAL(r
) - zReal
, COMPLEXTF_IMAGINARY(r
) - zImag
,
94 COMPLEXTF_REAL(r
), COMPLEXTF_IMAGINARY(r
));
95 // cabsl(z) == hypotl(creall(z), cimagl(z))
96 #ifdef CRT_LDBL_128BIT
97 if (hypotl(COMPLEXTF_REAL(diff
), COMPLEXTF_IMAGINARY(diff
)) > 1.e
-6)
99 // Avoid dependency on __trunctfxf2 for ld80 platforms and use double instead.
100 if (hypot(COMPLEXTF_REAL(diff
), COMPLEXTF_IMAGINARY(diff
)) > 1.e
-6)
106 if (classify(r
) != zero
)
110 if (classify(r
) != NaN
)
114 if (classify(r
) != NaN
)
120 switch (classify(divisor
)) {
122 if (classify(r
) != inf
)
126 if (classify(r
) != inf
)
130 if (classify(r
) != NaN
)
134 if (classify(r
) != NaN
)
138 if (classify(r
) != NaN
)
144 switch (classify(divisor
)) {
146 if (classify(r
) != NaN
)
150 if (classify(r
) != NaN
)
154 if (classify(r
) != NaN
)
158 if (classify(r
) != NaN
)
162 if (classify(r
) != NaN
)
168 switch (classify(divisor
)) {
170 if (classify(r
) != inf
)
174 if (classify(r
) != NaN
)
178 if (classify(r
) != NaN
)
182 if (classify(r
) != NaN
)
186 if (classify(r
) != NaN
)
196 tf_float x
[][2] = {{1.e
-6, 1.e
-6},
229 {-INFINITY
, -INFINITY
},
238 {INFINITY
, -INFINITY
},
337 {-INFINITY
, INFINITY
},
351 const unsigned N
= sizeof(x
) / sizeof(x
[0]);
353 for (i
= 0; i
< N
; ++i
) {
354 for (j
= 0; j
< N
; ++j
) {
355 if (test__divtc3(x
[i
][0], x
[i
][1], x
[j
][0], x
[j
][1])) {
356 fprintf(stderr
, "Failed for %g, %g, %g, %g\n", (double)x
[i
][0],
357 (double)x
[i
][1], (double)x
[j
][0], (double)x
[j
][1]);
363 fprintf(stderr
, "No errors found.\n");