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