builtins: emulate _Complex for cl

cl does not support C99 completely as of VS2015.  Emulate _Complex to allow
building with MSVC.

Patch by Tee Hao Wei!

llvm-svn: 249514
This commit is contained in:
Saleem Abdulrasool 2015-10-07 02:58:07 +00:00
parent 71c47e5a86
commit b0b7c8a8dd
7 changed files with 71 additions and 54 deletions

View File

@ -17,7 +17,7 @@
/* Returns: the quotient of (a + ib) / (c + id) */ /* Returns: the quotient of (a + ib) / (c + id) */
COMPILER_RT_ABI double _Complex COMPILER_RT_ABI Dcomplex
__divdc3(double __a, double __b, double __c, double __d) __divdc3(double __a, double __b, double __c, double __d)
{ {
int __ilogbw = 0; int __ilogbw = 0;
@ -29,31 +29,31 @@ __divdc3(double __a, double __b, double __c, double __d)
__d = crt_scalbn(__d, -__ilogbw); __d = crt_scalbn(__d, -__ilogbw);
} }
double __denom = __c * __c + __d * __d; double __denom = __c * __c + __d * __d;
double _Complex z; Dcomplex z;
__real__ z = crt_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); COMPLEX_REAL(z) = crt_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
__imag__ z = crt_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); COMPLEX_IMAGINARY(z) = crt_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
{ {
if ((__denom == 0.0) && (!crt_isnan(__a) || !crt_isnan(__b))) if ((__denom == 0.0) && (!crt_isnan(__a) || !crt_isnan(__b)))
{ {
__real__ z = crt_copysign(CRT_INFINITY, __c) * __a; COMPLEX_REAL(z) = crt_copysign(CRT_INFINITY, __c) * __a;
__imag__ z = crt_copysign(CRT_INFINITY, __c) * __b; COMPLEX_IMAGINARY(z) = crt_copysign(CRT_INFINITY, __c) * __b;
} }
else if ((crt_isinf(__a) || crt_isinf(__b)) && else if ((crt_isinf(__a) || crt_isinf(__b)) &&
crt_isfinite(__c) && crt_isfinite(__d)) crt_isfinite(__c) && crt_isfinite(__d))
{ {
__a = crt_copysign(crt_isinf(__a) ? 1.0 : 0.0, __a); __a = crt_copysign(crt_isinf(__a) ? 1.0 : 0.0, __a);
__b = crt_copysign(crt_isinf(__b) ? 1.0 : 0.0, __b); __b = crt_copysign(crt_isinf(__b) ? 1.0 : 0.0, __b);
__real__ z = CRT_INFINITY * (__a * __c + __b * __d); COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
__imag__ z = CRT_INFINITY * (__b * __c - __a * __d); COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
} }
else if (crt_isinf(__logbw) && __logbw > 0.0 && else if (crt_isinf(__logbw) && __logbw > 0.0 &&
crt_isfinite(__a) && crt_isfinite(__b)) crt_isfinite(__a) && crt_isfinite(__b))
{ {
__c = crt_copysign(crt_isinf(__c) ? 1.0 : 0.0, __c); __c = crt_copysign(crt_isinf(__c) ? 1.0 : 0.0, __c);
__d = crt_copysign(crt_isinf(__d) ? 1.0 : 0.0, __d); __d = crt_copysign(crt_isinf(__d) ? 1.0 : 0.0, __d);
__real__ z = 0.0 * (__a * __c + __b * __d); COMPLEX_REAL(z) = 0.0 * (__a * __c + __b * __d);
__imag__ z = 0.0 * (__b * __c - __a * __d); COMPLEX_IMAGINARY(z) = 0.0 * (__b * __c - __a * __d);
} }
} }
return z; return z;

View File

