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

#ifndef V8_UTILS_BOXED_FLOAT_H_
#define V8_UTILS_BOXED_FLOAT_H_

#include <cmath>
#include "src/base/macros.h"
#include "src/common/globals.h"

namespace v8 {
namespace internal {

// TODO(ahaas): Make these classes with the one in double.h

// Safety wrapper for a 32-bit floating-point value to make sure we don't lose
// the exact bit pattern during deoptimization when passing this value.
class Float32 {
 public:
  Float32() = default;

  // This constructor does not guarantee that bit pattern of the input value
  // is preserved if the input is a NaN.
  explicit Float32(float value) : bit_pattern_(bit_cast<uint32_t>(value)) {
    // Check that the provided value is not a NaN, because the bit pattern of a
    // NaN may be changed by a bit_cast, e.g. for signalling NaNs on ia32.
    DCHECK(!std::isnan(value));
  }

  uint32_t get_bits() const { return bit_pattern_; }

  float get_scalar() const { return bit_cast<float>(bit_pattern_); }

  bool is_nan() const {
    // Even though {get_scalar()} might flip the quiet NaN bit, it's ok here,
    // because this does not change the is_nan property.
    return std::isnan(get_scalar());
  }

  // Return a pointer to the field storing the bit pattern. Used in code
  // generation tests to store generated values there directly.
  uint32_t* get_bits_address() { return &bit_pattern_; }

  static constexpr Float32 FromBits(uint32_t bits) { return Float32(bits); }

 private:
  uint32_t bit_pattern_ = 0;

  explicit constexpr Float32(uint32_t bit_pattern)
      : bit_pattern_(bit_pattern) {}
};

ASSERT_TRIVIALLY_COPYABLE(Float32);

// Safety wrapper for a 64-bit floating-point value to make sure we don't lose
// the exact bit pattern during deoptimization when passing this value.
// TODO(ahaas): Unify this class with Double in double.h
class Float64 {
 public:
  Float64() = default;

  // This constructor does not guarantee that bit pattern of the input value
  // is preserved if the input is a NaN.
  explicit Float64(double value) : bit_pattern_(bit_cast<uint64_t>(value)) {
    // Check that the provided value is not a NaN, because the bit pattern of a
    // NaN may be changed by a bit_cast, e.g. for signalling NaNs on ia32.
    DCHECK(!std::isnan(value));
  }

  uint64_t get_bits() const { return bit_pattern_; }
  double get_scalar() const { return bit_cast<double>(bit_pattern_); }
  bool is_hole_nan() const { return bit_pattern_ == kHoleNanInt64; }
  bool is_nan() const {
    // Even though {get_scalar()} might flip the quiet NaN bit, it's ok here,
    // because this does not change the is_nan property.
    return std::isnan(get_scalar());
  }

  // Return a pointer to the field storing the bit pattern. Used in code
  // generation tests to store generated values there directly.
  uint64_t* get_bits_address() { return &bit_pattern_; }

  static constexpr Float64 FromBits(uint64_t bits) { return Float64(bits); }

 private:
  uint64_t bit_pattern_ = 0;

  explicit constexpr Float64(uint64_t bit_pattern)
      : bit_pattern_(bit_pattern) {}
};

ASSERT_TRIVIALLY_COPYABLE(Float64);

}  // namespace internal
}  // namespace v8

#endif  // V8_UTILS_BOXED_FLOAT_H_
