1 // Copyright 2017 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 #ifndef V8_BOXED_FLOAT_H_ 6 #define V8_BOXED_FLOAT_H_ 7 8 #include <cmath> 9 #include "src/base/macros.h" 10 #include "src/globals.h" 11 12 namespace v8 { 13 namespace internal { 14 15 // TODO(ahaas): Make these classes with the one in double.h 16 17 // Safety wrapper for a 32-bit floating-point value to make sure we don't lose 18 // the exact bit pattern during deoptimization when passing this value. 19 class Float32 { 20 public: 21 Float32() = default; 22 23 // This constructor does not guarantee that bit pattern of the input value 24 // is preserved if the input is a NaN. Float32(float value)25 explicit Float32(float value) : bit_pattern_(bit_cast<uint32_t>(value)) { 26 // Check that the provided value is not a NaN, because the bit pattern of a 27 // NaN may be changed by a bit_cast, e.g. for signalling NaNs on ia32. 28 DCHECK(!std::isnan(value)); 29 } 30 get_bits()31 uint32_t get_bits() const { return bit_pattern_; } 32 get_scalar()33 float get_scalar() const { return bit_cast<float>(bit_pattern_); } 34 is_nan()35 bool is_nan() const { 36 // Even though {get_scalar()} might flip the quiet NaN bit, it's ok here, 37 // because this does not change the is_nan property. 38 return std::isnan(get_scalar()); 39 } 40 41 // Return a pointer to the field storing the bit pattern. Used in code 42 // generation tests to store generated values there directly. get_bits_address()43 uint32_t* get_bits_address() { return &bit_pattern_; } 44 FromBits(uint32_t bits)45 static constexpr Float32 FromBits(uint32_t bits) { return Float32(bits); } 46 47 private: 48 uint32_t bit_pattern_ = 0; 49 Float32(uint32_t bit_pattern)50 explicit constexpr Float32(uint32_t bit_pattern) 51 : bit_pattern_(bit_pattern) {} 52 }; 53 54 ASSERT_TRIVIALLY_COPYABLE(Float32); 55 56 // Safety wrapper for a 64-bit floating-point value to make sure we don't lose 57 // the exact bit pattern during deoptimization when passing this value. 58 // TODO(ahaas): Unify this class with Double in double.h 59 class Float64 { 60 public: 61 Float64() = default; 62 63 // This constructor does not guarantee that bit pattern of the input value 64 // is preserved if the input is a NaN. Float64(double value)65 explicit Float64(double value) : bit_pattern_(bit_cast<uint64_t>(value)) { 66 // Check that the provided value is not a NaN, because the bit pattern of a 67 // NaN may be changed by a bit_cast, e.g. for signalling NaNs on ia32. 68 DCHECK(!std::isnan(value)); 69 } 70 get_bits()71 uint64_t get_bits() const { return bit_pattern_; } get_scalar()72 double get_scalar() const { return bit_cast<double>(bit_pattern_); } is_hole_nan()73 bool is_hole_nan() const { return bit_pattern_ == kHoleNanInt64; } is_nan()74 bool is_nan() const { 75 // Even though {get_scalar()} might flip the quiet NaN bit, it's ok here, 76 // because this does not change the is_nan property. 77 return std::isnan(get_scalar()); 78 } 79 80 // Return a pointer to the field storing the bit pattern. Used in code 81 // generation tests to store generated values there directly. get_bits_address()82 uint64_t* get_bits_address() { return &bit_pattern_; } 83 FromBits(uint64_t bits)84 static constexpr Float64 FromBits(uint64_t bits) { return Float64(bits); } 85 86 private: 87 uint64_t bit_pattern_ = 0; 88 Float64(uint64_t bit_pattern)89 explicit constexpr Float64(uint64_t bit_pattern) 90 : bit_pattern_(bit_pattern) {} 91 }; 92 93 ASSERT_TRIVIALLY_COPYABLE(Float64); 94 95 } // namespace internal 96 } // namespace v8 97 98 #endif // V8_BOXED_FLOAT_H_ 99