1156cd587Sjoerg /* ===-- mulxc3.c - Implement __mulxc3 -------------------------------------===
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 __mulxc3 for the compiler_rt library.
11156cd587Sjoerg *
12156cd587Sjoerg * ===----------------------------------------------------------------------===
13156cd587Sjoerg */
14156cd587Sjoerg
15156cd587Sjoerg #if !_ARCH_PPC
16156cd587Sjoerg
17156cd587Sjoerg #include "int_lib.h"
18156cd587Sjoerg #include "int_math.h"
19156cd587Sjoerg
20156cd587Sjoerg /* Returns: the product of a + ib and c + id */
21156cd587Sjoerg
22*ef84fd3bSjoerg COMPILER_RT_ABI Lcomplex
__mulxc3(long double __a,long double __b,long double __c,long double __d)23156cd587Sjoerg __mulxc3(long double __a, long double __b, long double __c, long double __d)
24156cd587Sjoerg {
25156cd587Sjoerg long double __ac = __a * __c;
26156cd587Sjoerg long double __bd = __b * __d;
27156cd587Sjoerg long double __ad = __a * __d;
28156cd587Sjoerg long double __bc = __b * __c;
29*ef84fd3bSjoerg Lcomplex z;
30*ef84fd3bSjoerg COMPLEX_REAL(z) = __ac - __bd;
31*ef84fd3bSjoerg COMPLEX_IMAGINARY(z) = __ad + __bc;
32*ef84fd3bSjoerg if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
33156cd587Sjoerg {
34156cd587Sjoerg int __recalc = 0;
35156cd587Sjoerg if (crt_isinf(__a) || crt_isinf(__b))
36156cd587Sjoerg {
37156cd587Sjoerg __a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a);
38156cd587Sjoerg __b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b);
39156cd587Sjoerg if (crt_isnan(__c))
40156cd587Sjoerg __c = crt_copysignl(0, __c);
41156cd587Sjoerg if (crt_isnan(__d))
42156cd587Sjoerg __d = crt_copysignl(0, __d);
43156cd587Sjoerg __recalc = 1;
44156cd587Sjoerg }
45156cd587Sjoerg if (crt_isinf(__c) || crt_isinf(__d))
46156cd587Sjoerg {
47156cd587Sjoerg __c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c);
48156cd587Sjoerg __d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d);
49156cd587Sjoerg if (crt_isnan(__a))
50156cd587Sjoerg __a = crt_copysignl(0, __a);
51156cd587Sjoerg if (crt_isnan(__b))
52156cd587Sjoerg __b = crt_copysignl(0, __b);
53156cd587Sjoerg __recalc = 1;
54156cd587Sjoerg }
55156cd587Sjoerg if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) ||
56156cd587Sjoerg crt_isinf(__ad) || crt_isinf(__bc)))
57156cd587Sjoerg {
58156cd587Sjoerg if (crt_isnan(__a))
59156cd587Sjoerg __a = crt_copysignl(0, __a);
60156cd587Sjoerg if (crt_isnan(__b))
61156cd587Sjoerg __b = crt_copysignl(0, __b);
62156cd587Sjoerg if (crt_isnan(__c))
63156cd587Sjoerg __c = crt_copysignl(0, __c);
64156cd587Sjoerg if (crt_isnan(__d))
65156cd587Sjoerg __d = crt_copysignl(0, __d);
66156cd587Sjoerg __recalc = 1;
67156cd587Sjoerg }
68156cd587Sjoerg if (__recalc)
69156cd587Sjoerg {
70*ef84fd3bSjoerg COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d);
71*ef84fd3bSjoerg COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c);
72156cd587Sjoerg }
73156cd587Sjoerg }
74156cd587Sjoerg return z;
75156cd587Sjoerg }
76156cd587Sjoerg
77156cd587Sjoerg #endif
78