1/* ===-- mulxc3.c - Implement __mulxc3 -------------------------------------===
2 *
3 *                     The LLVM Compiler Infrastructure
4 *
5 * This file is distributed under the University of Illinois Open Source
6 * License. See LICENSE.TXT for details.
7 *
8 * ===----------------------------------------------------------------------===
9 *
10 * This file implements __mulxc3 for the compiler_rt library.
11 *
12 * ===----------------------------------------------------------------------===
13 */
14
15#if !_ARCH_PPC
16
17#include "int_lib.h"
18#include <math.h>
19#include <complex.h>
20
21/* Returns: the product of a + ib and c + id */
22
23long double _Complex
24__mulxc3(long double __a, long double __b, long double __c, long double __d)
25{
26    long double __ac = __a * __c;
27    long double __bd = __b * __d;
28    long double __ad = __a * __d;
29    long double __bc = __b * __c;
30    long double _Complex z;
31    __real__ z = __ac - __bd;
32    __imag__ z = __ad + __bc;
33    if (isnan(__real__ z) && isnan(__imag__ z))
34    {
35        int __recalc = 0;
36        if (isinf(__a) || isinf(__b))
37        {
38            __a = copysignl(isinf(__a) ? 1 : 0, __a);
39            __b = copysignl(isinf(__b) ? 1 : 0, __b);
40            if (isnan(__c))
41                __c = copysignl(0, __c);
42            if (isnan(__d))
43                __d = copysignl(0, __d);
44            __recalc = 1;
45        }
46        if (isinf(__c) || isinf(__d))
47        {
48            __c = copysignl(isinf(__c) ? 1 : 0, __c);
49            __d = copysignl(isinf(__d) ? 1 : 0, __d);
50            if (isnan(__a))
51                __a = copysignl(0, __a);
52            if (isnan(__b))
53                __b = copysignl(0, __b);
54            __recalc = 1;
55        }
56        if (!__recalc && (isinf(__ac) || isinf(__bd) ||
57                          isinf(__ad) || isinf(__bc)))
58        {
59            if (isnan(__a))
60                __a = copysignl(0, __a);
61            if (isnan(__b))
62                __b = copysignl(0, __b);
63            if (isnan(__c))
64                __c = copysignl(0, __c);
65            if (isnan(__d))
66                __d = copysignl(0, __d);
67            __recalc = 1;
68        }
69        if (__recalc)
70        {
71            __real__ z = INFINITY * (__a * __c - __b * __d);
72            __imag__ z = INFINITY * (__a * __d + __b * __c);
73        }
74    }
75    return z;
76}
77
78#endif
79