1*fb1b10abSAndroid Build Coastguard Worker /* 2*fb1b10abSAndroid Build Coastguard Worker * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3*fb1b10abSAndroid Build Coastguard Worker * 4*fb1b10abSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*fb1b10abSAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*fb1b10abSAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*fb1b10abSAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*fb1b10abSAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*fb1b10abSAndroid Build Coastguard Worker */ 10*fb1b10abSAndroid Build Coastguard Worker 11*fb1b10abSAndroid Build Coastguard Worker #ifndef VPX_VPX_PORTS_BITOPS_H_ 12*fb1b10abSAndroid Build Coastguard Worker #define VPX_VPX_PORTS_BITOPS_H_ 13*fb1b10abSAndroid Build Coastguard Worker 14*fb1b10abSAndroid Build Coastguard Worker #include <assert.h> 15*fb1b10abSAndroid Build Coastguard Worker 16*fb1b10abSAndroid Build Coastguard Worker #ifdef _MSC_VER 17*fb1b10abSAndroid Build Coastguard Worker #if defined(_M_X64) || defined(_M_IX86) 18*fb1b10abSAndroid Build Coastguard Worker #include <intrin.h> 19*fb1b10abSAndroid Build Coastguard Worker #define USE_MSC_INTRINSICS 20*fb1b10abSAndroid Build Coastguard Worker #endif 21*fb1b10abSAndroid Build Coastguard Worker #endif 22*fb1b10abSAndroid Build Coastguard Worker 23*fb1b10abSAndroid Build Coastguard Worker #ifdef __cplusplus 24*fb1b10abSAndroid Build Coastguard Worker extern "C" { 25*fb1b10abSAndroid Build Coastguard Worker #endif 26*fb1b10abSAndroid Build Coastguard Worker 27*fb1b10abSAndroid Build Coastguard Worker // These versions of get_lsb() and get_msb() are only valid when n != 0 28*fb1b10abSAndroid Build Coastguard Worker // because all of the optimized versions are undefined when n == 0: 29*fb1b10abSAndroid Build Coastguard Worker // https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html 30*fb1b10abSAndroid Build Coastguard Worker 31*fb1b10abSAndroid Build Coastguard Worker // use GNU builtins where available. 32*fb1b10abSAndroid Build Coastguard Worker #if defined(__GNUC__) && \ 33*fb1b10abSAndroid Build Coastguard Worker ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) get_lsb(unsigned int n)34*fb1b10abSAndroid Build Coastguard Workerstatic INLINE int get_lsb(unsigned int n) { 35*fb1b10abSAndroid Build Coastguard Worker assert(n != 0); 36*fb1b10abSAndroid Build Coastguard Worker return __builtin_ctz(n); 37*fb1b10abSAndroid Build Coastguard Worker } 38*fb1b10abSAndroid Build Coastguard Worker get_msb(unsigned int n)39*fb1b10abSAndroid Build Coastguard Workerstatic INLINE int get_msb(unsigned int n) { 40*fb1b10abSAndroid Build Coastguard Worker assert(n != 0); 41*fb1b10abSAndroid Build Coastguard Worker return 31 ^ __builtin_clz(n); 42*fb1b10abSAndroid Build Coastguard Worker } 43*fb1b10abSAndroid Build Coastguard Worker #elif defined(USE_MSC_INTRINSICS) 44*fb1b10abSAndroid Build Coastguard Worker #pragma intrinsic(_BitScanForward) 45*fb1b10abSAndroid Build Coastguard Worker #pragma intrinsic(_BitScanReverse) 46*fb1b10abSAndroid Build Coastguard Worker 47*fb1b10abSAndroid Build Coastguard Worker static INLINE int get_lsb(unsigned int n) { 48*fb1b10abSAndroid Build Coastguard Worker unsigned long first_set_bit; // NOLINT(runtime/int) 49*fb1b10abSAndroid Build Coastguard Worker _BitScanForward(&first_set_bit, n); 50*fb1b10abSAndroid Build Coastguard Worker return first_set_bit; 51*fb1b10abSAndroid Build Coastguard Worker } 52*fb1b10abSAndroid Build Coastguard Worker 53*fb1b10abSAndroid Build Coastguard Worker static INLINE int get_msb(unsigned int n) { 54*fb1b10abSAndroid Build Coastguard Worker unsigned long first_set_bit; 55*fb1b10abSAndroid Build Coastguard Worker assert(n != 0); 56*fb1b10abSAndroid Build Coastguard Worker _BitScanReverse(&first_set_bit, n); 57*fb1b10abSAndroid Build Coastguard Worker return first_set_bit; 58*fb1b10abSAndroid Build Coastguard Worker } 59*fb1b10abSAndroid Build Coastguard Worker #undef USE_MSC_INTRINSICS 60*fb1b10abSAndroid Build Coastguard Worker #else 61*fb1b10abSAndroid Build Coastguard Worker static INLINE int get_lsb(unsigned int n) { 62*fb1b10abSAndroid Build Coastguard Worker int i; 63*fb1b10abSAndroid Build Coastguard Worker assert(n != 0); 64*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < 32 && !(n & 1); ++i) n >>= 1; 65*fb1b10abSAndroid Build Coastguard Worker return i; 66*fb1b10abSAndroid Build Coastguard Worker } 67*fb1b10abSAndroid Build Coastguard Worker 68*fb1b10abSAndroid Build Coastguard Worker // Returns (int)floor(log2(n)). n must be > 0. 69*fb1b10abSAndroid Build Coastguard Worker static INLINE int get_msb(unsigned int n) { 70*fb1b10abSAndroid Build Coastguard Worker int log = 0; 71*fb1b10abSAndroid Build Coastguard Worker unsigned int value = n; 72*fb1b10abSAndroid Build Coastguard Worker int i; 73*fb1b10abSAndroid Build Coastguard Worker 74*fb1b10abSAndroid Build Coastguard Worker assert(n != 0); 75*fb1b10abSAndroid Build Coastguard Worker 76*fb1b10abSAndroid Build Coastguard Worker for (i = 4; i >= 0; --i) { 77*fb1b10abSAndroid Build Coastguard Worker const int shift = (1 << i); 78*fb1b10abSAndroid Build Coastguard Worker const unsigned int x = value >> shift; 79*fb1b10abSAndroid Build Coastguard Worker if (x != 0) { 80*fb1b10abSAndroid Build Coastguard Worker value = x; 81*fb1b10abSAndroid Build Coastguard Worker log += shift; 82*fb1b10abSAndroid Build Coastguard Worker } 83*fb1b10abSAndroid Build Coastguard Worker } 84*fb1b10abSAndroid Build Coastguard Worker return log; 85*fb1b10abSAndroid Build Coastguard Worker } 86*fb1b10abSAndroid Build Coastguard Worker #endif 87*fb1b10abSAndroid Build Coastguard Worker 88*fb1b10abSAndroid Build Coastguard Worker #ifdef __cplusplus 89*fb1b10abSAndroid Build Coastguard Worker } // extern "C" 90*fb1b10abSAndroid Build Coastguard Worker #endif 91*fb1b10abSAndroid Build Coastguard Worker 92*fb1b10abSAndroid Build Coastguard Worker #endif // VPX_VPX_PORTS_BITOPS_H_ 93