Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Unified Diff: base/bits.h

Issue 2512593002: Move wtf/BitwiseOperations.h into base/bits.h. (Closed)
Patch Set: Add a TODO. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/bits_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/bits.h
diff --git a/base/bits.h b/base/bits.h
index a3a59d1dfad0d4c2992b1a6d0abd9a0c4fc2b1aa..d101cb731a7da764150ff567777a1c232c4f522f 100644
--- a/base/bits.h
+++ b/base/bits.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,8 +10,13 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/compiler_specific.h"
#include "base/logging.h"
+#if defined(COMPILER_MSVC)
+#include <intrin.h>
+#endif
+
namespace base {
namespace bits {
@@ -49,6 +54,58 @@ inline size_t Align(size_t size, size_t alignment) {
return (size + alignment - 1) & ~(alignment - 1);
}
+// These functions count the number of leading zeros in a binary value, starting
+// with the most significant bit. C does not have an operator to do this, but
+// fortunately the various compilers have built-ins that map to fast underlying
+// processor instructions.
+#if defined(COMPILER_MSVC)
+
+ALWAYS_INLINE uint32_t CountLeadingZeroBits32(uint32_t x) {
+ unsigned long index;
+ return LIKELY(_BitScanReverse(&index, x)) ? (31 - index) : 32;
+}
+
+#if defined(ARCH_CPU_64_BITS)
+
+// MSVC only supplies _BitScanForward64 when building for a 64-bit target.
+ALWAYS_INLINE uint64_t CountLeadingZeroBits64(uint64_t x) {
+ unsigned long index;
+ return LIKELY(_BitScanReverse64(&index, x)) ? (63 - index) : 64;
+}
+
+#endif
+
+#elif defined(COMPILER_GCC)
+
+// This is very annoying. __builtin_clz has undefined behaviour for an input of
+// 0, even though there's clearly a return value that makes sense, and even
+// though some processor clz instructions have defined behaviour for 0. We could
+// drop to raw __asm__ to do better, but we'll avoid doing that unless we see
+// proof that we need to.
+ALWAYS_INLINE uint32_t CountLeadingZeroBits32(uint32_t x) {
+ return LIKELY(x) ? __builtin_clz(x) : 32;
+}
+
+ALWAYS_INLINE uint64_t CountLeadingZeroBits64(uint64_t x) {
+ return LIKELY(x) ? __builtin_clzll(x) : 64;
+}
+
+#endif
+
+#if defined(ARCH_CPU_64_BITS)
+
+ALWAYS_INLINE size_t CountLeadingZeroBitsSizeT(size_t x) {
+ return CountLeadingZeroBits64(x);
+}
+
+#else
+
+ALWAYS_INLINE size_t CountLeadingZeroBitsSizeT(size_t x) {
+ return CountLeadingZeroBits32(x);
+}
+
+#endif
+
} // namespace bits
} // namespace base
« no previous file with comments | « no previous file | base/bits_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698