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