1 #ifndef __MDFN_MATH_OPS_H
2 #define __MDFN_MATH_OPS_H
3 
4 // Source: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
5 // Rounds up to the nearest power of 2.
round_up_pow2(uint64 v)6 static INLINE uint64 round_up_pow2(uint64 v)
7 {
8  v--;
9  v |= v >> 1;
10  v |= v >> 2;
11  v |= v >> 4;
12  v |= v >> 8;
13  v |= v >> 16;
14  v |= v >> 32;
15  v++;
16 
17  v += (v == 0);
18 
19  return(v);
20 }
21 
uilog2(uint32 v)22 static INLINE uint32 uilog2(uint32 v)
23 {
24  // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
25 
26  static const uint32 MultiplyDeBruijnBitPosition[32] =
27  {
28    0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
29    8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
30  };
31 
32  v |= v >> 1; // first round down to one less than a power of 2
33  v |= v >> 2;
34  v |= v >> 4;
35  v |= v >> 8;
36  v |= v >> 16;
37 
38  return MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
39 }
40 
41 // Some compilers' optimizers and some platforms might fubar the generated code from these macros,
42 // so some tests are run in...tests.cpp
43 #define sign_8_to_s16(_value) ((int16)(int8)(_value))
44 #define sign_9_to_s16(_value)  (((int16)((unsigned int)(_value) << 7)) >> 7)
45 #define sign_10_to_s16(_value)  (((int16)((uint32)(_value) << 6)) >> 6)
46 #define sign_11_to_s16(_value)  (((int16)((uint32)(_value) << 5)) >> 5)
47 #define sign_12_to_s16(_value)  (((int16)((uint32)(_value) << 4)) >> 4)
48 #define sign_13_to_s16(_value)  (((int16)((uint32)(_value) << 3)) >> 3)
49 #define sign_14_to_s16(_value)  (((int16)((uint32)(_value) << 2)) >> 2)
50 #define sign_15_to_s16(_value)  (((int16)((uint32)(_value) << 1)) >> 1)
51 
52 // This obviously won't convert higher-than-32 bit numbers to signed 32-bit ;)
53 // Also, this shouldn't be used for 8-bit and 16-bit signed numbers, since you can
54 // convert those faster with typecasts...
55 #define sign_x_to_s32(_bits, _value) (((int32)((uint32)(_value) << (32 - _bits))) >> (32 - _bits))
56 
57 #endif
58