Home | History | Annotate | Download | only in arm64
      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 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 v8::internal
     93 
     94 #endif  // V8_TARGET_ARCH_ARM64
     95