clang  19.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 
20 namespace clang {
21 namespace interp {
22 
25 
26 class Floating final {
27 private:
28  // The underlying value storage.
29  APFloat F;
30 
31 public:
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.
75  SmallVector<char, 16> Buffer;
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 
212 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Floating F);
213 Floating getSwappedBytes(Floating F);
214 
215 } // namespace interp
216 } // namespace clang
217 
218 #endif
#define V(N, I)
Definition: ASTContext.h:3299
llvm::APSInt APSInt
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
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:185
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
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
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: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
const APFloat & getAPFloat() const
Definition: Floating.h:40
APFloat::opStatus convertToInteger(APSInt &Result) const
Definition: Floating.h:50
APFloat::fltCategory getCategory() const
Definition: Floating.h:102
llvm::APFloat APFloat
Definition: Floating.h:23
llvm::APInt APInt
Definition: Integral.h:29
Floating getSwappedBytes(Floating F)
Definition: Floating.cpp:19
llvm::APSInt APSInt
Definition: Floating.h:24
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const Boolean &B)
Definition: Boolean.h:156
The JSON file list parser is used to communicate input to InstallAPI.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Other
Other implicit parameter.