1 /* 2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #ifndef AOM_AOM_PORTS_BITOPS_H_ 13 #define AOM_AOM_PORTS_BITOPS_H_ 14 15 #include <assert.h> 16 17 #include "aom_ports/msvc.h" 18 #include "config/aom_config.h" 19 20 #ifdef _MSC_VER 21 #if defined(_M_X64) || defined(_M_IX86) 22 #include <intrin.h> 23 #define USE_MSC_INTRINSICS 24 #endif 25 #endif 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 // get_msb: 32 // Returns (int)floor(log2(n)). n must be > 0. 33 // These versions of get_msb() are only valid when n != 0 because all 34 // of the optimized versions are undefined when n == 0: 35 // https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html 36 37 // use GNU builtins where available. 38 #if defined(__GNUC__) && \ 39 ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) get_msb(unsigned int n)40static INLINE int get_msb(unsigned int n) { 41 assert(n != 0); 42 return 31 ^ __builtin_clz(n); 43 } 44 #elif defined(USE_MSC_INTRINSICS) 45 #pragma intrinsic(_BitScanReverse) 46 47 static INLINE int get_msb(unsigned int n) { 48 unsigned long first_set_bit; 49 assert(n != 0); 50 _BitScanReverse(&first_set_bit, n); 51 return first_set_bit; 52 } 53 #undef USE_MSC_INTRINSICS 54 #else 55 static INLINE int get_msb(unsigned int n) { 56 int log = 0; 57 unsigned int value = n; 58 int i; 59 60 assert(n != 0); 61 62 for (i = 4; i >= 0; --i) { 63 const int shift = (1 << i); 64 const unsigned int x = value >> shift; 65 if (x != 0) { 66 value = x; 67 log += shift; 68 } 69 } 70 return log; 71 } 72 #endif 73 74 #ifdef __cplusplus 75 } // extern "C" 76 #endif 77 78 #endif // AOM_AOM_PORTS_BITOPS_H_ 79