1*ef84fd3bSjoerg /* ===-- multc3.c - Implement __multc3 -------------------------------------===
2*ef84fd3bSjoerg *
3*ef84fd3bSjoerg * The LLVM Compiler Infrastructure
4*ef84fd3bSjoerg *
5*ef84fd3bSjoerg * This file is dual licensed under the MIT and the University of Illinois Open
6*ef84fd3bSjoerg * Source Licenses. See LICENSE.TXT for details.
7*ef84fd3bSjoerg *
8*ef84fd3bSjoerg * ===----------------------------------------------------------------------===
9*ef84fd3bSjoerg *
10*ef84fd3bSjoerg * This file implements __multc3 for the compiler_rt library.
11*ef84fd3bSjoerg *
12*ef84fd3bSjoerg * ===----------------------------------------------------------------------===
13*ef84fd3bSjoerg */
14*ef84fd3bSjoerg
15*ef84fd3bSjoerg #include "int_lib.h"
16*ef84fd3bSjoerg #include "int_math.h"
17*ef84fd3bSjoerg
18*ef84fd3bSjoerg /* Returns: the product of a + ib and c + id */
19*ef84fd3bSjoerg
20*ef84fd3bSjoerg COMPILER_RT_ABI long double _Complex
__multc3(long double a,long double b,long double c,long double d)21*ef84fd3bSjoerg __multc3(long double a, long double b, long double c, long double d)
22*ef84fd3bSjoerg {
23*ef84fd3bSjoerg long double ac = a * c;
24*ef84fd3bSjoerg long double bd = b * d;
25*ef84fd3bSjoerg long double ad = a * d;
26*ef84fd3bSjoerg long double bc = b * c;
27*ef84fd3bSjoerg long double _Complex z;
28*ef84fd3bSjoerg __real__ z = ac - bd;
29*ef84fd3bSjoerg __imag__ z = ad + bc;
30*ef84fd3bSjoerg if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) {
31*ef84fd3bSjoerg int recalc = 0;
32*ef84fd3bSjoerg if (crt_isinf(a) || crt_isinf(b)) {
33*ef84fd3bSjoerg a = crt_copysignl(crt_isinf(a) ? 1 : 0, a);
34*ef84fd3bSjoerg b = crt_copysignl(crt_isinf(b) ? 1 : 0, b);
35*ef84fd3bSjoerg if (crt_isnan(c))
36*ef84fd3bSjoerg c = crt_copysignl(0, c);
37*ef84fd3bSjoerg if (crt_isnan(d))
38*ef84fd3bSjoerg d = crt_copysignl(0, d);
39*ef84fd3bSjoerg recalc = 1;
40*ef84fd3bSjoerg }
41*ef84fd3bSjoerg if (crt_isinf(c) || crt_isinf(d)) {
42*ef84fd3bSjoerg c = crt_copysignl(crt_isinf(c) ? 1 : 0, c);
43*ef84fd3bSjoerg d = crt_copysignl(crt_isinf(d) ? 1 : 0, d);
44*ef84fd3bSjoerg if (crt_isnan(a))
45*ef84fd3bSjoerg a = crt_copysignl(0, a);
46*ef84fd3bSjoerg if (crt_isnan(b))
47*ef84fd3bSjoerg b = crt_copysignl(0, b);
48*ef84fd3bSjoerg recalc = 1;
49*ef84fd3bSjoerg }
50*ef84fd3bSjoerg if (!recalc && (crt_isinf(ac) || crt_isinf(bd) ||
51*ef84fd3bSjoerg crt_isinf(ad) || crt_isinf(bc))) {
52*ef84fd3bSjoerg if (crt_isnan(a))
53*ef84fd3bSjoerg a = crt_copysignl(0, a);
54*ef84fd3bSjoerg if (crt_isnan(b))
55*ef84fd3bSjoerg b = crt_copysignl(0, b);
56*ef84fd3bSjoerg if (crt_isnan(c))
57*ef84fd3bSjoerg c = crt_copysignl(0, c);
58*ef84fd3bSjoerg if (crt_isnan(d))
59*ef84fd3bSjoerg d = crt_copysignl(0, d);
60*ef84fd3bSjoerg recalc = 1;
61*ef84fd3bSjoerg }
62*ef84fd3bSjoerg if (recalc) {
63*ef84fd3bSjoerg __real__ z = CRT_INFINITY * (a * c - b * d);
64*ef84fd3bSjoerg __imag__ z = CRT_INFINITY * (a * d + b * c);
65*ef84fd3bSjoerg }
66*ef84fd3bSjoerg }
67*ef84fd3bSjoerg return z;
68*ef84fd3bSjoerg }
69