1214152Sed/* ===-- mulsc3.c - Implement __mulsc3 -------------------------------------===
2214152Sed *
3214152Sed *                     The LLVM Compiler Infrastructure
4214152Sed *
5222656Sed * This file is dual licensed under the MIT and the University of Illinois Open
6222656Sed * Source Licenses. See LICENSE.TXT for details.
7214152Sed *
8214152Sed * ===----------------------------------------------------------------------===
9214152Sed *
10214152Sed * This file implements __mulsc3 for the compiler_rt library.
11214152Sed *
12214152Sed * ===----------------------------------------------------------------------===
13214152Sed */
14214152Sed
15214152Sed#include "int_lib.h"
16229135Sed#include "int_math.h"
17214152Sed
18214152Sed/* Returns: the product of a + ib and c + id */
19214152Sed
20214152Sedfloat _Complex
21214152Sed__mulsc3(float __a, float __b, float __c, float __d)
22214152Sed{
23214152Sed    float __ac = __a * __c;
24214152Sed    float __bd = __b * __d;
25214152Sed    float __ad = __a * __d;
26214152Sed    float __bc = __b * __c;
27214152Sed    float _Complex z;
28214152Sed    __real__ z = __ac - __bd;
29214152Sed    __imag__ z = __ad + __bc;
30229135Sed    if (crt_isnan(__real__ z) && crt_isnan(__imag__ z))
31214152Sed    {
32214152Sed        int __recalc = 0;
33229135Sed        if (crt_isinf(__a) || crt_isinf(__b))
34214152Sed        {
35229135Sed            __a = crt_copysignf(crt_isinf(__a) ? 1 : 0, __a);
36229135Sed            __b = crt_copysignf(crt_isinf(__b) ? 1 : 0, __b);
37229135Sed            if (crt_isnan(__c))
38229135Sed                __c = crt_copysignf(0, __c);
39229135Sed            if (crt_isnan(__d))
40229135Sed                __d = crt_copysignf(0, __d);
41214152Sed            __recalc = 1;
42214152Sed        }
43229135Sed        if (crt_isinf(__c) || crt_isinf(__d))
44214152Sed        {
45229135Sed            __c = crt_copysignf(crt_isinf(__c) ? 1 : 0, __c);
46229135Sed            __d = crt_copysignf(crt_isinf(__d) ? 1 : 0, __d);
47229135Sed            if (crt_isnan(__a))
48229135Sed                __a = crt_copysignf(0, __a);
49229135Sed            if (crt_isnan(__b))
50229135Sed                __b = crt_copysignf(0, __b);
51214152Sed            __recalc = 1;
52214152Sed        }
53229135Sed        if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) ||
54229135Sed                          crt_isinf(__ad) || crt_isinf(__bc)))
55214152Sed        {
56229135Sed            if (crt_isnan(__a))
57229135Sed                __a = crt_copysignf(0, __a);
58229135Sed            if (crt_isnan(__b))
59229135Sed                __b = crt_copysignf(0, __b);
60229135Sed            if (crt_isnan(__c))
61229135Sed                __c = crt_copysignf(0, __c);
62229135Sed            if (crt_isnan(__d))
63229135Sed                __d = crt_copysignf(0, __d);
64214152Sed            __recalc = 1;
65214152Sed        }
66214152Sed        if (__recalc)
67214152Sed        {
68229135Sed            __real__ z = CRT_INFINITY * (__a * __c - __b * __d);
69229135Sed            __imag__ z = CRT_INFINITY * (__a * __d + __b * __c);
70214152Sed        }
71214152Sed    }
72214152Sed    return z;
73214152Sed}
74