// // Copyright (c) 2017 The Khronos Group Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef _COMPAT_H_ #define _COMPAT_H_ #if defined(_WIN32) && defined(_MSC_VER) #include #endif #ifdef __cplusplus #define EXTERN_C extern "C" #else #define EXTERN_C #endif // // stdlib.h // #include // On Windows, _MAX_PATH defined there. // llabs appeared in MS C v16 (VS 10/2010). #if defined(_MSC_VER) && _MSC_VER <= 1500 EXTERN_C inline long long llabs(long long __x) { return __x >= 0 ? __x : -__x; } #endif // // stdbool.h // // stdbool.h appeared in MS C v18 (VS 12/2013). #if defined(_MSC_VER) && MSC_VER <= 1700 #if !defined(__cplusplus) typedef char bool; #define true 1 #define false 0 #endif #else #include #endif // defined(_MSC_VER) && MSC_VER <= 1700 // // stdint.h // // stdint.h appeared in MS C v16 (VS 10/2010) and Intel C v12. #if defined(_MSC_VER) \ && (!defined(__INTEL_COMPILER) && _MSC_VER <= 1500 \ || defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1200) typedef unsigned char uint8_t; typedef char int8_t; typedef unsigned short uint16_t; typedef short int16_t; typedef unsigned int uint32_t; typedef int int32_t; typedef unsigned long long uint64_t; typedef long long int64_t; #else #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS #endif #include #endif // // float.h // #include // // fenv.h // // fenv.h appeared in MS C v18 (VS 12/2013). #if defined(_MSC_VER) && _MSC_VER <= 1700 && !defined(__INTEL_COMPILER) // reimplement fenv.h because windows doesn't have it #define FE_INEXACT 0x0020 #define FE_UNDERFLOW 0x0010 #define FE_OVERFLOW 0x0008 #define FE_DIVBYZERO 0x0004 #define FE_INVALID 0x0001 #define FE_ALL_EXCEPT 0x003D int fetestexcept(int excepts); int feclearexcept(int excepts); #else #include #endif // // math.h // #if defined(__INTEL_COMPILER) #include #else #include #endif #ifndef M_PI #define M_PI 3.14159265358979323846264338327950288 #endif #if defined(_MSC_VER) #ifdef __cplusplus extern "C" { #endif #ifndef NAN #define NAN (INFINITY - INFINITY) #endif #ifndef HUGE_VALF #define HUGE_VALF (float)HUGE_VAL #endif #ifndef INFINITY #define INFINITY (FLT_MAX + FLT_MAX) #endif #ifndef isfinite #define isfinite(x) _finite(x) #endif #ifndef isnan #define isnan(x) ((x) != (x)) #endif #ifndef isinf #define isinf(_x) ((_x) == INFINITY || (_x) == -INFINITY) #endif #if _MSC_VER < 1900 && !defined(__INTEL_COMPILER) double rint(double x); float rintf(float x); long double rintl(long double x); float cbrtf(float); double cbrt(double); int ilogb(double x); int ilogbf(float x); int ilogbl(long double x); double fmax(double x, double y); double fmin(double x, double y); float fmaxf(float x, float y); float fminf(float x, float y); double log2(double x); long double log2l(long double x); double exp2(double x); long double exp2l(long double x); double fdim(double x, double y); float fdimf(float x, float y); long double fdiml(long double x, long double y); double remquo(double x, double y, int* quo); float remquof(float x, float y, int* quo); long double remquol(long double x, long double y, int* quo); long double scalblnl(long double x, long n); float hypotf(float x, float y); long double hypotl(long double x, long double y); double lgamma(double x); float lgammaf(float x); double trunc(double x); float truncf(float x); double log1p(double x); float log1pf(float x); long double log1pl(long double x); double copysign(double x, double y); float copysignf(float x, float y); long double copysignl(long double x, long double y); long lround(double x); long lroundf(float x); // long lroundl(long double x) double round(double x); float roundf(float x); long double roundl(long double x); int cf_signbit(double x); int cf_signbitf(float x); // Added in _MSC_VER == 1800 (Visual Studio 2013) #if _MSC_VER < 1800 static int signbit(double x) { return cf_signbit(x); } #endif static int signbitf(float x) { return cf_signbitf(x); } long int lrint(double flt); long int lrintf(float flt); float int2float(int32_t ix); int32_t float2int(float fx); #endif // _MSC_VER < 1900 && ! defined( __INTEL_COMPILER ) #if _MSC_VER < 1900 && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER < 1300) // These functions appeared in Intel C v13 and Visual Studio 2015 float nanf(const char* str); double nan(const char* str); long double nanl(const char* str); #endif #ifdef __cplusplus } #endif #endif // defined(_MSC_VER) #if defined(__ANDROID__) #define log2(X) (log(X) / log(2)) #endif // // stdio.h // #if defined(_MSC_VER) // snprintf added in _MSC_VER == 1900 (Visual Studio 2015) #if _MSC_VER < 1900 #define snprintf sprintf_s #endif #endif // defined(_MSC_VER) // // string.h // #if defined(_MSC_VER) #define strtok_r strtok_s #endif // // unistd.h // #if defined(_MSC_VER) EXTERN_C unsigned int sleep(unsigned int sec); EXTERN_C int usleep(int usec); #endif // // syscall.h // #if defined(__ANDROID__) // Android bionic's isn't providing SYS_sysctl wrappers. #define SYS__sysctl __NR__sysctl #endif // Some tests use _malloca which defined in malloc.h. #if !defined(__APPLE__) #include #endif // // ??? // #if defined(_MSC_VER) #define MAXPATHLEN _MAX_PATH EXTERN_C uint64_t ReadTime(void); EXTERN_C double SubtractTime(uint64_t endTime, uint64_t startTime); /** Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined. */ EXTERN_C int __builtin_clz(unsigned int pattern); #endif #ifndef MIN #define MIN(x, y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x, y) (((x) > (y)) ? (x) : (y)) #endif /*----------------------------------------------------------------------------- WARNING: DO NOT USE THESE MACROS: MAKE_HEX_FLOAT, MAKE_HEX_DOUBLE, MAKE_HEX_LONG. This is a typical usage of the macros: double yhi = MAKE_HEX_DOUBLE(0x1.5555555555555p-2,0x15555555555555LL,-2); (taken from math_brute_force/reference_math.c). There are two problems: 1. There is an error here. On Windows in will produce incorrect result `0x1.5555555555555p+50'. To have a correct result it should be written as: MAKE_HEX_DOUBLE(0x1.5555555555555p-2, 0x15555555555555LL, -54) A proper value of the third argument is not obvious -- sometimes it should be the same as exponent of the first argument, but sometimes not. 2. Information is duplicated. It is easy to make a mistake. Use HEX_FLT, HEX_DBL, HEX_LDBL macros instead (see them in the bottom of the file). -----------------------------------------------------------------------------*/ #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #define MAKE_HEX_FLOAT(x, y, z) ((float)ldexp((float)(y), z)) #define MAKE_HEX_DOUBLE(x, y, z) ldexp((double)(y), z) #define MAKE_HEX_LONG(x, y, z) ((long double)ldexp((long double)(y), z)) #else // Do not use these macros in new code, use HEX_FLT, HEX_DBL, HEX_LDBL instead. #define MAKE_HEX_FLOAT(x, y, z) x #define MAKE_HEX_DOUBLE(x, y, z) x #define MAKE_HEX_LONG(x, y, z) x #endif /*----------------------------------------------------------------------------- HEX_FLT, HEXT_DBL, HEX_LDBL -- Create hex floating point literal of type float, double, long double respectively. Arguments: sm -- sign of number, int -- integer part of mantissa (without `0x' prefix), fract -- fractional part of mantissa (without decimal point and `L' or `LL' suffixes), se -- sign of exponent, exp -- absolute value of (binary) exponent. Example: double yhi = HEX_DBL(+, 1, 5555555555555, -, 2); // 0x1.5555555555555p-2 Note: We have to pass signs as separate arguments because gcc pass negative integer values (e. g. `-2') into a macro as two separate tokens, so `HEX_FLT(1, 0, -2)' produces result `0x1.0p- 2' (note a space between minus and two) which is not a correct floating point literal. -----------------------------------------------------------------------------*/ #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // If compiler does not support hex floating point literals: #define HEX_FLT(sm, int, fract, se, exp) \ sm ldexpf((float)(0x##int##fract##UL), \ se exp + ilogbf((float)0x##int) \ - ilogbf((float)(0x##int##fract##UL))) #define HEX_DBL(sm, int, fract, se, exp) \ sm ldexp((double)(0x##int##fract##ULL), \ se exp + ilogb((double)0x##int) \ - ilogb((double)(0x##int##fract##ULL))) #define HEX_LDBL(sm, int, fract, se, exp) \ sm ldexpl((long double)(0x##int##fract##ULL), \ se exp + ilogbl((long double)0x##int) \ - ilogbl((long double)(0x##int##fract##ULL))) #else // If compiler supports hex floating point literals: just concatenate all the // parts into a literal. #define HEX_FLT(sm, int, fract, se, exp) sm 0x##int##.##fract##p##se##exp##F #define HEX_DBL(sm, int, fract, se, exp) sm 0x##int##.##fract##p##se##exp #define HEX_LDBL(sm, int, fract, se, exp) sm 0x##int##.##fract##p##se##exp##L #endif #if defined(__MINGW32__) #include #define sleep(sec) Sleep((sec)*1000) #endif #endif // _COMPAT_H_