1*0b57cec5SDimitry Andric //===-- multc3.c - Implement __multc3 -------------------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file implements __multc3 for the compiler_rt library. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include "int_lib.h" 14*0b57cec5SDimitry Andric #include "int_math.h" 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric // Returns: the product of a + ib and c + id 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric COMPILER_RT_ABI long double _Complex __multc3(long double a, long double b, 19*0b57cec5SDimitry Andric long double c, long double d) { 20*0b57cec5SDimitry Andric long double ac = a * c; 21*0b57cec5SDimitry Andric long double bd = b * d; 22*0b57cec5SDimitry Andric long double ad = a * d; 23*0b57cec5SDimitry Andric long double bc = b * c; 24*0b57cec5SDimitry Andric long double _Complex z; 25*0b57cec5SDimitry Andric __real__ z = ac - bd; 26*0b57cec5SDimitry Andric __imag__ z = ad + bc; 27*0b57cec5SDimitry Andric if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) { 28*0b57cec5SDimitry Andric int recalc = 0; 29*0b57cec5SDimitry Andric if (crt_isinf(a) || crt_isinf(b)) { 30*0b57cec5SDimitry Andric a = crt_copysignl(crt_isinf(a) ? 1 : 0, a); 31*0b57cec5SDimitry Andric b = crt_copysignl(crt_isinf(b) ? 1 : 0, b); 32*0b57cec5SDimitry Andric if (crt_isnan(c)) 33*0b57cec5SDimitry Andric c = crt_copysignl(0, c); 34*0b57cec5SDimitry Andric if (crt_isnan(d)) 35*0b57cec5SDimitry Andric d = crt_copysignl(0, d); 36*0b57cec5SDimitry Andric recalc = 1; 37*0b57cec5SDimitry Andric } 38*0b57cec5SDimitry Andric if (crt_isinf(c) || crt_isinf(d)) { 39*0b57cec5SDimitry Andric c = crt_copysignl(crt_isinf(c) ? 1 : 0, c); 40*0b57cec5SDimitry Andric d = crt_copysignl(crt_isinf(d) ? 1 : 0, d); 41*0b57cec5SDimitry Andric if (crt_isnan(a)) 42*0b57cec5SDimitry Andric a = crt_copysignl(0, a); 43*0b57cec5SDimitry Andric if (crt_isnan(b)) 44*0b57cec5SDimitry Andric b = crt_copysignl(0, b); 45*0b57cec5SDimitry Andric recalc = 1; 46*0b57cec5SDimitry Andric } 47*0b57cec5SDimitry Andric if (!recalc && 48*0b57cec5SDimitry Andric (crt_isinf(ac) || crt_isinf(bd) || crt_isinf(ad) || crt_isinf(bc))) { 49*0b57cec5SDimitry Andric if (crt_isnan(a)) 50*0b57cec5SDimitry Andric a = crt_copysignl(0, a); 51*0b57cec5SDimitry Andric if (crt_isnan(b)) 52*0b57cec5SDimitry Andric b = crt_copysignl(0, b); 53*0b57cec5SDimitry Andric if (crt_isnan(c)) 54*0b57cec5SDimitry Andric c = crt_copysignl(0, c); 55*0b57cec5SDimitry Andric if (crt_isnan(d)) 56*0b57cec5SDimitry Andric d = crt_copysignl(0, d); 57*0b57cec5SDimitry Andric recalc = 1; 58*0b57cec5SDimitry Andric } 59*0b57cec5SDimitry Andric if (recalc) { 60*0b57cec5SDimitry Andric __real__ z = CRT_INFINITY * (a * c - b * d); 61*0b57cec5SDimitry Andric __imag__ z = CRT_INFINITY * (a * d + b * c); 62*0b57cec5SDimitry Andric } 63*0b57cec5SDimitry Andric } 64*0b57cec5SDimitry Andric return z; 65*0b57cec5SDimitry Andric } 66