1156cd587Sjoerg /* ===-- muldc3.c - Implement __muldc3 -------------------------------------===
2156cd587Sjoerg *
3156cd587Sjoerg * The LLVM Compiler Infrastructure
4156cd587Sjoerg *
5156cd587Sjoerg * This file is dual licensed under the MIT and the University of Illinois Open
6156cd587Sjoerg * Source Licenses. See LICENSE.TXT for details.
7156cd587Sjoerg *
8156cd587Sjoerg * ===----------------------------------------------------------------------===
9156cd587Sjoerg *
10156cd587Sjoerg * This file implements __muldc3 for the compiler_rt library.
11156cd587Sjoerg *
12156cd587Sjoerg * ===----------------------------------------------------------------------===
13156cd587Sjoerg */
14156cd587Sjoerg
15156cd587Sjoerg #include "int_lib.h"
16156cd587Sjoerg #include "int_math.h"
17156cd587Sjoerg
18156cd587Sjoerg /* Returns: the product of a + ib and c + id */
19156cd587Sjoerg
20*ef84fd3bSjoerg COMPILER_RT_ABI Dcomplex
__muldc3(double __a,double __b,double __c,double __d)21156cd587Sjoerg __muldc3(double __a, double __b, double __c, double __d)
22156cd587Sjoerg {
23156cd587Sjoerg double __ac = __a * __c;
24156cd587Sjoerg double __bd = __b * __d;
25156cd587Sjoerg double __ad = __a * __d;
26156cd587Sjoerg double __bc = __b * __c;
27*ef84fd3bSjoerg Dcomplex z;
28*ef84fd3bSjoerg COMPLEX_REAL(z) = __ac - __bd;
29*ef84fd3bSjoerg COMPLEX_IMAGINARY(z) = __ad + __bc;
30*ef84fd3bSjoerg if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
31156cd587Sjoerg {
32156cd587Sjoerg int __recalc = 0;
33156cd587Sjoerg if (crt_isinf(__a) || crt_isinf(__b))
34156cd587Sjoerg {
35156cd587Sjoerg __a = crt_copysign(crt_isinf(__a) ? 1 : 0, __a);
36156cd587Sjoerg __b = crt_copysign(crt_isinf(__b) ? 1 : 0, __b);
37156cd587Sjoerg if (crt_isnan(__c))
38156cd587Sjoerg __c = crt_copysign(0, __c);
39156cd587Sjoerg if (crt_isnan(__d))
40156cd587Sjoerg __d = crt_copysign(0, __d);
41156cd587Sjoerg __recalc = 1;
42156cd587Sjoerg }
43156cd587Sjoerg if (crt_isinf(__c) || crt_isinf(__d))
44156cd587Sjoerg {
45156cd587Sjoerg __c = crt_copysign(crt_isinf(__c) ? 1 : 0, __c);
46156cd587Sjoerg __d = crt_copysign(crt_isinf(__d) ? 1 : 0, __d);
47156cd587Sjoerg if (crt_isnan(__a))
48156cd587Sjoerg __a = crt_copysign(0, __a);
49156cd587Sjoerg if (crt_isnan(__b))
50156cd587Sjoerg __b = crt_copysign(0, __b);
51156cd587Sjoerg __recalc = 1;
52156cd587Sjoerg }
53156cd587Sjoerg if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) ||
54156cd587Sjoerg crt_isinf(__ad) || crt_isinf(__bc)))
55156cd587Sjoerg {
56156cd587Sjoerg if (crt_isnan(__a))
57156cd587Sjoerg __a = crt_copysign(0, __a);
58156cd587Sjoerg if (crt_isnan(__b))
59156cd587Sjoerg __b = crt_copysign(0, __b);
60156cd587Sjoerg if (crt_isnan(__c))
61156cd587Sjoerg __c = crt_copysign(0, __c);
62156cd587Sjoerg if (crt_isnan(__d))
63156cd587Sjoerg __d = crt_copysign(0, __d);
64156cd587Sjoerg __recalc = 1;
65156cd587Sjoerg }
66156cd587Sjoerg if (__recalc)
67156cd587Sjoerg {
68*ef84fd3bSjoerg COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d);
69*ef84fd3bSjoerg COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c);
70156cd587Sjoerg }
71156cd587Sjoerg }
72156cd587Sjoerg return z;
73156cd587Sjoerg }
74