// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#if V8_TARGET_ARCH_ARM64

#include "src/codegen/arm64/utils-arm64.h"

namespace v8 {
namespace internal {

#define __ assm->

uint32_t float_sign(float val) {
  uint32_t bits = bit_cast<uint32_t>(val);
  return unsigned_bitextract_32(31, 31, bits);
}

uint32_t float_exp(float val) {
  uint32_t bits = bit_cast<uint32_t>(val);
  return unsigned_bitextract_32(30, 23, bits);
}

uint32_t float_mantissa(float val) {
  uint32_t bits = bit_cast<uint32_t>(val);
  return unsigned_bitextract_32(22, 0, bits);
}

uint32_t double_sign(double val) {
  uint64_t bits = bit_cast<uint64_t>(val);
  return static_cast<uint32_t>(unsigned_bitextract_64(63, 63, bits));
}

uint32_t double_exp(double val) {
  uint64_t bits = bit_cast<uint64_t>(val);
  return static_cast<uint32_t>(unsigned_bitextract_64(62, 52, bits));
}

uint64_t double_mantissa(double val) {
  uint64_t bits = bit_cast<uint64_t>(val);
  return unsigned_bitextract_64(51, 0, bits);
}

float float_pack(uint32_t sign, uint32_t exp, uint32_t mantissa) {
  uint32_t bits = sign << kFloatExponentBits | exp;
  return bit_cast<float>((bits << kFloatMantissaBits) | mantissa);
}

double double_pack(uint64_t sign, uint64_t exp, uint64_t mantissa) {
  uint64_t bits = sign << kDoubleExponentBits | exp;
  return bit_cast<double>((bits << kDoubleMantissaBits) | mantissa);
}

int float16classify(float16 value) {
  const uint16_t exponent_max = (1 << kFloat16ExponentBits) - 1;
  const uint16_t exponent_mask = exponent_max << kFloat16MantissaBits;
  const uint16_t mantissa_mask = (1 << kFloat16MantissaBits) - 1;

  const uint16_t exponent = (value & exponent_mask) >> kFloat16MantissaBits;
  const uint16_t mantissa = value & mantissa_mask;
  if (exponent == 0) {
    if (mantissa == 0) {
      return FP_ZERO;
    }
    return FP_SUBNORMAL;
  } else if (exponent == exponent_max) {
    if (mantissa == 0) {
      return FP_INFINITE;
    }
    return FP_NAN;
  }
  return FP_NORMAL;
}

int CountLeadingZeros(uint64_t value, int width) {
  DCHECK(base::bits::IsPowerOfTwo(width) && (width <= 64));
  if (value == 0) {
    return width;
  }
  return base::bits::CountLeadingZeros64(value << (64 - width));
}

int CountLeadingSignBits(int64_t value, int width) {
  DCHECK(base::bits::IsPowerOfTwo(width) && (width <= 64));
  if (value >= 0) {
    return CountLeadingZeros(value, width) - 1;
  } else {
    return CountLeadingZeros(~value, width) - 1;
  }
}

int CountTrailingZeros(uint64_t value, int width) {
  DCHECK((width == 32) || (width == 64));
  if (width == 64) {
    return static_cast<int>(base::bits::CountTrailingZeros64(value));
  }
  return static_cast<int>(base::bits::CountTrailingZeros32(
      static_cast<uint32_t>(value & 0xFFFFFFFFF)));
}

int CountSetBits(uint64_t value, int width) {
  DCHECK((width == 32) || (width == 64));
  if (width == 64) {
    return static_cast<int>(base::bits::CountPopulation(value));
  }
  return static_cast<int>(
      base::bits::CountPopulation(static_cast<uint32_t>(value & 0xFFFFFFFFF)));
}

int LowestSetBitPosition(uint64_t value) {
  DCHECK_NE(value, 0U);
  return CountTrailingZeros(value, 64) + 1;
}

int HighestSetBitPosition(uint64_t value) {
  DCHECK_NE(value, 0U);
  return 63 - CountLeadingZeros(value, 64);
}

uint64_t LargestPowerOf2Divisor(uint64_t value) {
  return value & (-(int64_t)value);
}

int MaskToBit(uint64_t mask) {
  DCHECK_EQ(CountSetBits(mask, 64), 1);
  return CountTrailingZeros(mask, 64);
}

#undef __

}  // namespace internal
}  // namespace v8

#endif  // V8_TARGET_ARCH_ARM64
