xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/builtins/mulxc3.c (revision ef84fd3bd8895f4e6be1e38baf19e6dc3255bc64)
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