1214152Sed/* ===-- muldc3.c - Implement __muldc3 -------------------------------------=== 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 __muldc3 for the compiler_rt library. 11214152Sed * 12214152Sed * ===----------------------------------------------------------------------=== 13214152Sed */ 14214152Sed 15214152Sed#include "int_lib.h" 16236011Smarius#include "int_math.h" 17214152Sed 18214152Sed/* Returns: the product of a + ib and c + id */ 19214152Sed 20214152Seddouble _Complex 21214152Sed__muldc3(double __a, double __b, double __c, double __d) 22214152Sed{ 23214152Sed double __ac = __a * __c; 24214152Sed double __bd = __b * __d; 25214152Sed double __ad = __a * __d; 26214152Sed double __bc = __b * __c; 27214152Sed double _Complex z; 28214152Sed __real__ z = __ac - __bd; 29214152Sed __imag__ z = __ad + __bc; 30236011Smarius if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) 31214152Sed { 32214152Sed int __recalc = 0; 33236011Smarius if (crt_isinf(__a) || crt_isinf(__b)) 34214152Sed { 35236011Smarius __a = crt_copysign(crt_isinf(__a) ? 1 : 0, __a); 36236011Smarius __b = crt_copysign(crt_isinf(__b) ? 1 : 0, __b); 37236011Smarius if (crt_isnan(__c)) 38236011Smarius __c = crt_copysign(0, __c); 39236011Smarius if (crt_isnan(__d)) 40236011Smarius __d = crt_copysign(0, __d); 41214152Sed __recalc = 1; 42214152Sed } 43236011Smarius if (crt_isinf(__c) || crt_isinf(__d)) 44214152Sed { 45236011Smarius __c = crt_copysign(crt_isinf(__c) ? 1 : 0, __c); 46236011Smarius __d = crt_copysign(crt_isinf(__d) ? 1 : 0, __d); 47236011Smarius if (crt_isnan(__a)) 48236011Smarius __a = crt_copysign(0, __a); 49236011Smarius if (crt_isnan(__b)) 50236011Smarius __b = crt_copysign(0, __b); 51214152Sed __recalc = 1; 52214152Sed } 53236011Smarius if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) || 54236011Smarius crt_isinf(__ad) || crt_isinf(__bc))) 55214152Sed { 56236011Smarius if (crt_isnan(__a)) 57236011Smarius __a = crt_copysign(0, __a); 58236011Smarius if (crt_isnan(__b)) 59236011Smarius __b = crt_copysign(0, __b); 60236011Smarius if (crt_isnan(__c)) 61236011Smarius __c = crt_copysign(0, __c); 62236011Smarius if (crt_isnan(__d)) 63236011Smarius __d = crt_copysign(0, __d); 64214152Sed __recalc = 1; 65214152Sed } 66214152Sed if (__recalc) 67214152Sed { 68236011Smarius __real__ z = CRT_INFINITY * (__a * __c - __b * __d); 69236011Smarius __imag__ z = CRT_INFINITY * (__a * __d + __b * __c); 70214152Sed } 71214152Sed } 72214152Sed return z; 73214152Sed} 74