FLANG
real-value.h
1//===-- include/flang/Evaluate/real-value.h ---------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef FORTRAN_EVALUATE_REAL_VALUE_H_
10#define FORTRAN_EVALUATE_REAL_VALUE_H_
11
12#include "flang/Evaluate/integer-value.h"
13#include "flang/Evaluate/object-sizes.h"
14#include "flang/Evaluate/target.h"
15#include "llvm/Support/Compiler.h"
16
17// Some environments, viz. glibc 2.17 and *BSD, allow the macro HUGE
18// to leak out of <math.h>.
19#undef HUGE
20
21namespace Fortran::evaluate::value {
22class RealValueImpl;
23
31class RealValue {
32public:
33 using Word = IntegerValue;
34
35 RealValue();
36 ~RealValue();
37 RealValue(const RealValue &);
38 RealValue(RealValue &&);
39 RealValue &operator=(const RealValue &);
40 RealValue &operator=(RealValue &&);
41
42 RealValue(int kind, const RealValue &v) : RealValue(v) {
43 CHECK(kind == v.kind());
44 }
45 RealValue(int kind, RealValue &&v) : RealValue(std::move(v)) {
46 CHECK(kind == v.kind());
47 }
48
50 RealValue(int kind, const Word &w);
51
56 RealValue(int kind, double x);
57
60 static RealValue Zero(int kind);
61
63 static RealValue NegativeZero(int kind);
64
65 static RealValue Infinity(int kind, bool negative = false);
66
67 void print(llvm::raw_ostream &os) const;
68
69#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
70 LLVM_DUMP_METHOD void dump() const;
71#endif
72
75 bool IsNull() const;
76
78 int kind() const;
79
80 int bits() const { return bits(kind()); }
81 static constexpr int bits(int kind) { return bytesStored(kind) * 8; }
82
84 std::size_t bytesStored() const { return bytesStored(kind()); }
85 static constexpr std::size_t bytesStored(int kind) {
86 switch (kind) {
87 case 3:
88 return 2;
89 case 10:
90 return 16;
91 default:
92 return kind;
93 }
94 }
95
96 bool operator==(const RealValue &y) const;
97 bool operator!=(const RealValue &y) const { return !operator==(y); }
98
99 bool IsNegative() const;
100
101 bool IsNotANumber() const;
102
103 bool IsSignalingNaN() const;
104
105 bool IsInfinite() const;
106
107 bool IsFinite() const;
108
109 bool IsZero() const;
110
111 bool IsNormal() const;
112
113 RealValue ABS() const;
114
115 RealValue SetSign(bool toNegative) const;
116
117 RealValue SIGN(const RealValue &x) const;
118
119 RealValue Negate() const;
120
121 Relation Compare(const RealValue &y) const;
122
123 ValueWithRealFlags<RealValue> Add(const RealValue &y,
124 Rounding rounding = TargetCharacteristics::defaultRounding) const;
125
126 ValueWithRealFlags<RealValue> Subtract(const RealValue &y,
127 Rounding rounding = TargetCharacteristics::defaultRounding) const;
128
129 ValueWithRealFlags<RealValue> Multiply(const RealValue &y,
130 Rounding rounding = TargetCharacteristics::defaultRounding) const;
131
132 ValueWithRealFlags<RealValue> Divide(const RealValue &y,
133 Rounding rounding = TargetCharacteristics::defaultRounding) const;
134
135 ValueWithRealFlags<RealValue> SQRT(
136 Rounding rounding = TargetCharacteristics::defaultRounding) const;
137
139 ValueWithRealFlags<RealValue> NEAREST(bool upward) const;
140
143 ValueWithRealFlags<RealValue> HYPOT(const RealValue &y,
144 Rounding rounding = TargetCharacteristics::defaultRounding) const;
145
147 ValueWithRealFlags<RealValue> DIM(const RealValue &y,
148 Rounding rounding = TargetCharacteristics::defaultRounding) const;
149
151 ValueWithRealFlags<RealValue> MOD(const RealValue &y,
152 Rounding rounding = TargetCharacteristics::defaultRounding) const;
153
155 ValueWithRealFlags<RealValue> MODULO(const RealValue &y,
156 Rounding rounding = TargetCharacteristics::defaultRounding) const;
157
158 ValueWithRealFlags<RealValue> KahanSummation(const RealValue &y,
159 RealValue &correction,
160 Rounding rounding = TargetCharacteristics::defaultRounding) const;
161
162 IntegerValue EXPONENT() const;
163
164 static RealValue EPSILON(int kind);
165
166 static RealValue HUGE(int kind);
167
168 static RealValue TINY(int kind);
169
170 static int DIGITS(int kind);
171
172 static int PRECISION(int kind);
173
174 static int RANGE(int kind);
175
176 static int MAXEXPONENT(int kind);
177
178 static int MINEXPONENT(int kind);
179
180 RealValue RRSPACING() const;
181
182 RealValue SPACING() const;
183
184 RealValue SET_EXPONENT(std::int64_t e) const;
185
186 RealValue FRACTION() const;
187
189 ValueWithRealFlags<RealValue> SCALE(const IntegerValue &by,
190 Rounding rounding = TargetCharacteristics::defaultRounding) const;
191
192 RealValue FlushSubnormalToZero() const;
193
194 // TODO: Configurable NotANumber representations
195 static RealValue NotANumber(int kind);
196
197 static ValueWithRealFlags<RealValue> FromInteger(int kind,
198 const IntegerValue &n, bool isUnsigned = false,
199 Rounding rounding = TargetCharacteristics::defaultRounding);
200
202 ValueWithRealFlags<RealValue> ToWholeNumber(
203 common::RoundingMode mode = common::RoundingMode::ToZero) const;
204
206 ValueWithRealFlags<IntegerValue> ToInteger(
207 common::RoundingMode mode = common::RoundingMode::ToZero,
208 int toBits = 0) const;
209
210 static ValueWithRealFlags<RealValue> Convert(int kind, const RealValue &from,
211 Rounding rounding = TargetCharacteristics::defaultRounding);
212
213 Word RawBits() const;
214
216 int Exponent() const;
217
218 static ValueWithRealFlags<RealValue> Read(int kind, const char *&pp,
219 Rounding rounding = TargetCharacteristics::defaultRounding);
220
221 std::string DumpHexadecimal() const;
222
225 llvm::raw_ostream &AsFortran(
226 llvm::raw_ostream &o, int kind, bool minimal = false) const;
227
228 static RealValue FromRawBytes(
229 int kind, const void *raw, std::size_t expectedSize);
230
231 void StoreRawBytes(void *dst, size_t size, bool *changed = nullptr) const;
232
233private:
234 static RealValue FromImpl(const RealValueImpl &x);
235 static RealValue FromImpl(RealValueImpl &&x);
236 static ValueWithRealFlags<RealValue> FromImpl(
237 const ValueWithRealFlags<RealValueImpl> &x);
238 static ValueWithRealFlags<RealValue> FromImpl(
239 ValueWithRealFlags<RealValueImpl> &&x);
240
241 RealValueImpl &impl() { return *reinterpret_cast<RealValueImpl *>(this); }
242 const RealValueImpl &impl() const {
243 return *reinterpret_cast<const RealValueImpl *>(this);
244 }
245
246 [[maybe_unused]] alignas(
247 detail::kRealObjectAlign) char opaque_[detail::kRealObjectSize];
248};
249
250} // namespace Fortran::evaluate::value
251
252namespace llvm {
254inline raw_ostream &operator<<(
255 raw_ostream &os, const Fortran::evaluate::value::RealValue &v) {
256 v.print(os);
257 return os;
258}
259} // namespace llvm
260
261#endif // FORTRAN_EVALUATE_REAL_VALUE_H_
Definition integer-value.h:34
Definition real-value-impl.h:29
ValueWithRealFlags< RealValue > DIM(const RealValue &y, Rounding rounding=TargetCharacteristics::defaultRounding) const
DIM(X,Y) = MAX(X-Y, 0)
Definition real-value.cpp:129
int Exponent() const
Extracts "raw" biased exponent field.
Definition real-value.cpp:218
ValueWithRealFlags< RealValue > ToWholeNumber(common::RoundingMode mode=common::RoundingMode::ToZero) const
Conversion to integer in the same real format (AINT(), ANINT())
Definition real-value.cpp:202
ValueWithRealFlags< RealValue > HYPOT(const RealValue &y, Rounding rounding=TargetCharacteristics::defaultRounding) const
Definition real-value.cpp:125
ValueWithRealFlags< RealValue > SCALE(const IntegerValue &by, Rounding rounding=TargetCharacteristics::defaultRounding) const
SCALE(); also known as IEEE_SCALB and (in IEEE-754 '08) ScaleB.
Definition real-value.cpp:184
llvm::raw_ostream & AsFortran(llvm::raw_ostream &o, int kind, bool minimal=false) const
Definition real-value.cpp:229
ValueWithRealFlags< RealValue > MOD(const RealValue &y, Rounding rounding=TargetCharacteristics::defaultRounding) const
MOD(x,y) = x - AINT(x/y)*y (in the standard)
Definition real-value.cpp:133
ValueWithRealFlags< RealValue > MODULO(const RealValue &y, Rounding rounding=TargetCharacteristics::defaultRounding) const
MODULO(x,y) = x - FLOOR(x/y)*y (in the standard)
Definition real-value.cpp:137
int kind() const
The kind of the value currently stored.
Definition real-value.cpp:61
bool IsNull() const
Definition real-value.cpp:59
std::size_t bytesStored() const
Number of bytes accessed by FromRawBytes/StoreRawBytes.
Definition real-value.h:84
static RealValue NegativeZero(int kind)
Creates a floating-point with value -0.0 of a given kind.
Definition real-value.cpp:51
ValueWithRealFlags< RealValue > NEAREST(bool upward) const
NEAREST(), IEEE_NEXT_AFTER(), IEEE_NEXT_UP(), and IEEE_NEXT_DOWN()
Definition real-value.cpp:122
static RealValue Zero(int kind)
Definition real-value.cpp:47
ValueWithRealFlags< IntegerValue > ToInteger(common::RoundingMode mode=common::RoundingMode::ToZero, int toBits=0) const
Conversion to an integer (INT(), NINT(), FLOOR(), CEILING())
Definition real-value.cpp:206
Definition target-rounding.h:18