Line data Source code
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_PORTS_BITOPS_H_
13 : #define AOM_PORTS_BITOPS_H_
14 :
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
27 : extern "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)
37 0 : static INLINE int get_msb(unsigned int n) {
38 0 : assert(n != 0);
39 0 : return 31 ^ __builtin_clz(n);
40 : }
41 : #elif defined(USE_MSC_INTRINSICS)
42 : #pragma intrinsic(_BitScanReverse)
43 :
44 : static 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.
53 : static 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 // AOM_PORTS_BITOPS_H_
|