1 #ifndef __MDFN_MATH_OPS_H 2 #define __MDFN_MATH_OPS_H 3 4 #ifdef _MSC_VER 5 #include <intrin.h> 6 #endif 7 8 // 9 // Result is defined for all possible inputs(including 0). 10 // MDFN_lzcount32(uint32 v)11static INLINE unsigned MDFN_lzcount32(uint32 v) 12 { 13 #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) 14 return v ? __builtin_clz(v) : 32; 15 #elif defined(_MSC_VER) 16 unsigned long idx; 17 18 if(!v) 19 return 32; 20 21 _BitScanReverse(&idx, v); 22 23 return 31 - idx; 24 #else 25 unsigned ret = 0; 26 27 if(!v) 28 return(32); 29 30 if(!(v & 0xFFFF0000)) 31 { 32 v <<= 16; 33 ret += 16; 34 } 35 36 if(!(v & 0xFF000000)) 37 { 38 v <<= 8; 39 ret += 8; 40 } 41 42 if(!(v & 0xF0000000)) 43 { 44 v <<= 4; 45 ret += 4; 46 } 47 48 if(!(v & 0xC0000000)) 49 { 50 v <<= 2; 51 ret += 2; 52 } 53 54 if(!(v & 0x80000000)) 55 { 56 v <<= 1; 57 ret += 1; 58 } 59 60 return(ret); 61 #endif 62 } 63 64 // Source: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 65 // Rounds up to the nearest power of 2. round_up_pow2(uint32 v)66static INLINE uint32 round_up_pow2(uint32 v) 67 { 68 v--; 69 v |= v >> 1; 70 v |= v >> 2; 71 v |= v >> 4; 72 v |= v >> 8; 73 v |= v >> 16; 74 v++; 75 76 v += (v == 0); 77 78 return(v); 79 } 80 81 // Some compilers' optimizers and some platforms might fubar the generated code from these macros, 82 // so some tests are run in...tests.cpp 83 #define sign_8_to_s16(_value) ((int16)(int8)(_value)) 84 #define sign_9_to_s16(_value) (((int16)((unsigned int)(_value) << 7)) >> 7) 85 #define sign_10_to_s16(_value) (((int16)((uint32)(_value) << 6)) >> 6) 86 #define sign_11_to_s16(_value) (((int16)((uint32)(_value) << 5)) >> 5) 87 #define sign_12_to_s16(_value) (((int16)((uint32)(_value) << 4)) >> 4) 88 #define sign_13_to_s16(_value) (((int16)((uint32)(_value) << 3)) >> 3) 89 #define sign_14_to_s16(_value) (((int16)((uint32)(_value) << 2)) >> 2) 90 #define sign_15_to_s16(_value) (((int16)((uint32)(_value) << 1)) >> 1) 91 92 // This obviously won't convert higher-than-32 bit numbers to signed 32-bit ;) 93 // Also, this shouldn't be used for 8-bit and 16-bit signed numbers, since you can 94 // convert those faster with typecasts... 95 #define sign_x_to_s32(_bits, _value) (((int32)((uint32)(_value) << (32 - (_bits)))) >> (32 - (_bits))) 96 97 #endif 98