blob: 36f5bd487b5266b427a906cb8d9108e2410c8e96 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07004 * 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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
Yaowu Xuf883b422016-08-30 14:01:10 -070012#ifndef AOM_PORTS_BITOPS_H_
13#define AOM_PORTS_BITOPS_H_
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
15#include <assert.h>
16
17#include "aom_ports/msvc.h"
18
19#ifdef _MSC_VER
20#if 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
Yaowu Xuf883b422016-08-30 14:01:10 -070076#endif // AOM_PORTS_BITOPS_H_