Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This file defines some bit utilities. | 5 // This file defines some bit utilities. |
| 6 | 6 |
| 7 #ifndef BASE_BITS_H_ | 7 #ifndef BASE_BITS_H_ |
| 8 #define BASE_BITS_H_ | 8 #define BASE_BITS_H_ |
| 9 | 9 |
| 10 #include <stddef.h> | 10 #include <stddef.h> |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 return 1 + Log2Floor(n - 1); | 42 return 1 + Log2Floor(n - 1); |
| 43 } | 43 } |
| 44 } | 44 } |
| 45 | 45 |
| 46 // Round up |size| to a multiple of alignment, which must be a power of two. | 46 // Round up |size| to a multiple of alignment, which must be a power of two. |
| 47 inline size_t Align(size_t size, size_t alignment) { | 47 inline size_t Align(size_t size, size_t alignment) { |
| 48 DCHECK_EQ(alignment & (alignment - 1), 0u); | 48 DCHECK_EQ(alignment & (alignment - 1), 0u); |
| 49 return (size + alignment - 1) & ~(alignment - 1); | 49 return (size + alignment - 1) & ~(alignment - 1); |
| 50 } | 50 } |
| 51 | 51 |
| 52 inline int CountLeadingZerosFallback(uint32_t value) { | |
|
vmpstr
2016/03/29 18:38:13
This should probably be a separate CL. Wdyt?
cblume
2016/03/29 18:53:44
I agree 100%.
I'll separate it out.
| |
| 53 if (value == 0) { | |
| 54 return 32; | |
| 55 } | |
| 56 | |
| 57 int zeros = 31; | |
| 58 if (value & 0xFFFF0000) { | |
| 59 zeros -= 16; | |
| 60 value >>= 16; | |
| 61 } | |
| 62 if (value & 0xFF00) { | |
| 63 zeros -= 8; | |
| 64 value >>= 8; | |
| 65 } | |
| 66 if (value & 0xF0) { | |
| 67 zeros -= 4; | |
| 68 value >>= 4; | |
| 69 } | |
| 70 if (value & 0xC) { | |
| 71 zeros -= 2; | |
| 72 value >>= 2; | |
| 73 } | |
| 74 if (value & 0x2) { | |
| 75 zeros -= 1; | |
| 76 } | |
| 77 | |
| 78 return zeros; | |
| 79 } | |
| 80 | |
| 81 // Returns the number of leading zero bits | |
| 82 #if defined(_MSC_VER) | |
| 83 // There is an intrinsic available on x86, ARM, and x64. | |
| 84 #if defined(_M_IX64) || defined(_M_ARM) || defined(_M_6X4) | |
| 85 #include <intrin.h> | |
| 86 | |
| 87 #pragma intrinsic(_BitScanReverse) | |
| 88 inline int CountLeadingZeros(uint32_t value) { | |
| 89 // We want to work with uint32_ts. | |
| 90 // But the intrinsic signature is unsigned long. | |
| 91 static_assert(sizeof(uint32_t) == sizeof(unsigned long), | |
| 92 "Failed assumption that long is 32-bit."); | |
| 93 | |
| 94 // _BitScanReverse returns the index of the first set bit if there is one. | |
| 95 // Otherwise, it returns 0. | |
| 96 unsigned long first_set_bit_index; | |
| 97 if (_BitScanReverse(&first_set_bit_index, value) { | |
| 98 return 31 - first_set_bit_index; | |
| 99 } else { | |
| 100 return 32; | |
| 101 } | |
| 102 } | |
| 103 #else // We cannot use the intrinsic so use the fallback | |
| 104 inline int CountLeadingZeros(uint32_t value) { | |
| 105 return CountLeadingZerosFallback(value); | |
| 106 } | |
| 107 #endif | |
| 108 #elif defined(__clang__) | |
| 109 #if __has_builtin(__builtin_clz) | |
| 110 inline int CountLeadingZeros(uint32_t value) { | |
| 111 // We want to work with uint32_ts. | |
| 112 // But the intrinsic signature is unsigned long. | |
| 113 static_assert(sizeof(uint32_t) == sizeof(unsigned int), | |
| 114 "Failed assumption that int is 32-bit."); | |
| 115 | |
| 116 if (value == 0) { | |
| 117 return 32; | |
| 118 } else { | |
| 119 return __builtin_clz(value); | |
| 120 } | |
| 121 } | |
| 122 #else // We could not use __builtin_clz | |
| 123 inline int CountLeadingZeros(uint32_t value) { | |
| 124 return CountLeadingZerosFallback(value); | |
| 125 } | |
| 126 #endif | |
| 127 #else // unrecognized compiler | |
| 128 #error Unrecognized compiler | |
| 129 #endif | |
| 130 | |
| 52 } // namespace bits | 131 } // namespace bits |
| 53 } // namespace base | 132 } // namespace base |
| 54 | 133 |
| 55 #endif // BASE_BITS_H_ | 134 #endif // BASE_BITS_H_ |
| OLD | NEW |