summaryrefslogtreecommitdiffstats
path: root/media/libvpx/libvpx/vpx_ports/bitops.h
diff options
context:
space:
mode:
Diffstat (limited to 'media/libvpx/libvpx/vpx_ports/bitops.h')
-rw-r--r--media/libvpx/libvpx/vpx_ports/bitops.h94
1 files changed, 94 insertions, 0 deletions
diff --git a/media/libvpx/libvpx/vpx_ports/bitops.h b/media/libvpx/libvpx/vpx_ports/bitops.h
new file mode 100644
index 0000000000..1b5cdaa6dd
--- /dev/null
+++ b/media/libvpx/libvpx/vpx_ports/bitops.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef VPX_VPX_PORTS_BITOPS_H_
+#define VPX_VPX_PORTS_BITOPS_H_
+
+#include <assert.h>
+
+#include "vpx_ports/msvc.h"
+
+#ifdef _MSC_VER
+#if defined(_M_X64) || defined(_M_IX86)
+#include <intrin.h>
+#define USE_MSC_INTRINSICS
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// These versions of get_lsb() and get_msb() are only valid when n != 0
+// because all of the optimized versions are undefined when n == 0:
+// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
+
+// use GNU builtins where available.
+#if defined(__GNUC__) && \
+ ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+static INLINE int get_lsb(unsigned int n) {
+ assert(n != 0);
+ return __builtin_ctz(n);
+}
+
+static INLINE int get_msb(unsigned int n) {
+ assert(n != 0);
+ return 31 ^ __builtin_clz(n);
+}
+#elif defined(USE_MSC_INTRINSICS)
+#pragma intrinsic(_BitScanForward)
+#pragma intrinsic(_BitScanReverse)
+
+static INLINE int get_lsb(unsigned int n) {
+ unsigned long first_set_bit; // NOLINT(runtime/int)
+ _BitScanForward(&first_set_bit, n);
+ return first_set_bit;
+}
+
+static INLINE int get_msb(unsigned int n) {
+ unsigned long first_set_bit;
+ assert(n != 0);
+ _BitScanReverse(&first_set_bit, n);
+ return first_set_bit;
+}
+#undef USE_MSC_INTRINSICS
+#else
+static INLINE int get_lsb(unsigned int n) {
+ int i;
+ assert(n != 0);
+ for (i = 0; i < 32 && !(n & 1); ++i) n >>= 1;
+ return i;
+}
+
+// Returns (int)floor(log2(n)). n must be > 0.
+static INLINE int get_msb(unsigned int n) {
+ int log = 0;
+ unsigned int value = n;
+ int i;
+
+ assert(n != 0);
+
+ for (i = 4; i >= 0; --i) {
+ const int shift = (1 << i);
+ const unsigned int x = value >> shift;
+ if (x != 0) {
+ value = x;
+ log += shift;
+ }
+ }
+ return log;
+}
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // VPX_VPX_PORTS_BITOPS_H_