1 // 2 // Copyright (c) 2017 The Khronos Group Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 #ifndef _COMPAT_H_ 17 #define _COMPAT_H_ 18 19 #if defined(_WIN32) && defined (_MSC_VER) 20 #include <Windows.h> 21 #endif 22 23 #ifdef __cplusplus 24 #define EXTERN_C extern "C" 25 #else 26 #define EXTERN_C 27 #endif 28 29 30 // 31 // stdlib.h 32 // 33 34 #include <stdlib.h> // On Windows, _MAX_PATH defined there. 35 36 // llabs appeared in MS C v16 (VS 10/2010). 37 #if defined( _MSC_VER ) && _MSC_VER <= 1500 llabs(long long __x)38 EXTERN_C inline long long llabs(long long __x) { return __x >= 0 ? __x : -__x; } 39 #endif 40 41 42 // 43 // stdbool.h 44 // 45 46 // stdbool.h appeared in MS C v18 (VS 12/2013). 47 #if defined( _MSC_VER ) && MSC_VER <= 1700 48 #if !defined(__cplusplus) 49 typedef char bool; 50 #define true 1 51 #define false 0 52 #endif 53 #else 54 #include <stdbool.h> 55 #endif 56 57 58 59 // 60 // stdint.h 61 // 62 63 // stdint.h appeared in MS C v16 (VS 10/2010) and Intel C v12. 64 #if defined( _MSC_VER ) && ( ! defined( __INTEL_COMPILER ) && _MSC_VER <= 1500 || defined( __INTEL_COMPILER ) && __INTEL_COMPILER < 1200 ) 65 typedef unsigned char uint8_t; 66 typedef char int8_t; 67 typedef unsigned short uint16_t; 68 typedef short int16_t; 69 typedef unsigned int uint32_t; 70 typedef int int32_t; 71 typedef unsigned long long uint64_t; 72 typedef long long int64_t; 73 #else 74 #ifndef __STDC_LIMIT_MACROS 75 #define __STDC_LIMIT_MACROS 76 #endif 77 #include <stdint.h> 78 #endif 79 80 81 82 // 83 // float.h 84 // 85 86 #include <float.h> 87 88 89 90 // 91 // fenv.h 92 // 93 94 // fenv.h appeared in MS C v18 (VS 12/2013). 95 #if defined( _MSC_VER ) && _MSC_VER <= 1700 && ! defined( __INTEL_COMPILER ) 96 // reimplement fenv.h because windows doesn't have it 97 #define FE_INEXACT 0x0020 98 #define FE_UNDERFLOW 0x0010 99 #define FE_OVERFLOW 0x0008 100 #define FE_DIVBYZERO 0x0004 101 #define FE_INVALID 0x0001 102 #define FE_ALL_EXCEPT 0x003D 103 int fetestexcept(int excepts); 104 int feclearexcept(int excepts); 105 #else 106 #include <fenv.h> 107 #endif 108 109 110 // 111 // math.h 112 // 113 114 #if defined( __INTEL_COMPILER ) 115 #include <mathimf.h> 116 #else 117 #include <math.h> 118 #endif 119 120 #ifndef M_PI 121 #define M_PI 3.14159265358979323846264338327950288 122 #endif 123 124 #if defined( _MSC_VER ) 125 126 #ifdef __cplusplus 127 extern "C" { 128 #endif 129 130 #ifndef NAN 131 #define NAN (INFINITY - INFINITY) 132 #endif 133 134 #ifndef HUGE_VALF 135 #define HUGE_VALF (float)HUGE_VAL 136 #endif 137 138 #ifndef INFINITY 139 #define INFINITY (FLT_MAX + FLT_MAX) 140 #endif 141 142 #ifndef isfinite 143 #define isfinite(x) _finite(x) 144 #endif 145 146 #ifndef isnan 147 #define isnan( x ) ((x) != (x)) 148 #endif 149 150 #ifndef isinf 151 #define isinf( _x) ((_x) == INFINITY || (_x) == -INFINITY) 152 #endif 153 154 #if _MSC_VER < 1900 && ! defined( __INTEL_COMPILER ) 155 156 double rint( double x); 157 float rintf( float x); 158 long double rintl( long double x); 159 160 float cbrtf( float ); 161 double cbrt( double ); 162 163 int ilogb( double x); 164 int ilogbf (float x); 165 int ilogbl(long double x); 166 167 double fmax(double x, double y); 168 double fmin(double x, double y); 169 float fmaxf( float x, float y ); 170 float fminf(float x, float y); 171 172 double log2(double x); 173 long double log2l(long double x); 174 175 double exp2(double x); 176 long double exp2l(long double x); 177 178 double fdim(double x, double y); 179 float fdimf(float x, float y); 180 long double fdiml(long double x, long double y); 181 182 double remquo( double x, double y, int *quo); 183 float remquof( float x, float y, int *quo); 184 long double remquol( long double x, long double y, int *quo); 185 186 long double scalblnl(long double x, long n); 187 188 float hypotf(float x, float y); 189 long double hypotl(long double x, long double y) ; 190 double lgamma(double x); 191 float lgammaf(float x); 192 193 double trunc(double x); 194 float truncf(float x); 195 196 double log1p(double x); 197 float log1pf(float x); 198 long double log1pl(long double x); 199 200 double copysign(double x, double y); 201 float copysignf(float x, float y); 202 long double copysignl(long double x, long double y); 203 204 long lround(double x); 205 long lroundf(float x); 206 //long lroundl(long double x) 207 208 double round(double x); 209 float roundf(float x); 210 long double roundl(long double x); 211 212 int cf_signbit(double x); 213 int cf_signbitf(float x); 214 215 // Added in _MSC_VER == 1800 (Visual Studio 2013) 216 #if _MSC_VER < 1800 signbit(double x)217 static int signbit(double x) { return cf_signbit(x); } 218 #endif signbitf(float x)219 static int signbitf(float x) { return cf_signbitf(x); } 220 221 long int lrint (double flt); 222 long int lrintf (float flt); 223 224 float int2float (int32_t ix); 225 int32_t float2int (float fx); 226 227 #endif // _MSC_VER < 1900 && ! defined( __INTEL_COMPILER ) 228 229 #if _MSC_VER < 1900 && ( ! defined( __INTEL_COMPILER ) || __INTEL_COMPILER < 1300 ) 230 // These functions appeared in Intel C v13 and Visual Studio 2015 231 float nanf( const char* str); 232 double nan( const char* str); 233 long double nanl( const char* str); 234 #endif 235 236 #ifdef __cplusplus 237 } 238 #endif 239 240 #endif 241 242 #if defined( __ANDROID__ ) 243 #define log2(X) (log(X)/log(2)) 244 #endif 245 246 247 248 // 249 // stdio.h 250 // 251 252 #if defined(_MSC_VER) 253 // snprintf added in _MSC_VER == 1900 (Visual Studio 2015) 254 #if _MSC_VER < 1900 255 #define snprintf sprintf_s 256 #endif 257 #endif 258 259 260 261 // 262 // string.h 263 // 264 265 #if defined(_MSC_VER) 266 #define strtok_r strtok_s 267 #endif 268 269 270 271 // 272 // unistd.h 273 // 274 275 #if defined( _MSC_VER ) 276 EXTERN_C unsigned int sleep( unsigned int sec ); 277 EXTERN_C int usleep( int usec ); 278 #endif 279 280 281 282 // 283 // syscall.h 284 // 285 286 #if defined( __ANDROID__ ) 287 // Android bionic's isn't providing SYS_sysctl wrappers. 288 #define SYS__sysctl __NR__sysctl 289 #endif 290 291 292 293 // Some tests use _malloca which defined in malloc.h. 294 #if !defined (__APPLE__) 295 #include <malloc.h> 296 #endif 297 298 299 // 300 // ??? 301 // 302 303 #if defined( _MSC_VER ) 304 305 #define MAXPATHLEN _MAX_PATH 306 307 EXTERN_C uint64_t ReadTime( void ); 308 EXTERN_C double SubtractTime( uint64_t endTime, uint64_t startTime ); 309 310 /** Returns the number of leading 0-bits in x, 311 starting at the most significant bit position. 312 If x is 0, the result is undefined. 313 */ 314 EXTERN_C int __builtin_clz(unsigned int pattern); 315 316 #endif 317 318 #ifndef MIN 319 #define MIN(x,y) (((x)<(y))?(x):(y)) 320 #endif 321 #ifndef MAX 322 #define MAX(x,y) (((x)>(y))?(x):(y)) 323 #endif 324 325 326 /* 327 ------------------------------------------------------------------------------------------------ 328 WARNING: DO NOT USE THESE MACROS: MAKE_HEX_FLOAT, MAKE_HEX_DOUBLE, MAKE_HEX_LONG. 329 330 This is a typical usage of the macros: 331 332 double yhi = MAKE_HEX_DOUBLE(0x1.5555555555555p-2,0x15555555555555LL,-2); 333 334 (taken from math_brute_force/reference_math.c). There are two problems: 335 336 1. There is an error here. On Windows in will produce incorrect result 337 `0x1.5555555555555p+50'. To have a correct result it should be written as 338 `MAKE_HEX_DOUBLE(0x1.5555555555555p-2,0x15555555555555LL,-54)'. A proper value of the 339 third argument is not obvious -- sometimes it should be the same as exponent of the 340 first argument, but sometimes not. 341 342 2. Information is duplicated. It is easy to make a mistake. 343 344 Use HEX_FLT, HEX_DBL, HEX_LDBL macros instead (see them in the bottom of the file). 345 ------------------------------------------------------------------------------------------------ 346 */ 347 #if defined ( _MSC_VER ) && ! defined( __INTEL_COMPILER ) 348 349 #define MAKE_HEX_FLOAT(x,y,z) ((float)ldexp( (float)(y), z)) 350 #define MAKE_HEX_DOUBLE(x,y,z) ldexp( (double)(y), z) 351 #define MAKE_HEX_LONG(x,y,z) ((long double) ldexp( (long double)(y), z)) 352 353 #else 354 355 // Do not use these macros in new code, use HEX_FLT, HEX_DBL, HEX_LDBL instead. 356 #define MAKE_HEX_FLOAT(x,y,z) x 357 #define MAKE_HEX_DOUBLE(x,y,z) x 358 #define MAKE_HEX_LONG(x,y,z) x 359 360 #endif 361 362 363 /* 364 ------------------------------------------------------------------------------------------------ 365 HEX_FLT, HEXT_DBL, HEX_LDBL -- Create hex floating point literal of type float, double, long 366 double respectively. Arguments: 367 368 sm -- sign of number, 369 int -- integer part of mantissa (without `0x' prefix), 370 fract -- fractional part of mantissa (without decimal point and `L' or `LL' suffixes), 371 se -- sign of exponent, 372 exp -- absolute value of (binary) exponent. 373 374 Example: 375 376 double yhi = HEX_DBL( +, 1, 5555555555555, -, 2 ); // == 0x1.5555555555555p-2 377 378 Note: 379 380 We have to pass signs as separate arguments because gcc pass negative integer values 381 (e. g. `-2') into a macro as two separate tokens, so `HEX_FLT( 1, 0, -2 )' produces result 382 `0x1.0p- 2' (note a space between minus and two) which is not a correct floating point 383 literal. 384 ------------------------------------------------------------------------------------------------ 385 */ 386 #if defined ( _MSC_VER ) && ! defined( __INTEL_COMPILER ) 387 // If compiler does not support hex floating point literals: 388 #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 ) ) ) 389 #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 ) ) ) 390 #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 ) ) ) 391 #else 392 // If compiler supports hex floating point literals: just concatenate all the parts into a literal. 393 #define HEX_FLT( sm, int, fract, se, exp ) sm 0x ## int ## . ## fract ## p ## se ## exp ## F 394 #define HEX_DBL( sm, int, fract, se, exp ) sm 0x ## int ## . ## fract ## p ## se ## exp 395 #define HEX_LDBL( sm, int, fract, se, exp ) sm 0x ## int ## . ## fract ## p ## se ## exp ## L 396 #endif 397 398 #if defined(__MINGW32__) 399 #include <Windows.h> 400 #define sleep(sec) Sleep((sec) * 1000) 401 #endif 402 403 #endif // _COMPAT_H_ 404