1276789Sdim/* ===-- mulxc3.c - Implement __mulxc3 -------------------------------------=== 2276789Sdim * 3276789Sdim * The LLVM Compiler Infrastructure 4276789Sdim * 5276789Sdim * This file is dual licensed under the MIT and the University of Illinois Open 6276789Sdim * Source Licenses. See LICENSE.TXT for details. 7276789Sdim * 8276789Sdim * ===----------------------------------------------------------------------=== 9276789Sdim * 10276789Sdim * This file implements __mulxc3 for the compiler_rt library. 11276789Sdim * 12276789Sdim * ===----------------------------------------------------------------------=== 13276789Sdim */ 14276789Sdim 15276789Sdim#if !_ARCH_PPC 16276789Sdim 17276789Sdim#include "int_lib.h" 18276789Sdim#include "int_math.h" 19276789Sdim 20276789Sdim/* Returns: the product of a + ib and c + id */ 21276789Sdim 22296417SdimCOMPILER_RT_ABI Lcomplex 23276789Sdim__mulxc3(long double __a, long double __b, long double __c, long double __d) 24276789Sdim{ 25276789Sdim long double __ac = __a * __c; 26276789Sdim long double __bd = __b * __d; 27276789Sdim long double __ad = __a * __d; 28276789Sdim long double __bc = __b * __c; 29296417Sdim Lcomplex z; 30296417Sdim COMPLEX_REAL(z) = __ac - __bd; 31296417Sdim COMPLEX_IMAGINARY(z) = __ad + __bc; 32296417Sdim if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) 33276789Sdim { 34276789Sdim int __recalc = 0; 35276789Sdim if (crt_isinf(__a) || crt_isinf(__b)) 36276789Sdim { 37276789Sdim __a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a); 38276789Sdim __b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b); 39276789Sdim if (crt_isnan(__c)) 40276789Sdim __c = crt_copysignl(0, __c); 41276789Sdim if (crt_isnan(__d)) 42276789Sdim __d = crt_copysignl(0, __d); 43276789Sdim __recalc = 1; 44276789Sdim } 45276789Sdim if (crt_isinf(__c) || crt_isinf(__d)) 46276789Sdim { 47276789Sdim __c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c); 48276789Sdim __d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d); 49276789Sdim if (crt_isnan(__a)) 50276789Sdim __a = crt_copysignl(0, __a); 51276789Sdim if (crt_isnan(__b)) 52276789Sdim __b = crt_copysignl(0, __b); 53276789Sdim __recalc = 1; 54276789Sdim } 55276789Sdim if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) || 56276789Sdim crt_isinf(__ad) || crt_isinf(__bc))) 57276789Sdim { 58276789Sdim if (crt_isnan(__a)) 59276789Sdim __a = crt_copysignl(0, __a); 60276789Sdim if (crt_isnan(__b)) 61276789Sdim __b = crt_copysignl(0, __b); 62276789Sdim if (crt_isnan(__c)) 63276789Sdim __c = crt_copysignl(0, __c); 64276789Sdim if (crt_isnan(__d)) 65276789Sdim __d = crt_copysignl(0, __d); 66276789Sdim __recalc = 1; 67276789Sdim } 68276789Sdim if (__recalc) 69276789Sdim { 70296417Sdim COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d); 71296417Sdim COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c); 72276789Sdim } 73276789Sdim } 74276789Sdim return z; 75276789Sdim} 76276789Sdim 77276789Sdim#endif 78