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 uint32_t float_sign(float val) {
     16   uint32_t bits = bit_cast<uint32_t>(val);
     17   return unsigned_bitextract_32(31, 31, bits);
     18 }
     19 
     20 uint32_t float_exp(float val) {
     21   uint32_t bits = bit_cast<uint32_t>(val);
     22   return unsigned_bitextract_32(30, 23, bits);
     23 }
     24 
     25 uint32_t float_mantissa(float val) {
     26   uint32_t bits = bit_cast<uint32_t>(val);
     27   return unsigned_bitextract_32(22, 0, bits);
     28 }
     29 
     30 uint32_t double_sign(double val) {
     31   uint64_t bits = bit_cast<uint64_t>(val);
     32   return static_cast<uint32_t>(unsigned_bitextract_64(63, 63, bits));
     33 }
     34 
     35 uint32_t double_exp(double val) {
     36   uint64_t bits = bit_cast<uint64_t>(val);
     37   return static_cast<uint32_t>(unsigned_bitextract_64(62, 52, bits));
     38 }
     39 
     40 uint64_t double_mantissa(double val) {
     41   uint64_t bits = bit_cast<uint64_t>(val);
     42   return unsigned_bitextract_64(51, 0, bits);
     43 }
     44 
     45 float float_pack(uint32_t sign, uint32_t exp, uint32_t mantissa) {
     46   uint32_t bits = sign << kFloatExponentBits | exp;
     47   return bit_cast<float>((bits << kFloatMantissaBits) | mantissa);
     48 }
     49 
     50 double double_pack(uint64_t sign, uint64_t exp, uint64_t mantissa) {
     51   uint64_t bits = sign << kDoubleExponentBits | exp;
     52   return bit_cast<double>((bits << kDoubleMantissaBits) | mantissa);
     53 }
     54 
     55 int float16classify(float16 value) {
     56   const uint16_t exponent_max = (1 << kFloat16ExponentBits) - 1;
     57   const uint16_t exponent_mask = exponent_max << kFloat16MantissaBits;
     58   const uint16_t mantissa_mask = (1 << kFloat16MantissaBits) - 1;
     59 
     60   const uint16_t exponent = (value & exponent_mask) >> kFloat16MantissaBits;
     61   const uint16_t mantissa = value & mantissa_mask;
     62   if (exponent == 0) {
     63     if (mantissa == 0) {
     64       return FP_ZERO;
     65     }
     66     return FP_SUBNORMAL;
     67   } else if (exponent == exponent_max) {
     68     if (mantissa == 0) {
     69       return FP_INFINITE;
     70     }
     71     return FP_NAN;
     72   }
     73   return FP_NORMAL;
     74 }
     75 
     76 int CountLeadingZeros(uint64_t value, int width) {
     77   DCHECK(base::bits::IsPowerOfTwo(width) && (width <= 64));
     78   if (value == 0) {
     79     return width;
     80   }
     81   return base::bits::CountLeadingZeros64(value << (64 - width));
     82 }
     83 
     84 
     85 int CountLeadingSignBits(int64_t value, int width) {
     86   DCHECK(base::bits::IsPowerOfTwo(width) && (width <= 64));
     87   if (value >= 0) {
     88     return CountLeadingZeros(value, width) - 1;
     89   } else {
     90     return CountLeadingZeros(~value, width) - 1;
     91   }
     92 }
     93 
     94 
     95 int CountTrailingZeros(uint64_t value, int width) {
     96   DCHECK((width == 32) || (width == 64));
     97   if (width == 64) {
     98     return static_cast<int>(base::bits::CountTrailingZeros64(value));
     99   }
    100   return static_cast<int>(base::bits::CountTrailingZeros32(
    101       static_cast<uint32_t>(value & 0xFFFFFFFFF)));
    102 }
    103 
    104 
    105 int CountSetBits(uint64_t value, int width) {
    106   DCHECK((width == 32) || (width == 64));
    107   if (width == 64) {
    108     return static_cast<int>(base::bits::CountPopulation(value));
    109   }
    110   return static_cast<int>(
    111       base::bits::CountPopulation(static_cast<uint32_t>(value & 0xFFFFFFFFF)));
    112 }
    113 
    114 int LowestSetBitPosition(uint64_t value) {
    115   DCHECK_NE(value, 0U);
    116   return CountTrailingZeros(value, 64) + 1;
    117 }
    118 
    119 int HighestSetBitPosition(uint64_t value) {
    120   DCHECK_NE(value, 0U);
    121   return 63 - CountLeadingZeros(value, 64);
    122 }
    123 
    124 
    125 uint64_t LargestPowerOf2Divisor(uint64_t value) {
    126   return value & -value;
    127 }
    128 
    129 
    130 int MaskToBit(uint64_t mask) {
    131   DCHECK_EQ(CountSetBits(mask, 64), 1);
    132   return CountTrailingZeros(mask, 64);
    133 }
    134 
    135 #undef __
    136 
    137 }  // namespace internal
    138 }  // namespace v8
    139 
    140 #endif  // V8_TARGET_ARCH_ARM64
    141