@ -17,7 +17,7 @@
/* Returns: the quotient of (a + ib) / (c + id) */ /* Returns: the quotient of (a + ib) / (c + id) */
COMPILER_RT_ABI float _Complex COMPILER_RT_ABI Fcomplex
__divsc3(float __a, float __b, float __c, float __d) __divsc3(float __a, float __b, float __c, float __d)
{ {
int __ilogbw = 0; int __ilogbw = 0;
@ -29,31 +29,31 @@ __divsc3(float __a, float __b, float __c, float __d)
__d = crt_scalbnf(__d, -__ilogbw); __d = crt_scalbnf(__d, -__ilogbw);
} }
float __denom = __c * __c + __d * __d; float __denom = __c * __c + __d * __d;
float _Complex z; Fcomplex z;
__real__ z = crt_scalbnf((__a * __c + __b * __d) / __denom, -__ilogbw); COMPLEX_REAL(z) = crt_scalbnf((__a * __c + __b * __d) / __denom, -__ilogbw);
__imag__ z = crt_scalbnf((__b * __c - __a * __d) / __denom, -__ilogbw); COMPLEX_IMAGINARY(z) = crt_scalbnf((__b * __c - __a * __d) / __denom, -__ilogbw);
if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
{ {
if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b))) if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b)))
{ {
__real__ z = crt_copysignf(CRT_INFINITY, __c) * __a; COMPLEX_REAL(z) = crt_copysignf(CRT_INFINITY, __c) * __a;
__imag__ z = crt_copysignf(CRT_INFINITY, __c) * __b; COMPLEX_IMAGINARY(z) = crt_copysignf(CRT_INFINITY, __c) * __b;
} }
else if ((crt_isinf(__a) || crt_isinf(__b)) && else if ((crt_isinf(__a) || crt_isinf(__b)) &&
crt_isfinite(__c) && crt_isfinite(__d)) crt_isfinite(__c) && crt_isfinite(__d))
{ {
__a = crt_copysignf(crt_isinf(__a) ? 1 : 0, __a); __a = crt_copysignf(crt_isinf(__a) ? 1 : 0, __a);
__b = crt_copysignf(crt_isinf(__b) ? 1 : 0, __b); __b = crt_copysignf(crt_isinf(__b) ? 1 : 0, __b);
__real__ z = CRT_INFINITY * (__a * __c + __b * __d); COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
__imag__ z = CRT_INFINITY * (__b * __c - __a * __d); COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
} }
else if (crt_isinf(__logbw) && __logbw > 0 && else if (crt_isinf(__logbw) && __logbw > 0 &&
crt_isfinite(__a) && crt_isfinite(__b)) crt_isfinite(__a) && crt_isfinite(__b))
{ {
__c = crt_copysignf(crt_isinf(__c) ? 1 : 0, __c); __c = crt_copysignf(crt_isinf(__c) ? 1 : 0, __c);
__d = crt_copysignf(crt_isinf(__d) ? 1 : 0, __d); __d = crt_copysignf(crt_isinf(__d) ? 1 : 0, __d);
__real__ z = 0 * (__a * __c + __b * __d); COMPLEX_REAL(z) = 0 * (__a * __c + __b * __d);
__imag__ z = 0 * (__b * __c - __a * __d); COMPLEX_IMAGINARY(z) = 0 * (__b * __c - __a * __d);
} }
} }
return z; return z;

View File

@ -18,7 +18,7 @@
/* Returns: the quotient of (a + ib) / (c + id) */ /* Returns: the quotient of (a + ib) / (c + id) */
COMPILER_RT_ABI long double _Complex COMPILER_RT_ABI Lcomplex
__divxc3(long double __a, long double __b, long double __c, long double __d) __divxc3(long double __a, long double __b, long double __c, long double __d)
{ {
int __ilogbw = 0; int __ilogbw = 0;
@ -30,31 +30,31 @@ __divxc3(long double __a, long double __b, long double __c, long double __d)
__d = crt_scalbnl(__d, -__ilogbw); __d = crt_scalbnl(__d, -__ilogbw);
} }
long double __denom = __c * __c + __d * __d; long double __denom = __c * __c + __d * __d;
long double _Complex z; Lcomplex z;
__real__ z = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw); COMPLEX_REAL(z) = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);
__imag__ z = crt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw); COMPLEX_IMAGINARY(z) = crt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw);
if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
{ {
if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b))) if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b)))
{ {
__real__ z = crt_copysignl(CRT_INFINITY, __c) * __a; COMPLEX_REAL(z) = crt_copysignl(CRT_INFINITY, __c) * __a;
__imag__ z = crt_copysignl(CRT_INFINITY, __c) * __b; COMPLEX_IMAGINARY(z) = crt_copysignl(CRT_INFINITY, __c) * __b;
} }
else if ((crt_isinf(__a) || crt_isinf(__b)) && else if ((crt_isinf(__a) || crt_isinf(__b)) &&
crt_isfinite(__c) && crt_isfinite(__d)) crt_isfinite(__c) && crt_isfinite(__d))
{ {
__a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a); __a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a);
__b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b); __b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b);
__real__ z = CRT_INFINITY * (__a * __c + __b * __d); COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
__imag__ z = CRT_INFINITY * (__b * __c - __a * __d); COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
} }
else if (crt_isinf(__logbw) && __logbw > 0 && else if (crt_isinf(__logbw) && __logbw > 0 &&
crt_isfinite(__a) && crt_isfinite(__b)) crt_isfinite(__a) && crt_isfinite(__b))
{ {
__c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c); __c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c);
__d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d); __d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d);
__real__ z = 0 * (__a * __c + __b * __d); COMPLEX_REAL(z) = 0 * (__a * __c + __b * __d);
__imag__ z = 0 * (__b * __c - __a * __d); COMPLEX_IMAGINARY(z) = 0 * (__b * __c - __a * __d);
} }
} }
return z; return z;

View File

