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 "int_math.h" 19 20 /* Returns: the product of a + ib and c + id */ 21 22 long double _Complex 23 __mulxc3(long double __a, long double __b, long double __c, long double __d) 24 { 25 long double __ac = __a * __c; 26 long double __bd = __b * __d; 27 long double __ad = __a * __d; 28 long double __bc = __b * __c; 29 long double _Complex z; 30 __real__ z = __ac - __bd; 31 __imag__ z = __ad + __bc; 32 if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) 33 { 34 int __recalc = 0; 35 if (crt_isinf(__a) || crt_isinf(__b)) 36 { 37 __a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a); 38 __b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b); 39 if (crt_isnan(__c)) 40 __c = crt_copysignl(0, __c); 41 if (crt_isnan(__d)) 42 __d = crt_copysignl(0, __d); 43 __recalc = 1; 44 } 45 if (crt_isinf(__c) || crt_isinf(__d)) 46 { 47 __c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c); 48 __d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d); 49 if (crt_isnan(__a)) 50 __a = crt_copysignl(0, __a); 51 if (crt_isnan(__b)) 52 __b = crt_copysignl(0, __b); 53 __recalc = 1; 54 } 55 if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) || 56 crt_isinf(__ad) || crt_isinf(__bc))) 57 { 58 if (crt_isnan(__a)) 59 __a = crt_copysignl(0, __a); 60 if (crt_isnan(__b)) 61 __b = crt_copysignl(0, __b); 62 if (crt_isnan(__c)) 63 __c = crt_copysignl(0, __c); 64 if (crt_isnan(__d)) 65 __d = crt_copysignl(0, __d); 66 __recalc = 1; 67 } 68 if (__recalc) 69 { 70 __real__ z = CRT_INFINITY * (__a * __c - __b * __d); 71 __imag__ z = CRT_INFINITY * (__a * __d + __b * __c); 72 } 73 } 74 return z; 75 } 76 77 #endif 78