1 /* ===-- divdc3.c - Implement __divdc3 -------------------------------------===
3 * The LLVM Compiler Infrastructure
5 * This file is dual licensed under the MIT and the University of Illinois Open
6 * Source Licenses. See LICENSE.TXT for details.
8 * ===----------------------------------------------------------------------===
10 * This file implements __divdc3 for the compiler_rt library.
12 * ===----------------------------------------------------------------------===
18 /* Returns: the quotient of (a + ib) / (c + id) */
20 COMPILER_RT_ABI
double _Complex
21 __divdc3(double __a
, double __b
, double __c
, double __d
)
24 double __logbw
= crt_logb(crt_fmax(crt_fabs(__c
), crt_fabs(__d
)));
25 if (crt_isfinite(__logbw
))
27 __ilogbw
= (int)__logbw
;
28 __c
= crt_scalbn(__c
, -__ilogbw
);
29 __d
= crt_scalbn(__d
, -__ilogbw
);
31 double __denom
= __c
* __c
+ __d
* __d
;
33 __real__ z
= crt_scalbn((__a
* __c
+ __b
* __d
) / __denom
, -__ilogbw
);
34 __imag__ z
= crt_scalbn((__b
* __c
- __a
* __d
) / __denom
, -__ilogbw
);
35 if (crt_isnan(__real__ z
) && crt_isnan(__imag__ z
))
37 if ((__denom
== 0.0) && (!crt_isnan(__a
) || !crt_isnan(__b
)))
39 __real__ z
= crt_copysign(CRT_INFINITY
, __c
) * __a
;
40 __imag__ z
= crt_copysign(CRT_INFINITY
, __c
) * __b
;
42 else if ((crt_isinf(__a
) || crt_isinf(__b
)) &&
43 crt_isfinite(__c
) && crt_isfinite(__d
))
45 __a
= crt_copysign(crt_isinf(__a
) ? 1.0 : 0.0, __a
);
46 __b
= crt_copysign(crt_isinf(__b
) ? 1.0 : 0.0, __b
);
47 __real__ z
= CRT_INFINITY
* (__a
* __c
+ __b
* __d
);
48 __imag__ z
= CRT_INFINITY
* (__b
* __c
- __a
* __d
);
50 else if (crt_isinf(__logbw
) && __logbw
> 0.0 &&
51 crt_isfinite(__a
) && crt_isfinite(__b
))
53 __c
= crt_copysign(crt_isinf(__c
) ? 1.0 : 0.0, __c
);
54 __d
= crt_copysign(crt_isinf(__d
) ? 1.0 : 0.0, __d
);
55 __real__ z
= 0.0 * (__a
* __c
+ __b
* __d
);
56 __imag__ z
= 0.0 * (__b
* __c
- __a
* __d
);