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