Home | History | Annotate | Download | only in lib
      1 /* ===-- mulxc3.c - Implement __mulxc3 -------------------------------------===
      2  *
      3  *                     The LLVM Compiler Infrastructure
      4  *
      5  * This file is distributed under the University of Illinois Open Source
      6  * License. See LICENSE.TXT for details.
      7  *
      8  * ===----------------------------------------------------------------------===
      9  *
     10  * This file implements __mulxc3 for the compiler_rt library.
     11  *
     12  * ===----------------------------------------------------------------------===
     13  */
     14 
     15 #if !_ARCH_PPC
     16 
     17 #include "int_lib.h"
     18 #include <math.h>
     19 #include <complex.h>
     20 
     21 /* Returns: the product of a + ib and c + id */
     22 
     23 long double _Complex
     24 __mulxc3(long double __a, long double __b, long double __c, long double __d)
     25 {
     26     long double __ac = __a * __c;
     27     long double __bd = __b * __d;
     28     long double __ad = __a * __d;
     29     long double __bc = __b * __c;
     30     long double _Complex z;
     31     __real__ z = __ac - __bd;
     32     __imag__ z = __ad + __bc;
     33     if (isnan(__real__ z) && isnan(__imag__ z))
     34     {
     35         int __recalc = 0;
     36         if (isinf(__a) || isinf(__b))
     37         {
     38             __a = copysignl(isinf(__a) ? 1 : 0, __a);
     39             __b = copysignl(isinf(__b) ? 1 : 0, __b);
     40             if (isnan(__c))
     41                 __c = copysignl(0, __c);
     42             if (isnan(__d))
     43                 __d = copysignl(0, __d);
     44             __recalc = 1;
     45         }
     46         if (isinf(__c) || isinf(__d))
     47         {
     48             __c = copysignl(isinf(__c) ? 1 : 0, __c);
     49             __d = copysignl(isinf(__d) ? 1 : 0, __d);
     50             if (isnan(__a))
     51                 __a = copysignl(0, __a);
     52             if (isnan(__b))
     53                 __b = copysignl(0, __b);
     54             __recalc = 1;
     55         }
     56         if (!__recalc && (isinf(__ac) || isinf(__bd) ||
     57                           isinf(__ad) || isinf(__bc)))
     58         {
     59             if (isnan(__a))
     60                 __a = copysignl(0, __a);
     61             if (isnan(__b))
     62                 __b = copysignl(0, __b);
     63             if (isnan(__c))
     64                 __c = copysignl(0, __c);
     65             if (isnan(__d))
     66                 __d = copysignl(0, __d);
     67             __recalc = 1;
     68         }
     69         if (__recalc)
     70         {
     71             __real__ z = INFINITY * (__a * __c - __b * __d);
     72             __imag__ z = INFINITY * (__a * __d + __b * __c);
     73         }
     74     }
     75     return z;
     76 }
     77 
     78 #endif
     79