Line data Source code
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.
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 :
31 232 : uint32_t get_bits() const { return bit_pattern_; }
32 :
33 : float get_scalar() const { return bit_cast<float>(bit_pattern_); }
34 :
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.
43 : uint32_t* get_bits_address() { return &bit_pattern_; }
44 :
45 : static constexpr Float32 FromBits(uint32_t bits) { return Float32(bits); }
46 :
47 : private:
48 : uint32_t bit_pattern_ = 0;
49 :
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.
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 :
71 324 : uint64_t get_bits() const { return bit_pattern_; }
72 : double get_scalar() const { return bit_cast<double>(bit_pattern_); }
73 14251 : bool is_hole_nan() const { return bit_pattern_ == kHoleNanInt64; }
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.
82 : uint64_t* get_bits_address() { return &bit_pattern_; }
83 :
84 : static constexpr Float64 FromBits(uint64_t bits) { return Float64(bits); }
85 :
86 : private:
87 : uint64_t bit_pattern_ = 0;
88 :
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_
|