Home | History | Annotate | Download | only in lib
      1 /* ===-- mulsc3.c - Implement __mulsc3 -------------------------------------===
      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 __mulsc3 for the compiler_rt library.
     11  *
     12  * ===----------------------------------------------------------------------===
     13  */
     14 
     15 #include "int_lib.h"
     16 #include <math.h>
     17 #include <complex.h>
     18 
     19 /* Returns: the product of a + ib and c + id */
     20 
     21 float _Complex
     22 __mulsc3(float __a, float __b, float __c, float __d)
     23 {
     24     float __ac = __a * __c;
     25     float __bd = __b * __d;
     26     float __ad = __a * __d;
     27     float __bc = __b * __c;
     28     float _Complex z;
     29     __real__ z = __ac - __bd;
     30     __imag__ z = __ad + __bc;
     31     if (isnan(__real__ z) && isnan(__imag__ z))
     32     {
     33         int __recalc = 0;
     34         if (isinf(__a) || isinf(__b))
     35         {
     36             __a = copysignf(isinf(__a) ? 1 : 0, __a);
     37             __b = copysignf(isinf(__b) ? 1 : 0, __b);
     38             if (isnan(__c))
     39                 __c = copysignf(0, __c);
     40             if (isnan(__d))
     41                 __d = copysignf(0, __d);
     42             __recalc = 1;
     43         }
     44         if (isinf(__c) || isinf(__d))
     45         {
     46             __c = copysignf(isinf(__c) ? 1 : 0, __c);
     47             __d = copysignf(isinf(__d) ? 1 : 0, __d);
     48             if (isnan(__a))
     49                 __a = copysignf(0, __a);
     50             if (isnan(__b))
     51                 __b = copysignf(0, __b);
     52             __recalc = 1;
     53         }
     54         if (!__recalc && (isinf(__ac) || isinf(__bd) ||
     55                           isinf(__ad) || isinf(__bc)))
     56         {
     57             if (isnan(__a))
     58                 __a = copysignf(0, __a);
     59             if (isnan(__b))
     60                 __b = copysignf(0, __b);
     61             if (isnan(__c))
     62                 __c = copysignf(0, __c);
     63             if (isnan(__d))
     64                 __d = copysignf(0, __d);
     65             __recalc = 1;
     66         }
     67         if (__recalc)
     68         {
     69             __real__ z = INFINITY * (__a * __c - __b * __d);
     70             __imag__ z = INFINITY * (__a * __d + __b * __c);
     71         }
     72     }
     73     return z;
     74 }
     75