]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/compiler-rt/lib/mulxc3.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / compiler-rt / lib / mulxc3.c
1 /* ===-- mulxc3.c - Implement __mulxc3 -------------------------------------===
2  *
3  *                     The LLVM Compiler Infrastructure
4  *
5  * This file is dual licensed under the MIT and the University of Illinois Open
6  * Source Licenses. 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
23 long 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