@ -140,5 +140,22 @@ typedef union
long double f; long double f;
} long_double_bits; } long_double_bits;
#if __STDC_VERSION__ >= 199901L
typedef float _Complex Fcomplex;
typedef double _Complex Dcomplex;
typedef long double _Complex Lcomplex;
#define COMPLEX_REAL(x) __real__(x)
#define COMPLEX_IMAGINARY(x) __imag__(x)
#else
typedef struct { float real, imaginary; } Fcomplex;
typedef struct { double real, imaginary; } Dcomplex;
typedef struct { long double real, imaginary; } Lcomplex;
#define COMPLEX_REAL(x) (x).real
#define COMPLEX_IMAGINARY(x) (x).imaginary
#endif
#endif /* INT_TYPES_H */ #endif /* INT_TYPES_H */

View File

@ -17,17 +17,17 @@
/* Returns: the product of a + ib and c + id */ /* Returns: the product of a + ib and c + id */
COMPILER_RT_ABI double _Complex COMPILER_RT_ABI Dcomplex
__muldc3(double __a, double __b, double __c, double __d) __muldc3(double __a, double __b, double __c, double __d)
{ {
double __ac = __a * __c; double __ac = __a * __c;
double __bd = __b * __d; double __bd = __b * __d;
double __ad = __a * __d; double __ad = __a * __d;
double __bc = __b * __c; double __bc = __b * __c;
double _Complex z; Dcomplex z;
__real__ z = __ac - __bd; COMPLEX_REAL(z) = __ac - __bd;
__imag__ z = __ad + __bc; COMPLEX_IMAGINARY(z) = __ad + __bc;
if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
{ {
int __recalc = 0; int __recalc = 0;
if (crt_isinf(__a) || crt_isinf(__b)) if (crt_isinf(__a) || crt_isinf(__b))
@ -65,8 +65,8 @@ __muldc3(double __a, double __b, double __c, double __d)
} }
if (__recalc) if (__recalc)
{ {
__real__ z = CRT_INFINITY * (__a * __c - __b * __d); COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d);
__imag__ z = CRT_INFINITY * (__a * __d + __b * __c); COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c);
} }
} }
return z; return z;

View File

@ -17,17 +17,17 @@
/* Returns: the product of a + ib and c + id */ /* Returns: the product of a + ib and c + id */
COMPILER_RT_ABI float _Complex COMPILER_RT_ABI Fcomplex
__mulsc3(float __a, float __b, float __c, float __d) __mulsc3(float __a, float __b, float __c, float __d)
{ {
float __ac = __a * __c; float __ac = __a * __c;
float __bd = __b * __d; float __bd = __b * __d;
float __ad = __a * __d; float __ad = __a * __d;
float __bc = __b * __c; float __bc = __b * __c;
float _Complex z; Fcomplex z;
__real__ z = __ac - __bd; COMPLEX_REAL(z) = __ac - __bd;
__imag__ z = __ad + __bc; COMPLEX_IMAGINARY(z) = __ad + __bc;
if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
{ {
int __recalc = 0; int __recalc = 0;
if (crt_isinf(__a) || crt_isinf(__b)) if (crt_isinf(__a) || crt_isinf(__b))
@ -65,8 +65,8 @@ __mulsc3(float __a, float __b, float __c, float __d)
} }
if (__recalc) if (__recalc)
{ {
__real__ z = CRT_INFINITY * (__a * __c - __b * __d); COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d);
__imag__ z = CRT_INFINITY * (__a * __d + __b * __c); COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c);
} }
} }
return z; return z;

View File

@ -19,17 +19,17 @@
/* Returns: the product of a + ib and c + id */ /* Returns: the product of a + ib and c + id */
COMPILER_RT_ABI long double _Complex COMPILER_RT_ABI Lcomplex
__mulxc3(long double __a, long double __b, long double __c, long double __d) __mulxc3(long double __a, long double __b, long double __c, long double __d)
{ {
long double __ac = __a * __c; long double __ac = __a * __c;
long double __bd = __b * __d; long double __bd = __b * __d;
long double __ad = __a * __d; long double __ad = __a * __d;
long double __bc = __b * __c; long double __bc = __b * __c;
long double _Complex z; Lcomplex z;
__real__ z = __ac - __bd; COMPLEX_REAL(z) = __ac - __bd;
__imag__ z = __ad + __bc; COMPLEX_IMAGINARY(z) = __ad + __bc;
if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
{ {
int __recalc = 0; int __recalc = 0;
if (crt_isinf(__a) || crt_isinf(__b)) if (crt_isinf(__a) || crt_isinf(__b))
@ -67,8 +67,8 @@ __mulxc3(long double __a, long double __b, long double __c, long double __d)
} }
if (__recalc) if (__recalc)
{ {
__real__ z = CRT_INFINITY * (__a * __c - __b * __d); COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d);
__imag__ z = CRT_INFINITY * (__a * __d + __b * __c); COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c);
} }
} }
return z; return z;