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)11 static 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)66 static 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