// Copyright 2014 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.

#include "src/base/bits.h"

#include <limits>

#include "src/base/logging.h"
#include "src/base/safe_math.h"

namespace v8 {
namespace base {
namespace bits {

uint32_t RoundUpToPowerOfTwo32(uint32_t value) {
  DCHECK_LE(value, uint32_t{1} << 31);
  if (value) --value;
// Use computation based on leading zeros if we have compiler support for that.
#if V8_HAS_BUILTIN_CLZ || V8_CC_MSVC
  return 1u << (32 - CountLeadingZeros32(value));
#else
  value |= value >> 1;
  value |= value >> 2;
  value |= value >> 4;
  value |= value >> 8;
  value |= value >> 16;
  return value + 1;
#endif
}

uint64_t RoundUpToPowerOfTwo64(uint64_t value) {
  DCHECK_LE(value, uint64_t{1} << 63);
  if (value) --value;
// Use computation based on leading zeros if we have compiler support for that.
#if V8_HAS_BUILTIN_CLZ
  return uint64_t{1} << (64 - CountLeadingZeros64(value));
#else
  value |= value >> 1;
  value |= value >> 2;
  value |= value >> 4;
  value |= value >> 8;
  value |= value >> 16;
  value |= value >> 32;
  return value + 1;
#endif
}


int32_t SignedMulHigh32(int32_t lhs, int32_t rhs) {
  int64_t const value = static_cast<int64_t>(lhs) * static_cast<int64_t>(rhs);
  return bit_cast<int32_t, uint32_t>(bit_cast<uint64_t>(value) >> 32u);
}


int32_t SignedMulHighAndAdd32(int32_t lhs, int32_t rhs, int32_t acc) {
  return bit_cast<int32_t>(bit_cast<uint32_t>(acc) +
                           bit_cast<uint32_t>(SignedMulHigh32(lhs, rhs)));
}


int32_t SignedDiv32(int32_t lhs, int32_t rhs) {
  if (rhs == 0) return 0;
  if (rhs == -1) return -lhs;
  return lhs / rhs;
}


int32_t SignedMod32(int32_t lhs, int32_t rhs) {
  if (rhs == 0 || rhs == -1) return 0;
  return lhs % rhs;
}


int64_t FromCheckedNumeric(const internal::CheckedNumeric<int64_t> value) {
  if (value.IsValid())
    return value.ValueUnsafe();

  // We could return max/min but we don't really expose what the maximum delta
  // is. Instead, return max/(-max), which is something that clients can reason
  // about.
  // TODO(rvargas) crbug.com/332611: don't use internal values.
  int64_t limit = std::numeric_limits<int64_t>::max();
  if (value.validity() == internal::RANGE_UNDERFLOW)
    limit = -limit;
  return value.ValueOrDefault(limit);
}


int64_t SignedSaturatedAdd64(int64_t lhs, int64_t rhs) {
  internal::CheckedNumeric<int64_t> rv(lhs);
  rv += rhs;
  return FromCheckedNumeric(rv);
}


int64_t SignedSaturatedSub64(int64_t lhs, int64_t rhs) {
  internal::CheckedNumeric<int64_t> rv(lhs);
  rv -= rhs;
  return FromCheckedNumeric(rv);
}

bool SignedMulOverflow32(int32_t lhs, int32_t rhs, int32_t* val) {
  internal::CheckedNumeric<int32_t> rv(lhs);
  rv *= rhs;
  int32_t limit = std::numeric_limits<int32_t>::max();
  *val = rv.ValueOrDefault(limit);
  return !rv.IsValid();
}

bool SignedMulOverflow64(int64_t lhs, int64_t rhs, int64_t* val) {
  internal::CheckedNumeric<int64_t> rv(lhs);
  rv *= rhs;
  int64_t limit = std::numeric_limits<int64_t>::max();
  *val = rv.ValueOrDefault(limit);
  return !rv.IsValid();
}

}  // namespace bits
}  // namespace base
}  // namespace v8
