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