1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_MISC_INTRINSICS_H_ 6 #define V8_MISC_INTRINSICS_H_ 7 8 #include "include/v8.h" 9 #include "src/globals.h" 10 11 namespace v8 { 12 namespace internal { 13 14 // Returns the index of the leading 1 bit, counting the least significant bit at 15 // index 0. (1 << IntegerLog2(x)) is a mask for the most significant bit of x. 16 // Result is undefined if input is zero. 17 int IntegerLog2(uint32_t value); 18 19 #if defined(__GNUC__) 20 IntegerLog2(uint32_t value)21inline int IntegerLog2(uint32_t value) { 22 return 31 - __builtin_clz(value); 23 } 24 25 #elif defined(_MSC_VER) 26 27 #pragma intrinsic(_BitScanReverse) 28 IntegerLog2(uint32_t value)29inline int IntegerLog2(uint32_t value) { 30 unsigned long result; // NOLINT: MSVC intrinsic demands this type. 31 _BitScanReverse(&result, value); 32 return result; 33 } 34 35 #else 36 37 // Default version using regular operations. Code taken from: 38 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog IntegerLog2(uint32_t value)39inline int IntegerLog2(uint32_t value) { 40 int result, shift; 41 42 shift = (value > 0xFFFF) << 4; 43 value >>= shift; 44 result = shift; 45 46 shift = (value > 0xFF) << 3; 47 value >>= shift; 48 result |= shift; 49 50 shift = (value > 0xF) << 2; 51 value >>= shift; 52 result |= shift; 53 54 shift = (value > 0x3) << 1; 55 value >>= shift; 56 result |= shift; 57 58 result |= (value >> 1); 59 60 return result; 61 } 62 #endif 63 64 } } // namespace v8::internal 65 66 #endif // V8_MISC_INTRINSICS_H_ 67