1 // Copyright 2006-2008 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_COMPILER_INTRINSICS_H_ 6 #define V8_COMPILER_INTRINSICS_H_ 7 8 namespace v8 { 9 namespace internal { 10 11 class CompilerIntrinsics { 12 public: 13 // Returns number of zero bits preceding least significant 1 bit. 14 // Undefined for zero value. 15 INLINE(static int CountTrailingZeros(uint32_t value)); 16 17 // Returns number of zero bits following most significant 1 bit. 18 // Undefined for zero value. 19 INLINE(static int CountLeadingZeros(uint32_t value)); 20 21 // Returns the number of bits set. 22 INLINE(static int CountSetBits(uint32_t value)); 23 }; 24 25 #ifdef __GNUC__ CountTrailingZeros(uint32_t value)26int CompilerIntrinsics::CountTrailingZeros(uint32_t value) { 27 return __builtin_ctz(value); 28 } 29 CountLeadingZeros(uint32_t value)30int CompilerIntrinsics::CountLeadingZeros(uint32_t value) { 31 return __builtin_clz(value); 32 } 33 CountSetBits(uint32_t value)34int CompilerIntrinsics::CountSetBits(uint32_t value) { 35 return __builtin_popcount(value); 36 } 37 38 #elif defined(_MSC_VER) 39 40 #pragma intrinsic(_BitScanForward) 41 #pragma intrinsic(_BitScanReverse) 42 CountTrailingZeros(uint32_t value)43int CompilerIntrinsics::CountTrailingZeros(uint32_t value) { 44 unsigned long result; //NOLINT 45 _BitScanForward(&result, static_cast<long>(value)); //NOLINT 46 return static_cast<int>(result); 47 } 48 CountLeadingZeros(uint32_t value)49int CompilerIntrinsics::CountLeadingZeros(uint32_t value) { 50 unsigned long result; //NOLINT 51 _BitScanReverse(&result, static_cast<long>(value)); //NOLINT 52 return 31 - static_cast<int>(result); 53 } 54 CountSetBits(uint32_t value)55int CompilerIntrinsics::CountSetBits(uint32_t value) { 56 // Manually count set bits. 57 value = ((value >> 1) & 0x55555555) + (value & 0x55555555); 58 value = ((value >> 2) & 0x33333333) + (value & 0x33333333); 59 value = ((value >> 4) & 0x0f0f0f0f) + (value & 0x0f0f0f0f); 60 value = ((value >> 8) & 0x00ff00ff) + (value & 0x00ff00ff); 61 value = ((value >> 16) & 0x0000ffff) + (value & 0x0000ffff); 62 return value; 63 } 64 65 #else 66 #error Unsupported compiler 67 #endif 68 69 } } // namespace v8::internal 70 71 #endif // V8_COMPILER_INTRINSICS_H_ 72