1214152Sed/* ===-- divxc3.c - Implement __divxc3 -------------------------------------=== 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 __divxc3 for the compiler_rt library. 11214152Sed * 12214152Sed */ 13214152Sed 14214152Sed#if !_ARCH_PPC 15214152Sed 16214152Sed#include "int_lib.h" 17229135Sed#include "int_math.h" 18214152Sed 19214152Sed/* Returns: the quotient of (a + ib) / (c + id) */ 20214152Sed 21214152Sedlong double _Complex 22214152Sed__divxc3(long double __a, long double __b, long double __c, long double __d) 23214152Sed{ 24214152Sed int __ilogbw = 0; 25229135Sed long double __logbw = crt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d))); 26229135Sed if (crt_isfinite(__logbw)) 27214152Sed { 28214152Sed __ilogbw = (int)__logbw; 29229135Sed __c = crt_scalbnl(__c, -__ilogbw); 30229135Sed __d = crt_scalbnl(__d, -__ilogbw); 31214152Sed } 32214152Sed long double __denom = __c * __c + __d * __d; 33214152Sed long double _Complex z; 34229135Sed __real__ z = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw); 35229135Sed __imag__ z = crt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw); 36229135Sed if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) 37214152Sed { 38229135Sed if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b))) 39214152Sed { 40229135Sed __real__ z = crt_copysignl(CRT_INFINITY, __c) * __a; 41229135Sed __imag__ z = crt_copysignl(CRT_INFINITY, __c) * __b; 42214152Sed } 43229135Sed else if ((crt_isinf(__a) || crt_isinf(__b)) && 44229135Sed crt_isfinite(__c) && crt_isfinite(__d)) 45214152Sed { 46229135Sed __a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a); 47229135Sed __b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b); 48229135Sed __real__ z = CRT_INFINITY * (__a * __c + __b * __d); 49229135Sed __imag__ z = CRT_INFINITY * (__b * __c - __a * __d); 50214152Sed } 51229135Sed else if (crt_isinf(__logbw) && __logbw > 0 && 52229135Sed crt_isfinite(__a) && crt_isfinite(__b)) 53214152Sed { 54229135Sed __c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c); 55229135Sed __d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d); 56214152Sed __real__ z = 0 * (__a * __c + __b * __d); 57214152Sed __imag__ z = 0 * (__b * __c - __a * __d); 58214152Sed } 59214152Sed } 60214152Sed return z; 61214152Sed} 62214152Sed 63214152Sed#endif 64