10b57cec5SDimitry Andric //===-- mulxc3.c - Implement __mulxc3 -------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements __mulxc3 for the compiler_rt library. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #if !_ARCH_PPC 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "int_lib.h" 160b57cec5SDimitry Andric #include "int_math.h" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric // Returns: the product of a + ib and c + id 190b57cec5SDimitry Andric 20*5f757f3fSDimitry Andric COMPILER_RT_ABI Lcomplex __mulxc3(xf_float __a, xf_float __b, xf_float __c, 21*5f757f3fSDimitry Andric xf_float __d) { 22*5f757f3fSDimitry Andric xf_float __ac = __a * __c; 23*5f757f3fSDimitry Andric xf_float __bd = __b * __d; 24*5f757f3fSDimitry Andric xf_float __ad = __a * __d; 25*5f757f3fSDimitry Andric xf_float __bc = __b * __c; 260b57cec5SDimitry Andric Lcomplex z; 270b57cec5SDimitry Andric COMPLEX_REAL(z) = __ac - __bd; 280b57cec5SDimitry Andric COMPLEX_IMAGINARY(z) = __ad + __bc; 290b57cec5SDimitry Andric if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) { 300b57cec5SDimitry Andric int __recalc = 0; 310b57cec5SDimitry Andric if (crt_isinf(__a) || crt_isinf(__b)) { 320b57cec5SDimitry Andric __a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a); 330b57cec5SDimitry Andric __b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b); 340b57cec5SDimitry Andric if (crt_isnan(__c)) 350b57cec5SDimitry Andric __c = crt_copysignl(0, __c); 360b57cec5SDimitry Andric if (crt_isnan(__d)) 370b57cec5SDimitry Andric __d = crt_copysignl(0, __d); 380b57cec5SDimitry Andric __recalc = 1; 390b57cec5SDimitry Andric } 400b57cec5SDimitry Andric if (crt_isinf(__c) || crt_isinf(__d)) { 410b57cec5SDimitry Andric __c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c); 420b57cec5SDimitry Andric __d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d); 430b57cec5SDimitry Andric if (crt_isnan(__a)) 440b57cec5SDimitry Andric __a = crt_copysignl(0, __a); 450b57cec5SDimitry Andric if (crt_isnan(__b)) 460b57cec5SDimitry Andric __b = crt_copysignl(0, __b); 470b57cec5SDimitry Andric __recalc = 1; 480b57cec5SDimitry Andric } 490b57cec5SDimitry Andric if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) || crt_isinf(__ad) || 500b57cec5SDimitry Andric crt_isinf(__bc))) { 510b57cec5SDimitry Andric if (crt_isnan(__a)) 520b57cec5SDimitry Andric __a = crt_copysignl(0, __a); 530b57cec5SDimitry Andric if (crt_isnan(__b)) 540b57cec5SDimitry Andric __b = crt_copysignl(0, __b); 550b57cec5SDimitry Andric if (crt_isnan(__c)) 560b57cec5SDimitry Andric __c = crt_copysignl(0, __c); 570b57cec5SDimitry Andric if (crt_isnan(__d)) 580b57cec5SDimitry Andric __d = crt_copysignl(0, __d); 590b57cec5SDimitry Andric __recalc = 1; 600b57cec5SDimitry Andric } 610b57cec5SDimitry Andric if (__recalc) { 620b57cec5SDimitry Andric COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d); 630b57cec5SDimitry Andric COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c); 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric return z; 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric #endif 70