diff options
Diffstat (limited to 'source/blender/blenlib/intern/math_bits_inline.c')
-rw-r--r-- | source/blender/blenlib/intern/math_bits_inline.c | 75 |
1 files changed, 68 insertions, 7 deletions
diff --git a/source/blender/blenlib/intern/math_bits_inline.c b/source/blender/blenlib/intern/math_bits_inline.c index 82d7e2114c2..9b16756134e 100644 --- a/source/blender/blenlib/intern/math_bits_inline.c +++ b/source/blender/blenlib/intern/math_bits_inline.c @@ -25,16 +25,77 @@ #ifndef __MATH_BITS_INLINE_C__ #define __MATH_BITS_INLINE_C__ +#ifdef _MSC_VER +# include <intrin.h> +#endif + #include "BLI_math_bits.h" -MINLINE unsigned int highest_order_bit_i(unsigned int n) +MINLINE int bitscan_forward_i(int a) { - n |= (n >> 1); - n |= (n >> 2); - n |= (n >> 4); - n |= (n >> 8); - n |= (n >> 16); - return n - (n >> 1); + BLI_assert(a != 0); +#ifdef _MSC_VER + unsigned long ctz; + _BitScanForward(&ctz, a); + return ctz; +#else + return __builtin_ctz((unsigned int)a); +#endif +} + +MINLINE unsigned int bitscan_forward_uint(unsigned int a) +{ + return (unsigned int)bitscan_forward_i((int)a); +} + +MINLINE int bitscan_forward_clear_i(int *a) +{ + int i = bitscan_forward_i(*a); + *a &= (*a) - 1; + return i; +} + +MINLINE unsigned int bitscan_forward_clear_uint(unsigned int *a) +{ + return (unsigned int)bitscan_forward_clear_i((int *)a); +} + +MINLINE int bitscan_reverse_i(int a) +{ + BLI_assert(a != 0); +#ifdef _MSC_VER + unsigned long clz; + _BitScanReverse(&clz, a); + return clz; +#else + return __builtin_clz((unsigned int)a); +#endif +} + +MINLINE unsigned int bitscan_reverse_uint(unsigned int a) +{ + return (unsigned int)bitscan_reverse_i((int)a); +} + +MINLINE int bitscan_reverse_clear_i(int *a) +{ + int i = bitscan_reverse_i(*a); + /* TODO(sergey): This could probably be optimized. */ + *a &= ~(1 << (sizeof(int) * 8 - i - 1)); + return i; +} + +MINLINE unsigned int bitscan_reverse_clear_uint(unsigned int *a) +{ + return (unsigned int)bitscan_reverse_clear_i((int *)a); +} + +MINLINE unsigned int highest_order_bit_uint(unsigned int n) +{ + if (n == 0) { + return 0; + } + return 1 << (sizeof(unsigned int) * 8 - bitscan_reverse_uint(n)); } MINLINE unsigned short highest_order_bit_s(unsigned short n) |