clang 20.0.0git
Floating.h
Go to the documentation of this file.
1//===--- Floating.h - Types for the constexpr VM ----------------*- 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// Defines the VM types and helpers operating on types.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_INTERP_FLOATING_H
14#define LLVM_CLANG_AST_INTERP_FLOATING_H
15
16#include "Primitives.h"
17#include "clang/AST/APValue.h"
18#include "llvm/ADT/APFloat.h"
19
20namespace clang {
21namespace interp {
22
23using APFloat = llvm::APFloat;
24using APSInt = llvm::APSInt;
25
26class Floating final {
27private:
28 // The underlying value storage.
29 APFloat F;
30
31public:
32 /// Zero-initializes a Floating.
33 Floating() : F(0.0f) {}
34 Floating(const APFloat &F) : F(F) {}
35
36 // Static constructors for special floating point values.
37 static Floating getInf(const llvm::fltSemantics &Sem) {
38 return Floating(APFloat::getInf(Sem));
39 }
40 const APFloat &getAPFloat() const { return F; }
41
42 bool operator<(Floating RHS) const { return F < RHS.F; }
43 bool operator>(Floating RHS) const { return F > RHS.F; }
44 bool operator<=(Floating RHS) const { return F <= RHS.F; }
45 bool operator>=(Floating RHS) const { return F >= RHS.F; }
46 bool operator==(Floating RHS) const { return F == RHS.F; }
47 bool operator!=(Floating RHS) const { return F != RHS.F; }
48 Floating operator-() const { return Floating(-F); }
49
50 APFloat::opStatus convertToInteger(APSInt &Result) const {
51 bool IsExact;
52 return F.convertToInteger(Result, llvm::APFloat::rmTowardZero, &IsExact);
53 }
54
55 Floating toSemantics(const llvm::fltSemantics *Sem,
56 llvm::RoundingMode RM) const {
57 APFloat Copy = F;
58 bool LosesInfo;
59 Copy.convert(*Sem, RM, &LosesInfo);
60 (void)LosesInfo;
61 return Floating(Copy);
62 }
63
64 /// Convert this Floating to one with the same semantics as \Other.
65 Floating toSemantics(const Floating &Other, llvm::RoundingMode RM) const {
66 return toSemantics(&Other.F.getSemantics(), RM);
67 }
68
69 APSInt toAPSInt(unsigned NumBits = 0) const {
70 return APSInt(F.bitcastToAPInt());
71 }
72 APValue toAPValue(const ASTContext &) const { return APValue(F); }
73 void print(llvm::raw_ostream &OS) const {
74 // Can't use APFloat::print() since it appends a newline.
76 F.toString(Buffer);
77 OS << Buffer;
78 }
79 std::string toDiagnosticString(const ASTContext &Ctx) const {
80 std::string NameStr;
81 llvm::raw_string_ostream OS(NameStr);
82 print(OS);
83 return NameStr;
84 }
85
86 unsigned bitWidth() const { return F.semanticsSizeInBits(F.getSemantics()); }
87
88 bool isSigned() const { return true; }
89 bool isNegative() const { return F.isNegative(); }
90 bool isPositive() const { return !F.isNegative(); }
91 bool isZero() const { return F.isZero(); }
92 bool isNonZero() const { return F.isNonZero(); }
93 bool isMin() const { return F.isSmallest(); }
94 bool isMinusOne() const { return F.isExactlyValue(-1.0); }
95 bool isNan() const { return F.isNaN(); }
96 bool isSignaling() const { return F.isSignaling(); }
97 bool isInf() const { return F.isInfinity(); }
98 bool isFinite() const { return F.isFinite(); }
99 bool isNormal() const { return F.isNormal(); }
100 bool isDenormal() const { return F.isDenormal(); }
101 llvm::FPClassTest classify() const { return F.classify(); }
102 APFloat::fltCategory getCategory() const { return F.getCategory(); }
103
105 llvm::APFloatBase::cmpResult CmpRes = F.compare(RHS.F);
106 switch (CmpRes) {
107 case llvm::APFloatBase::cmpLessThan:
109 case llvm::APFloatBase::cmpEqual:
111 case llvm::APFloatBase::cmpGreaterThan:
113 case llvm::APFloatBase::cmpUnordered:
115 }
116 llvm_unreachable("Inavlid cmpResult value");
117 }
118
119 static APFloat::opStatus fromIntegral(APSInt Val,
120 const llvm::fltSemantics &Sem,
121 llvm::RoundingMode RM,
122 Floating &Result) {
123 APFloat F = APFloat(Sem);
124 APFloat::opStatus Status = F.convertFromAPInt(Val, Val.isSigned(), RM);
125 Result = Floating(F);
126 return Status;
127 }
128
129 static Floating bitcastFromMemory(const std::byte *Buff,
130 const llvm::fltSemantics &Sem) {
131 size_t Size = APFloat::semanticsSizeInBits(Sem);
132 llvm::APInt API(Size, true);
133 llvm::LoadIntFromMemory(API, (const uint8_t *)Buff, Size / 8);
134
135 return Floating(APFloat(Sem, API));
136 }
137
138 void bitcastToMemory(std::byte *Buff) const {
139 llvm::APInt API = F.bitcastToAPInt();
140 llvm::StoreIntToMemory(API, (uint8_t *)Buff, bitWidth() / 8);
141 }
142
143 // === Serialization support ===
144 size_t bytesToSerialize() const {
145 return sizeof(llvm::fltSemantics *) +
146 (APFloat::semanticsSizeInBits(F.getSemantics()) / 8);
147 }
148
149 void serialize(std::byte *Buff) const {
150 // Semantics followed by an APInt.
151 *reinterpret_cast<const llvm::fltSemantics **>(Buff) = &F.getSemantics();
152
153 llvm::APInt API = F.bitcastToAPInt();
154 llvm::StoreIntToMemory(API, (uint8_t *)(Buff + sizeof(void *)),
155 bitWidth() / 8);
156 }
157
158 static Floating deserialize(const std::byte *Buff) {
159 const llvm::fltSemantics *Sem;
160 std::memcpy((void *)&Sem, Buff, sizeof(void *));
161 return bitcastFromMemory(Buff + sizeof(void *), *Sem);
162 }
163
164 static Floating abs(const Floating &F) {
165 APFloat V = F.F;
166 if (V.isNegative())
167 V.changeSign();
168 return Floating(V);
169 }
170
171 // -------
172
173 static APFloat::opStatus add(const Floating &A, const Floating &B,
174 llvm::RoundingMode RM, Floating *R) {
175 *R = Floating(A.F);
176 return R->F.add(B.F, RM);
177 }
178
179 static APFloat::opStatus increment(const Floating &A, llvm::RoundingMode RM,
180 Floating *R) {
181 APFloat One(A.F.getSemantics(), 1);
182 *R = Floating(A.F);
183 return R->F.add(One, RM);
184 }
185
186 static APFloat::opStatus sub(const Floating &A, const Floating &B,
187 llvm::RoundingMode RM, Floating *R) {
188 *R = Floating(A.F);
189 return R->F.subtract(B.F, RM);
190 }
191
192 static APFloat::opStatus decrement(const Floating &A, llvm::RoundingMode RM,
193 Floating *R) {
194 APFloat One(A.F.getSemantics(), 1);
195 *R = Floating(A.F);
196 return R->F.subtract(One, RM);
197 }
198
199 static APFloat::opStatus mul(const Floating &A, const Floating &B,
200 llvm::RoundingMode RM, Floating *R) {
201 *R = Floating(A.F);
202 return R->F.multiply(B.F, RM);
203 }
204
205 static APFloat::opStatus div(const Floating &A, const Floating &B,
206 llvm::RoundingMode RM, Floating *R) {
207 *R = Floating(A.F);
208 return R->F.divide(B.F, RM);
209 }
210
211 static bool neg(const Floating &A, Floating *R) {
212 *R = -A;
213 return false;
214 }
215};
216
217llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Floating F);
218Floating getSwappedBytes(Floating F);
219
220} // namespace interp
221} // namespace clang
222
223#endif
#define V(N, I)
Definition: ASTContext.h:3443
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
bool operator<(Floating RHS) const
Definition: Floating.h:42
static APFloat::opStatus div(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:205
bool isInf() const
Definition: Floating.h:97
Floating operator-() const
Definition: Floating.h:48
static Floating bitcastFromMemory(const std::byte *Buff, const llvm::fltSemantics &Sem)
Definition: Floating.h:129
void print(llvm::raw_ostream &OS) const
Definition: Floating.h:73
APSInt toAPSInt(unsigned NumBits=0) const
Definition: Floating.h:69
static Floating deserialize(const std::byte *Buff)
Definition: Floating.h:158
void serialize(std::byte *Buff) const
Definition: Floating.h:149
static APFloat::opStatus sub(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:186
const APFloat & getAPFloat() const
Definition: Floating.h:40
llvm::FPClassTest classify() const
Definition: Floating.h:101
Floating toSemantics(const Floating &Other, llvm::RoundingMode RM) const
Convert this Floating to one with the same semantics as \Other.
Definition: Floating.h:65
bool operator>(Floating RHS) const
Definition: Floating.h:43
bool isSignaling() const
Definition: Floating.h:96
Floating()
Zero-initializes a Floating.
Definition: Floating.h:33
unsigned bitWidth() const
Definition: Floating.h:86
bool isNormal() const
Definition: Floating.h:99
ComparisonCategoryResult compare(const Floating &RHS) const
Definition: Floating.h:104
static APFloat::opStatus increment(const Floating &A, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:179
bool operator>=(Floating RHS) const
Definition: Floating.h:45
bool isSigned() const
Definition: Floating.h:88
bool operator<=(Floating RHS) const
Definition: Floating.h:44
static APFloat::opStatus fromIntegral(APSInt Val, const llvm::fltSemantics &Sem, llvm::RoundingMode RM, Floating &Result)
Definition: Floating.h:119
bool isMin() const
Definition: Floating.h:93
Floating toSemantics(const llvm::fltSemantics *Sem, llvm::RoundingMode RM) const
Definition: Floating.h:55
size_t bytesToSerialize() const
Definition: Floating.h:144
static APFloat::opStatus add(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:173
static APFloat::opStatus mul(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:199
bool isNan() const
Definition: Floating.h:95
bool isNonZero() const
Definition: Floating.h:92
std::string toDiagnosticString(const ASTContext &Ctx) const
Definition: Floating.h:79
bool operator!=(Floating RHS) const
Definition: Floating.h:47
bool isZero() const
Definition: Floating.h:91
bool isNegative() const
Definition: Floating.h:89
bool isPositive() const
Definition: Floating.h:90
static Floating getInf(const llvm::fltSemantics &Sem)
Definition: Floating.h:37
bool operator==(Floating RHS) const
Definition: Floating.h:46
static bool neg(const Floating &A, Floating *R)
Definition: Floating.h:211
bool isFinite() const
Definition: Floating.h:98
static APFloat::opStatus decrement(const Floating &A, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:192
Floating(const APFloat &F)
Definition: Floating.h:34
bool isDenormal() const
Definition: Floating.h:100
static Floating abs(const Floating &F)
Definition: Floating.h:164
bool isMinusOne() const
Definition: Floating.h:94
APFloat::opStatus convertToInteger(APSInt &Result) const
Definition: Floating.h:50
APValue toAPValue(const ASTContext &) const
Definition: Floating.h:72
APFloat::fltCategory getCategory() const
Definition: Floating.h:102
void bitcastToMemory(std::byte *Buff) const
Definition: Floating.h:138
llvm::APFloat APFloat
Definition: Floating.h:23
FixedPoint getSwappedBytes(FixedPoint F)
Definition: FixedPoint.h:162
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const Boolean &B)
Definition: Boolean.h:160
llvm::APSInt APSInt
Definition: FixedPoint.h:20
The JSON file list parser is used to communicate input to InstallAPI.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Result
The result type of a method or function.
@ Other
Other implicit parameter.