1 //===-- divtc3.c - Implement __divtc3 -------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements __divtc3 for the compiler_rt library.
11 //===----------------------------------------------------------------------===//
13 #define QUAD_PRECISION
16 #if defined(CRT_HAS_TF_MODE)
18 // Returns: the quotient of (a + ib) / (c + id)
20 COMPILER_RT_ABI Qcomplex
__divtc3(fp_t __a
, fp_t __b
, fp_t __c
, fp_t __d
) {
22 fp_t __logbw
= __compiler_rt_logbtf(
23 __compiler_rt_fmaxtf(crt_fabstf(__c
), crt_fabstf(__d
)));
24 if (crt_isfinite(__logbw
)) {
25 __ilogbw
= (int)__logbw
;
26 __c
= __compiler_rt_scalbntf(__c
, -__ilogbw
);
27 __d
= __compiler_rt_scalbntf(__d
, -__ilogbw
);
29 fp_t __denom
= __c
* __c
+ __d
* __d
;
32 __compiler_rt_scalbntf((__a
* __c
+ __b
* __d
) / __denom
, -__ilogbw
);
33 COMPLEXTF_IMAGINARY(z
) =
34 __compiler_rt_scalbntf((__b
* __c
- __a
* __d
) / __denom
, -__ilogbw
);
35 if (crt_isnan(COMPLEXTF_REAL(z
)) && crt_isnan(COMPLEXTF_IMAGINARY(z
))) {
36 if ((__denom
== 0.0) && (!crt_isnan(__a
) || !crt_isnan(__b
))) {
37 COMPLEXTF_REAL(z
) = crt_copysigntf(CRT_INFINITY
, __c
) * __a
;
38 COMPLEXTF_IMAGINARY(z
) = crt_copysigntf(CRT_INFINITY
, __c
) * __b
;
39 } else if ((crt_isinf(__a
) || crt_isinf(__b
)) && crt_isfinite(__c
) &&
41 __a
= crt_copysigntf(crt_isinf(__a
) ? (fp_t
)1.0 : (fp_t
)0.0, __a
);
42 __b
= crt_copysigntf(crt_isinf(__b
) ? (fp_t
)1.0 : (fp_t
)0.0, __b
);
43 COMPLEXTF_REAL(z
) = CRT_INFINITY
* (__a
* __c
+ __b
* __d
);
44 COMPLEXTF_IMAGINARY(z
) = CRT_INFINITY
* (__b
* __c
- __a
* __d
);
45 } else if (crt_isinf(__logbw
) && __logbw
> 0.0 && crt_isfinite(__a
) &&
47 __c
= crt_copysigntf(crt_isinf(__c
) ? (fp_t
)1.0 : (fp_t
)0.0, __c
);
48 __d
= crt_copysigntf(crt_isinf(__d
) ? (fp_t
)1.0 : (fp_t
)0.0, __d
);
49 COMPLEXTF_REAL(z
) = 0.0 * (__a
* __c
+ __b
* __d
);
50 COMPLEXTF_IMAGINARY(z
) = 0.0 * (__b
* __c
- __a
* __d
);