1 // Copyright 2013 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 #if V8_TARGET_ARCH_ARM64 6 7 #include "src/arm64/utils-arm64.h" 8 9 10 namespace v8 { 11 namespace internal { 12 13 #define __ assm-> 14 15 16 int CountLeadingZeros(uint64_t value, int width) { 17 // TODO(jbramley): Optimize this for ARM64 hosts. 18 DCHECK((width == 32) || (width == 64)); 19 int count = 0; 20 uint64_t bit_test = 1UL << (width - 1); 21 while ((count < width) && ((bit_test & value) == 0)) { 22 count++; 23 bit_test >>= 1; 24 } 25 return count; 26 } 27 28 29 int CountLeadingSignBits(int64_t value, int width) { 30 // TODO(jbramley): Optimize this for ARM64 hosts. 31 DCHECK((width == 32) || (width == 64)); 32 if (value >= 0) { 33 return CountLeadingZeros(value, width) - 1; 34 } else { 35 return CountLeadingZeros(~value, width) - 1; 36 } 37 } 38 39 40 int CountTrailingZeros(uint64_t value, int width) { 41 // TODO(jbramley): Optimize this for ARM64 hosts. 42 DCHECK((width == 32) || (width == 64)); 43 int count = 0; 44 while ((count < width) && (((value >> count) & 1) == 0)) { 45 count++; 46 } 47 return count; 48 } 49 50 51 int CountSetBits(uint64_t value, int width) { 52 // TODO(jbramley): Would it be useful to allow other widths? The 53 // implementation already supports them. 54 DCHECK((width == 32) || (width == 64)); 55 56 // Mask out unused bits to ensure that they are not counted. 57 value &= (0xffffffffffffffffUL >> (64-width)); 58 59 // Add up the set bits. 60 // The algorithm works by adding pairs of bit fields together iteratively, 61 // where the size of each bit field doubles each time. 62 // An example for an 8-bit value: 63 // Bits: h g f e d c b a 64 // \ | \ | \ | \ | 65 // value = h+g f+e d+c b+a 66 // \ | \ | 67 // value = h+g+f+e d+c+b+a 68 // \ | 69 // value = h+g+f+e+d+c+b+a 70 value = ((value >> 1) & 0x5555555555555555) + (value & 0x5555555555555555); 71 value = ((value >> 2) & 0x3333333333333333) + (value & 0x3333333333333333); 72 value = ((value >> 4) & 0x0f0f0f0f0f0f0f0f) + (value & 0x0f0f0f0f0f0f0f0f); 73 value = ((value >> 8) & 0x00ff00ff00ff00ff) + (value & 0x00ff00ff00ff00ff); 74 value = ((value >> 16) & 0x0000ffff0000ffff) + (value & 0x0000ffff0000ffff); 75 value = ((value >> 32) & 0x00000000ffffffff) + (value & 0x00000000ffffffff); 76 77 return static_cast<int>(value); 78 } 79 80 81 uint64_t LargestPowerOf2Divisor(uint64_t value) { 82 return value & -value; 83 } 84 85 86 int MaskToBit(uint64_t mask) { 87 DCHECK(CountSetBits(mask, 64) == 1); 88 return CountTrailingZeros(mask, 64); 89 } 90 91 92 } // namespace internal 93 } // namespace v8 94 95 #endif // V8_TARGET_ARCH_ARM64 96