clang 18.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 { 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
80 unsigned bitWidth() const { return F.semanticsSizeInBits(F.getSemantics()); }
81
82 bool isSigned() const { return true; }
83 bool isNegative() const { return F.isNegative(); }
84 bool isPositive() const { return !F.isNegative(); }
85 bool isZero() const { return F.isZero(); }
86 bool isNonZero() const { return F.isNonZero(); }
87 bool isMin() const { return F.isSmallest(); }
88 bool isMinusOne() const { return F.isExactlyValue(-1.0); }
89 bool isNan() const { return F.isNaN(); }
90 bool isInf() const { return F.isInfinity(); }
91 bool isFinite() const { return F.isFinite(); }
92 bool isNormal() const { return F.isNormal(); }
93 bool isDenormal() const { return F.isDenormal(); }
94 llvm::FPClassTest classify() const { return F.classify(); }
95 APFloat::fltCategory getCategory() const { return F.getCategory(); }
96
98 llvm::APFloatBase::cmpResult CmpRes = F.compare(RHS.F);
99 switch (CmpRes) {
100 case llvm::APFloatBase::cmpLessThan:
102 case llvm::APFloatBase::cmpEqual:
104 case llvm::APFloatBase::cmpGreaterThan:
106 case llvm::APFloatBase::cmpUnordered:
108 }
109 llvm_unreachable("Inavlid cmpResult value");
110 }
111
112 static APFloat::opStatus fromIntegral(APSInt Val,
113 const llvm::fltSemantics &Sem,
114 llvm::RoundingMode RM,
115 Floating &Result) {
116 APFloat F = APFloat(Sem);
117 APFloat::opStatus Status = F.convertFromAPInt(Val, Val.isSigned(), RM);
118 Result = Floating(F);
119 return Status;
120 }
121
122 static Floating bitcastFromMemory(const std::byte *Buff,
123 const llvm::fltSemantics &Sem) {
124 size_t Size = APFloat::semanticsSizeInBits(Sem);
125 llvm::APInt API(Size, true);
126 llvm::LoadIntFromMemory(API, (const uint8_t *)Buff, Size / 8);
127
128 return Floating(APFloat(Sem, API));
129 }
130
131 // === Serialization support ===
132 size_t bytesToSerialize() const {
133 return sizeof(llvm::fltSemantics *) +
134 (APFloat::semanticsSizeInBits(F.getSemantics()) / 8);
135 }
136
137 void serialize(std::byte *Buff) const {
138 // Semantics followed by an APInt.
139 *reinterpret_cast<const llvm::fltSemantics **>(Buff) = &F.getSemantics();
140
141 llvm::APInt API = F.bitcastToAPInt();
142 llvm::StoreIntToMemory(API, (uint8_t *)(Buff + sizeof(void *)),
143 bitWidth() / 8);
144 }
145
146 static Floating deserialize(const std::byte *Buff) {
147 const llvm::fltSemantics *Sem;
148 std::memcpy((void *)&Sem, Buff, sizeof(void *));
149 return bitcastFromMemory(Buff + sizeof(void *), *Sem);
150 }
151
152 static Floating abs(const Floating &F) {
153 APFloat V = F.F;
154 if (V.isNegative())
155 V.changeSign();
156 return Floating(V);
157 }
158
159 // -------
160
161 static APFloat::opStatus add(const Floating &A, const Floating &B,
162 llvm::RoundingMode RM, Floating *R) {
163 *R = Floating(A.F);
164 return R->F.add(B.F, RM);
165 }
166
167 static APFloat::opStatus increment(const Floating &A, llvm::RoundingMode RM,
168 Floating *R) {
169 APFloat One(A.F.getSemantics(), 1);
170 *R = Floating(A.F);
171 return R->F.add(One, RM);
172 }
173
174 static APFloat::opStatus sub(const Floating &A, const Floating &B,
175 llvm::RoundingMode RM, Floating *R) {
176 *R = Floating(A.F);
177 return R->F.subtract(B.F, RM);
178 }
179
180 static APFloat::opStatus decrement(const Floating &A, llvm::RoundingMode RM,
181 Floating *R) {
182 APFloat One(A.F.getSemantics(), 1);
183 *R = Floating(A.F);
184 return R->F.subtract(One, RM);
185 }
186
187 static APFloat::opStatus mul(const Floating &A, const Floating &B,
188 llvm::RoundingMode RM, Floating *R) {
189 *R = Floating(A.F);
190 return R->F.multiply(B.F, RM);
191 }
192
193 static APFloat::opStatus div(const Floating &A, const Floating &B,
194 llvm::RoundingMode RM, Floating *R) {
195 *R = Floating(A.F);
196 return R->F.divide(B.F, RM);
197 }
198
199 static bool neg(const Floating &A, Floating *R) {
200 *R = -A;
201 return false;
202 }
203};
204
205llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Floating F);
206Floating getSwappedBytes(Floating F);
207
208} // namespace interp
209} // namespace clang
210
211#endif
#define V(N, I)
Definition: ASTContext.h:3233
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
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:193
bool isInf() const
Definition: Floating.h:90
Floating operator-() const
Definition: Floating.h:48
static Floating bitcastFromMemory(const std::byte *Buff, const llvm::fltSemantics &Sem)
Definition: Floating.h:122
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:146
void serialize(std::byte *Buff) const
Definition: Floating.h:137
static APFloat::opStatus sub(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:174
const APFloat & getAPFloat() const
Definition: Floating.h:40
llvm::FPClassTest classify() const
Definition: Floating.h:94
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
Floating()
Zero-initializes a Floating.
Definition: Floating.h:33
unsigned bitWidth() const
Definition: Floating.h:80
bool isNormal() const
Definition: Floating.h:92
ComparisonCategoryResult compare(const Floating &RHS) const
Definition: Floating.h:97
static APFloat::opStatus increment(const Floating &A, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:167
bool operator>=(Floating RHS) const
Definition: Floating.h:45
bool isSigned() const
Definition: Floating.h:82
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:112
bool isMin() const
Definition: Floating.h:87
Floating toSemantics(const llvm::fltSemantics *Sem, llvm::RoundingMode RM) const
Definition: Floating.h:55
size_t bytesToSerialize() const
Definition: Floating.h:132
static APFloat::opStatus add(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:161
static APFloat::opStatus mul(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:187
bool isNan() const
Definition: Floating.h:89
bool isNonZero() const
Definition: Floating.h:86
bool operator!=(Floating RHS) const
Definition: Floating.h:47
bool isZero() const
Definition: Floating.h:85
bool isNegative() const
Definition: Floating.h:83
bool isPositive() const
Definition: Floating.h:84
APValue toAPValue() const
Definition: Floating.h:72
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:199
bool isFinite() const
Definition: Floating.h:91
static APFloat::opStatus decrement(const Floating &A, llvm::RoundingMode RM, Floating *R)
Definition: Floating.h:180
Floating(const APFloat &F)
Definition: Floating.h:34
bool isDenormal() const
Definition: Floating.h:93
static Floating abs(const Floating &F)
Definition: Floating.h:152
bool isMinusOne() const
Definition: Floating.h:88
APFloat::opStatus convertToInteger(APSInt &Result) const
Definition: Floating.h:50
APFloat::fltCategory getCategory() const
Definition: Floating.h:95
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:149
llvm::APSInt APSInt
Definition: Floating.h:24
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Result
The result type of a method or function.