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 // === Serialization support ===
139 size_t bytesToSerialize() const {
140 return sizeof(llvm::fltSemantics *) +
141 (APFloat::semanticsSizeInBits(F.getSemantics()) / 8);
142 }
143
144 void serialize(std::byte *Buff) const {
145 // Semantics followed by an APInt.
146 *reinterpret_cast<const llvm::fltSemantics **>(Buff) = &F.getSemantics();
147
148 llvm::APInt API = F.bitcastToAPInt();
149 llvm::StoreIntToMemory(API, (uint8_t *)(Buff + sizeof(void *)),
150 bitWidth() / 8);
151 }
152
153 static Floating deserialize(const std::byte *Buff) {
154 const llvm::fltSemantics *Sem;
155 std::memcpy((void *)&Sem, Buff, sizeof(void *));
156 return bitcastFromMemory(Buff + sizeof(void *), *Sem);
157 }
158
159 static Floating abs(const Floating &F) {
160 APFloat V = F.F;
161 if (V.isNegative())
162 V.changeSign();
163 return Floating(V);
164 }
165
166 // -------
167
168 static APFloat::opStatus add(const Floating &A, const Floating &B,
169 llvm::RoundingMode RM, Floating *R) {
170 *R = Floating(A.F);
171 return R->F.add(B.F, RM);
172 }
173
174 static APFloat::opStatus increment(const Floating &A, llvm::RoundingMode RM,
175 Floating *R) {
176 APFloat One(A.F.getSemantics(), 1);
177 *R = Floating(A.F);
178 return R->F.add(One, RM);
179 }
180
181 static APFloat::opStatus sub(const Floating &A, const Floating &B,
182 llvm::RoundingMode RM, Floating *R) {
183 *R = Floating(A.F);
184 return R->F.subtract(B.F, RM);
185 }
186
187 static APFloat::opStatus decrement(const Floating &A, llvm::RoundingMode RM,
188 Floating *R) {
189 APFloat One(A.F.getSemantics(), 1);
190 *R = Floating(A.F);
191 return R->F.subtract(One, RM);
192 }
193
194 static APFloat::opStatus mul(const Floating &A, const Floating &B,
195 llvm::RoundingMode RM, Floating *R) {
196 *R = Floating(A.F);
197 return R->F.multiply(B.F, RM);
198 }
199
200 static APFloat::opStatus div(const Floating &A, const Floating &B,
201 llvm::RoundingMode RM, Floating *R) {
202 *R = Floating(A.F);
203 return R->F.divide(B.F, RM);
204 }
205
206 static bool neg(const Floating &A, Floating *R) {
207 *R = -A;
208 return false;
209 }
210};
211
212llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Floating F);
213Floating getSwappedBytes(Floating F);
214
215} // namespace interp
216} // namespace clang
217
218#endif
#define V(N, I)
Definition: ASTContext.h:3341
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:187
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:200
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:153
void serialize(std::byte *Buff) const
Definition: Floating.h:144
static APFloat::opStatus sub(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:181
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:174
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:139
static APFloat::opStatus add(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:168
static APFloat::opStatus mul(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:194
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:206
bool isFinite() const
Definition: Floating.h:98
static APFloat::opStatus decrement(const Floating &A, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:187
Floating(const APFloat &F)
Definition: Floating.h:34
bool isDenormal() const
Definition: Floating.h:100
static Floating abs(const Floating &F)
Definition: Floating.h:159
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
llvm::APFloat APFloat
Definition: Floating.h:23
Floating getSwappedBytes(Floating F)
Definition: Floating.cpp:19
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const Boolean &B)
Definition: Boolean.h:151
llvm::APSInt APSInt
Definition: Floating.h:24
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.