diff options
Diffstat (limited to 'prelude/slang-cpp-scalar-intrinsics.h')
| -rw-r--r-- | prelude/slang-cpp-scalar-intrinsics.h | 186 |
1 files changed, 151 insertions, 35 deletions
diff --git a/prelude/slang-cpp-scalar-intrinsics.h b/prelude/slang-cpp-scalar-intrinsics.h index 7ee62dbc6..60f1dd278 100644 --- a/prelude/slang-cpp-scalar-intrinsics.h +++ b/prelude/slang-cpp-scalar-intrinsics.h @@ -1,8 +1,8 @@ #ifndef SLANG_PRELUDE_SCALAR_INTRINSICS_H #define SLANG_PRELUDE_SCALAR_INTRINSICS_H -#if SLANG_PROCESSOR_X86_64 && SLANG_VC -// If we have visual studio and 64 bit processor, we can assume we have popcnt, and can include x86 intrinsics +#if !defined(SLANG_LLVM) && SLANG_PROCESSOR_X86_64 && SLANG_VC +// If we have visual studio and 64 bit processor, we can assume we have popcnt, and can include x86 intrinsics # include <intrin.h> #endif @@ -35,15 +35,55 @@ union Union64 }; // Helpers -SLANG_FORCE_INLINE float F32_calcSafeRadians(float radians) -{ - // Put 0 to 2pi cycles to cycle around 0 to 1 - float a = radians * (1.0f / float(SLANG_PRELUDE_PI * 2)); - // Get truncated fraction, as value in 0 - 1 range - a = a - ::floorf(a); - // Convert back to 0 - 2pi range - return (a * float(SLANG_PRELUDE_PI * 2)); -} +SLANG_FORCE_INLINE float F32_calcSafeRadians(float radians); + +#ifdef SLANG_LLVM + +SLANG_PRELUDE_EXTERN_C_START + +// Unary +float F32_ceil(float f); +float F32_floor(float f); +float F32_round(float f); +float F32_sin(float f); +float F32_cos(float f); +float F32_tan(float f); +float F32_asin(float f); +float F32_acos(float f); +float F32_atan(float f); +float F32_sinh(float f); +float F32_cosh(float f); +float F32_tanh(float f); +float F32_log2(float f); +float F32_log(float f); +float F32_log10(float f); +float F32_exp2(float f); +float F32_exp(float f); +float F32_abs(float f); +float F32_trunc(float f); +float F32_sqrt(float f); + +bool F32_isnan(float f); +bool F32_isfinite(float f); +bool F32_isinf(float f); + +// Binary +SLANG_FORCE_INLINE float F32_min(float a, float b) { return a < b ? a : b; } +SLANG_FORCE_INLINE float F32_max(float a, float b) { return a > b ? a : b; } +float F32_pow(float a, float b); +float F32_fmod(float a, float b); +float F32_remainder(float a, float b); +float F32_atan2(float a, float b); + +float F32_frexp(float x, float* e); +float F32_modf(float x, float* ip); + +// Ternary +SLANG_FORCE_INLINE float F32_fma(float a, float b, float c) { return a * b + c; } + +SLANG_PRELUDE_EXTERN_C_END + +#else // Unary SLANG_FORCE_INLINE float F32_ceil(float f) { return ::ceilf(f); } @@ -66,9 +106,6 @@ SLANG_FORCE_INLINE float F32_exp(float f) { return ::expf(f); } SLANG_FORCE_INLINE float F32_abs(float f) { return ::fabsf(f); } SLANG_FORCE_INLINE float F32_trunc(float f) { return ::truncf(f); } SLANG_FORCE_INLINE float F32_sqrt(float f) { return ::sqrtf(f); } -SLANG_FORCE_INLINE float F32_rsqrt(float f) { return 1.0f / F32_sqrt(f); } -SLANG_FORCE_INLINE float F32_sign(float f) { return ( f == 0.0f) ? f : (( f < 0.0f) ? -1.0f : 1.0f); } -SLANG_FORCE_INLINE float F32_frac(float f) { return f - F32_floor(f); } SLANG_FORCE_INLINE bool F32_isnan(float f) { return SLANG_PRELUDE_STD isnan(f); } SLANG_FORCE_INLINE bool F32_isfinite(float f) { return SLANG_PRELUDE_STD isfinite(f); } @@ -94,24 +131,81 @@ SLANG_FORCE_INLINE float F32_modf(float x, float* ip) return ::modff(x, ip); } -SLANG_FORCE_INLINE uint32_t F32_asuint(float f) { Union32 u; u.f = f; return u.u; } -SLANG_FORCE_INLINE int32_t F32_asint(float f) { Union32 u; u.f = f; return u.i; } - // Ternary SLANG_FORCE_INLINE float F32_fma(float a, float b, float c) { return ::fmaf(a, b, c); } -// ----------------------------- F64 ----------------------------------------- +#endif -SLANG_FORCE_INLINE double F64_calcSafeRadians(double radians) +SLANG_FORCE_INLINE float F32_calcSafeRadians(float radians) { // Put 0 to 2pi cycles to cycle around 0 to 1 - double a = radians * (1.0f / (SLANG_PRELUDE_PI * 2)); + float a = radians * (1.0f / float(SLANG_PRELUDE_PI * 2)); // Get truncated fraction, as value in 0 - 1 range - a = a - ::floor(a); + a = a - F32_floor(a); // Convert back to 0 - 2pi range - return (a * (SLANG_PRELUDE_PI * 2)); + return (a * float(SLANG_PRELUDE_PI * 2)); } +SLANG_FORCE_INLINE float F32_rsqrt(float f) { return 1.0f / F32_sqrt(f); } +SLANG_FORCE_INLINE float F32_sign(float f) { return ( f == 0.0f) ? f : (( f < 0.0f) ? -1.0f : 1.0f); } +SLANG_FORCE_INLINE float F32_frac(float f) { return f - F32_floor(f); } + +SLANG_FORCE_INLINE uint32_t F32_asuint(float f) { Union32 u; u.f = f; return u.u; } +SLANG_FORCE_INLINE int32_t F32_asint(float f) { Union32 u; u.f = f; return u.i; } + +// ----------------------------- F64 ----------------------------------------- + +SLANG_FORCE_INLINE double F64_calcSafeRadians(double radians); + +#ifdef SLANG_LLVM + +SLANG_PRELUDE_EXTERN_C_START + +// Unary +double F64_ceil(double f); +double F64_floor(double f); +double F64_round(double f); +double F64_sin(double f); +double F64_cos(double f); +double F64_tan(double f); +double F64_asin(double f); +double F64_acos(double f); +double F64_atan(double f); +double F64_sinh(double f); +double F64_cosh(double f); +double F64_tanh(double f); +double F64_log2(double f); +double F64_log(double f); +double F64_log10(float f); +double F64_exp2(double f); +double F64_exp(double f); +double F64_abs(double f); +double F64_trunc(double f); +double F64_sqrt(double f); + +bool F64_isnan(double f); +bool F64_isfinite(double f); +bool F64_isinf(double f); + +// Binary +SLANG_FORCE_INLINE double F64_min(double a, double b) { return a < b ? a : b; } +SLANG_FORCE_INLINE double F64_max(double a, double b) { return a > b ? a : b; } +double F64_pow(double a, double b); +double F64_fmod(double a, double b); +double F64_remainder(double a, double b); +double F64_atan2(double a, double b); + +double F64_frexp(double x, double* e); + +double F64_modf(double x, double* ip); + +// Ternary +SLANG_FORCE_INLINE double F64_fma(double a, double b, double c) { return a * b + c; } + +SLANG_PRELUDE_EXTERN_C_END + +#else // SLANG_LLVM + // Unary SLANG_FORCE_INLINE double F64_ceil(double f) { return ::ceil(f); } SLANG_FORCE_INLINE double F64_floor(double f) { return ::floor(f); } @@ -133,9 +227,7 @@ SLANG_FORCE_INLINE double F64_exp(double f) { return ::exp(f); } SLANG_FORCE_INLINE double F64_abs(double f) { return ::fabs(f); } SLANG_FORCE_INLINE double F64_trunc(double f) { return ::trunc(f); } SLANG_FORCE_INLINE double F64_sqrt(double f) { return ::sqrt(f); } -SLANG_FORCE_INLINE double F64_rsqrt(double f) { return 1.0 / F64_sqrt(f); } -SLANG_FORCE_INLINE double F64_sign(double f) { return (f == 0.0) ? f : ((f < 0.0) ? -1.0 : 1.0); } -SLANG_FORCE_INLINE double F64_frac(double f) { return f - F64_floor(f); } + SLANG_FORCE_INLINE bool F64_isnan(double f) { return SLANG_PRELUDE_STD isnan(f); } SLANG_FORCE_INLINE bool F64_isfinite(double f) { return SLANG_PRELUDE_STD isfinite(f); } @@ -162,6 +254,15 @@ SLANG_FORCE_INLINE double F64_modf(double x, double* ip) return ::modf(x, ip); } +// Ternary +SLANG_FORCE_INLINE double F64_fma(double a, double b, double c) { return ::fma(a, b, c); } + +#endif // SLANG_LLVM + +SLANG_FORCE_INLINE double F64_rsqrt(double f) { return 1.0 / F64_sqrt(f); } +SLANG_FORCE_INLINE double F64_sign(double f) { return (f == 0.0) ? f : ((f < 0.0) ? -1.0 : 1.0); } +SLANG_FORCE_INLINE double F64_frac(double f) { return f - F64_floor(f); } + SLANG_FORCE_INLINE void F64_asuint(double d, uint32_t* low, uint32_t* hi) { Union64 u; @@ -178,8 +279,15 @@ SLANG_FORCE_INLINE void F64_asint(double d, int32_t* low, int32_t* hi) *hi = int32_t(u.u >> 32); } -// Ternary -SLANG_FORCE_INLINE double F64_fma(double a, double b, double c) { return ::fma(a, b, c); } +SLANG_FORCE_INLINE double F64_calcSafeRadians(double radians) +{ + // Put 0 to 2pi cycles to cycle around 0 to 1 + double a = radians * (1.0f / (SLANG_PRELUDE_PI * 2)); + // Get truncated fraction, as value in 0 - 1 range + a = a - F64_floor(a); + // Convert back to 0 - 2pi range + return (a * (SLANG_PRELUDE_PI * 2)); +} // ----------------------------- I32 ----------------------------------------- @@ -217,7 +325,7 @@ SLANG_FORCE_INLINE double U32_asdouble(uint32_t low, uint32_t hi) SLANG_FORCE_INLINE uint32_t U32_countbits(uint32_t v) { -#if SLANG_GCC_FAMILY +#if SLANG_GCC_FAMILY && !defined(SLANG_LLVM) return __builtin_popcount(v); #elif SLANG_PROCESSOR_X86_64 && SLANG_VC return __popcnt(v); @@ -244,7 +352,7 @@ SLANG_FORCE_INLINE uint64_t U64_max(uint64_t a, uint64_t b) { return a > b ? a : // 32 bits can always hold the result, and will be implicitly promoted. SLANG_FORCE_INLINE uint32_t U64_countbits(uint64_t v) { -#if SLANG_GCC_FAMILY +#if SLANG_GCC_FAMILY && !defined(SLANG_LLVM) return uint32_t(__builtin_popcountl(v)); #elif SLANG_PROCESSOR_X86_64 && SLANG_VC return uint32_t(__popcnt64(v)); @@ -268,18 +376,26 @@ SLANG_FORCE_INLINE int64_t I64_max(int64_t a, int64_t b) { return a > b ? a : b; // ----------------------------- Interlocked --------------------------------- -#ifdef _WIN32 -#include <intrin.h> -#endif + +#if SLANG_LLVM + +#else // SLANG_LLVM + +# ifdef _WIN32 +# include <intrin.h> +# endif void InterlockedAdd(uint32_t* dest, uint32_t value, uint32_t* oldValue) { -#ifdef _WIN32 +# ifdef _WIN32 *oldValue = _InterlockedExchangeAdd((long*)dest, (long)value); -#else +# else *oldValue = __sync_fetch_and_add(dest, value); -#endif +# endif } + +#endif // SLANG_LLVM + #ifdef SLANG_PRELUDE_NAMESPACE } #endif |
