LLVM  14.0.0git
APFixedPoint.h
Go to the documentation of this file.
1 //===- APFixedPoint.h - Fixed point constant handling -----------*- 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 /// \file
10 /// Defines the fixed point number interface.
11 /// This is a class for abstracting various operations performed on fixed point
12 /// types.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_ADT_APFIXEDPOINT_H
17 #define LLVM_ADT_APFIXEDPOINT_H
18 
19 #include "llvm/ADT/APSInt.h"
20 #include "llvm/ADT/SmallString.h"
22 
23 namespace llvm {
24 
25 class APFloat;
26 struct fltSemantics;
27 
28 /// The fixed point semantics work similarly to fltSemantics. The width
29 /// specifies the whole bit width of the underlying scaled integer (with padding
30 /// if any). The scale represents the number of fractional bits in this type.
31 /// When HasUnsignedPadding is true and this type is unsigned, the first bit
32 /// in the value this represents is treated as padding.
34 public:
35  FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned,
36  bool IsSaturated, bool HasUnsignedPadding)
37  : Width(Width), Scale(Scale), IsSigned(IsSigned),
38  IsSaturated(IsSaturated), HasUnsignedPadding(HasUnsignedPadding) {
39  assert(Width >= Scale && "Not enough room for the scale");
40  assert(!(IsSigned && HasUnsignedPadding) &&
41  "Cannot have unsigned padding on a signed type.");
42  }
43 
44  unsigned getWidth() const { return Width; }
45  unsigned getScale() const { return Scale; }
46  bool isSigned() const { return IsSigned; }
47  bool isSaturated() const { return IsSaturated; }
48  bool hasUnsignedPadding() const { return HasUnsignedPadding; }
49 
50  void setSaturated(bool Saturated) { IsSaturated = Saturated; }
51 
52  /// Return the number of integral bits represented by these semantics. These
53  /// are separate from the fractional bits and do not include the sign or
54  /// padding bit.
55  unsigned getIntegralBits() const {
56  if (IsSigned || (!IsSigned && HasUnsignedPadding))
57  return Width - Scale - 1;
58  else
59  return Width - Scale;
60  }
61 
62  /// Return the FixedPointSemantics that allows for calculating the full
63  /// precision semantic that can precisely represent the precision and ranges
64  /// of both input values. This does not compute the resulting semantics for a
65  /// given binary operation.
67  getCommonSemantics(const FixedPointSemantics &Other) const;
68 
69  /// Returns true if this fixed-point semantic with its value bits interpreted
70  /// as an integer can fit in the given floating point semantic without
71  /// overflowing to infinity.
72  /// For example, a signed 8-bit fixed-point semantic has a maximum and
73  /// minimum integer representation of 127 and -128, respectively. If both of
74  /// these values can be represented (possibly inexactly) in the floating
75  /// point semantic without overflowing, this returns true.
76  bool fitsInFloatSemantics(const fltSemantics &FloatSema) const;
77 
78  /// Return the FixedPointSemantics for an integer type.
80  bool IsSigned) {
81  return FixedPointSemantics(Width, /*Scale=*/0, IsSigned,
82  /*IsSaturated=*/false,
83  /*HasUnsignedPadding=*/false);
84  }
85 
86 private:
87  unsigned Width : 16;
88  unsigned Scale : 13;
89  unsigned IsSigned : 1;
90  unsigned IsSaturated : 1;
91  unsigned HasUnsignedPadding : 1;
92 };
93 
94 /// The APFixedPoint class works similarly to APInt/APSInt in that it is a
95 /// functional replacement for a scaled integer. It is meant to replicate the
96 /// fixed point types proposed in ISO/IEC JTC1 SC22 WG14 N1169. The class carries
97 /// info about the fixed point type's width, sign, scale, and saturation, and
98 /// provides different operations that would normally be performed on fixed point
99 /// types.
101 public:
102  APFixedPoint(const APInt &Val, const FixedPointSemantics &Sema)
103  : Val(Val, !Sema.isSigned()), Sema(Sema) {
104  assert(Val.getBitWidth() == Sema.getWidth() &&
105  "The value should have a bit width that matches the Sema width");
106  }
107 
109  : APFixedPoint(APInt(Sema.getWidth(), Val, Sema.isSigned()), Sema) {}
110 
111  // Zero initialization.
112  APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}
113 
114  APSInt getValue() const { return APSInt(Val, !Sema.isSigned()); }
115  inline unsigned getWidth() const { return Sema.getWidth(); }
116  inline unsigned getScale() const { return Sema.getScale(); }
117  inline bool isSaturated() const { return Sema.isSaturated(); }
118  inline bool isSigned() const { return Sema.isSigned(); }
119  inline bool hasPadding() const { return Sema.hasUnsignedPadding(); }
120  FixedPointSemantics getSemantics() const { return Sema; }
121 
122  bool getBoolValue() const { return Val.getBoolValue(); }
123 
124  // Convert this number to match the semantics provided. If the overflow
125  // parameter is provided, set this value to true or false to indicate if this
126  // operation results in an overflow.
128  bool *Overflow = nullptr) const;
129 
130  // Perform binary operations on a fixed point type. The resulting fixed point
131  // value will be in the common, full precision semantics that can represent
132  // the precision and ranges of both input values. See convert() for an
133  // explanation of the Overflow parameter.
134  APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const;
135  APFixedPoint sub(const APFixedPoint &Other, bool *Overflow = nullptr) const;
136  APFixedPoint mul(const APFixedPoint &Other, bool *Overflow = nullptr) const;
137  APFixedPoint div(const APFixedPoint &Other, bool *Overflow = nullptr) const;
138 
139  // Perform shift operations on a fixed point type. Unlike the other binary
140  // operations, the resulting fixed point value will be in the original
141  // semantic.
142  APFixedPoint shl(unsigned Amt, bool *Overflow = nullptr) const;
143  APFixedPoint shr(unsigned Amt, bool *Overflow = nullptr) const {
144  // Right shift cannot overflow.
145  if (Overflow)
146  *Overflow = false;
147  return APFixedPoint(Val >> Amt, Sema);
148  }
149 
150  /// Perform a unary negation (-X) on this fixed point type, taking into
151  /// account saturation if applicable.
152  APFixedPoint negate(bool *Overflow = nullptr) const;
153 
154  /// Return the integral part of this fixed point number, rounded towards
155  /// zero. (-2.5k -> -2)
156  APSInt getIntPart() const {
157  if (Val < 0 && Val != -Val) // Cover the case when we have the min val
158  return -(-Val >> getScale());
159  else
160  return Val >> getScale();
161  }
162 
163  /// Return the integral part of this fixed point number, rounded towards
164  /// zero. The value is stored into an APSInt with the provided width and sign.
165  /// If the overflow parameter is provided, and the integral value is not able
166  /// to be fully stored in the provided width and sign, the overflow parameter
167  /// is set to true.
168  APSInt convertToInt(unsigned DstWidth, bool DstSign,
169  bool *Overflow = nullptr) const;
170 
171  /// Convert this fixed point number to a floating point value with the
172  /// provided semantics.
173  APFloat convertToFloat(const fltSemantics &FloatSema) const;
174 
175  void toString(SmallVectorImpl<char> &Str) const;
176  std::string toString() const {
178  toString(S);
179  return std::string(S.str());
180  }
181 
182  // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1.
183  int compare(const APFixedPoint &Other) const;
184  bool operator==(const APFixedPoint &Other) const {
185  return compare(Other) == 0;
186  }
187  bool operator!=(const APFixedPoint &Other) const {
188  return compare(Other) != 0;
189  }
190  bool operator>(const APFixedPoint &Other) const { return compare(Other) > 0; }
191  bool operator<(const APFixedPoint &Other) const { return compare(Other) < 0; }
192  bool operator>=(const APFixedPoint &Other) const {
193  return compare(Other) >= 0;
194  }
195  bool operator<=(const APFixedPoint &Other) const {
196  return compare(Other) <= 0;
197  }
198 
199  static APFixedPoint getMax(const FixedPointSemantics &Sema);
200  static APFixedPoint getMin(const FixedPointSemantics &Sema);
201 
202  /// Given a floating point semantic, return the next floating point semantic
203  /// with a larger exponent and larger or equal mantissa.
204  static const fltSemantics *promoteFloatSemantics(const fltSemantics *S);
205 
206  /// Create an APFixedPoint with a value equal to that of the provided integer,
207  /// and in the same semantics as the provided target semantics. If the value
208  /// is not able to fit in the specified fixed point semantics, and the
209  /// overflow parameter is provided, it is set to true.
211  const FixedPointSemantics &DstFXSema,
212  bool *Overflow = nullptr);
213 
214  /// Create an APFixedPoint with a value equal to that of the provided
215  /// floating point value, in the provided target semantics. If the value is
216  /// not able to fit in the specified fixed point semantics and the overflow
217  /// parameter is specified, it is set to true.
218  /// For NaN, the Overflow flag is always set. For +inf and -inf, if the
219  /// semantic is saturating, the value saturates. Otherwise, the Overflow flag
220  /// is set.
222  const FixedPointSemantics &DstFXSema,
223  bool *Overflow = nullptr);
224 
225 private:
226  APSInt Val;
227  FixedPointSemantics Sema;
228 };
229 
231  OS << FX.toString();
232  return OS;
233 }
234 
235 } // namespace llvm
236 
237 #endif
llvm::lltok::APFloat
@ APFloat
Definition: LLToken.h:495
llvm::APFixedPoint::getValue
APSInt getValue() const
Definition: APFixedPoint.h:114
llvm::APFixedPoint::compare
int compare(const APFixedPoint &Other) const
Definition: APFixedPoint.cpp:64
llvm::APFixedPoint::getFromFloatValue
static APFixedPoint getFromFloatValue(const APFloat &Value, const FixedPointSemantics &DstFXSema, bool *Overflow=nullptr)
Create an APFixedPoint with a value equal to that of the provided floating point value,...
Definition: APFixedPoint.cpp:501
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::APFixedPoint
The APFixedPoint class works similarly to APInt/APSInt in that it is a functional replacement for a s...
Definition: APFixedPoint.h:100
llvm::APFixedPoint::APFixedPoint
APFixedPoint(const FixedPointSemantics &Sema)
Definition: APFixedPoint.h:112
llvm::APFixedPoint::operator>
bool operator>(const APFixedPoint &Other) const
Definition: APFixedPoint.h:190
llvm::FixedPointSemantics::getScale
unsigned getScale() const
Definition: APFixedPoint.h:45
llvm::FixedPointSemantics::getIntegralBits
unsigned getIntegralBits() const
Return the number of integral bits represented by these semantics.
Definition: APFixedPoint.h:55
llvm::APFixedPoint::hasPadding
bool hasPadding() const
Definition: APFixedPoint.h:119
llvm::APFixedPoint::isSaturated
bool isSaturated() const
Definition: APFixedPoint.h:117
llvm::lltok::APSInt
@ APSInt
Definition: LLToken.h:496
llvm::APFixedPoint::operator!=
bool operator!=(const APFixedPoint &Other) const
Definition: APFixedPoint.h:187
llvm::APFixedPoint::negate
APFixedPoint negate(bool *Overflow=nullptr) const
Perform a unary negation (-X) on this fixed point type, taking into account saturation if applicable.
Definition: APFixedPoint.cpp:397
llvm::APInt::getBitWidth
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1410
llvm::APFixedPoint::getIntPart
APSInt getIntPart() const
Return the integral part of this fixed point number, rounded towards zero.
Definition: APFixedPoint.h:156
llvm::FixedPointSemantics::getCommonSemantics
FixedPointSemantics getCommonSemantics(const FixedPointSemantics &Other) const
Return the FixedPointSemantics that allows for calculating the full precision semantic that can preci...
Definition: APFixedPoint.cpp:151
llvm::FixedPointSemantics::hasUnsignedPadding
bool hasUnsignedPadding() const
Definition: APFixedPoint.h:48
llvm::FixedPointSemantics::setSaturated
void setSaturated(bool Saturated)
Definition: APFixedPoint.h:50
llvm::APFixedPoint::shr
APFixedPoint shr(unsigned Amt, bool *Overflow=nullptr) const
Definition: APFixedPoint.h:143
llvm::APFixedPoint::operator<=
bool operator<=(const APFixedPoint &Other) const
Definition: APFixedPoint.h:195
llvm::APFixedPoint::operator>=
bool operator>=(const APFixedPoint &Other) const
Definition: APFixedPoint.h:192
SmallString.h
llvm::FixedPointSemantics::FixedPointSemantics
FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned, bool IsSaturated, bool HasUnsignedPadding)
Definition: APFixedPoint.h:35
llvm::APFixedPoint::isSigned
bool isSigned() const
Definition: APFixedPoint.h:118
llvm::APFixedPoint::APFixedPoint
APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema)
Definition: APFixedPoint.h:108
llvm::APFixedPoint::getWidth
unsigned getWidth() const
Definition: APFixedPoint.h:115
llvm::FixedPointSemantics
The fixed point semantics work similarly to fltSemantics.
Definition: APFixedPoint.h:33
llvm::APFixedPoint::getMax
static APFixedPoint getMax(const FixedPointSemantics &Sema)
Definition: APFixedPoint.cpp:115
llvm::APSInt
An arbitrary precision integer that knows its signedness.
Definition: APSInt.h:22
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::operator<<
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:230
llvm::APFixedPoint::getMin
static APFixedPoint getMin(const FixedPointSemantics &Sema)
Definition: APFixedPoint.cpp:123
llvm::FixedPointSemantics::isSaturated
bool isSaturated() const
Definition: APFixedPoint.h:47
llvm::APFixedPoint::operator<
bool operator<(const APFixedPoint &Other) const
Definition: APFixedPoint.h:191
llvm::APFixedPoint::getBoolValue
bool getBoolValue() const
Definition: APFixedPoint.h:122
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:25
llvm::FixedPointSemantics::isSigned
bool isSigned() const
Definition: APFixedPoint.h:46
llvm::FixedPointSemantics::getWidth
unsigned getWidth() const
Definition: APFixedPoint.h:44
llvm::APFloat
Definition: APFloat.h:701
llvm::APFixedPoint::shl
APFixedPoint shl(unsigned Amt, bool *Overflow=nullptr) const
Definition: APFixedPoint.cpp:336
llvm::APFixedPoint::div
APFixedPoint div(const APFixedPoint &Other, bool *Overflow=nullptr) const
Definition: APFixedPoint.cpp:281
uint64_t
llvm::FixedPointSemantics::GetIntegerSemantics
static FixedPointSemantics GetIntegerSemantics(unsigned Width, bool IsSigned)
Return the FixedPointSemantics for an integer type.
Definition: APFixedPoint.h:79
llvm::APFixedPoint::convertToFloat
APFloat convertToFloat(const fltSemantics &FloatSema) const
Convert this fixed point number to a floating point value with the provided semantics.
Definition: APFixedPoint.cpp:456
llvm::APFixedPoint::getSemantics
FixedPointSemantics getSemantics() const
Definition: APFixedPoint.h:120
llvm::APFixedPoint::convertToInt
APSInt convertToInt(unsigned DstWidth, bool DstSign, bool *Overflow=nullptr) const
Return the integral part of this fixed point number, rounded towards zero.
Definition: APFixedPoint.cpp:415
llvm::APInt::getBoolValue
bool getBoolValue() const
Convert APInt to a boolean value.
Definition: APInt.h:452
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
APSInt.h
llvm::APFixedPoint::add
APFixedPoint add(const APFixedPoint &Other, bool *Overflow=nullptr) const
Definition: APFixedPoint.cpp:176
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:75
llvm::FixedPointSemantics::fitsInFloatSemantics
bool fitsInFloatSemantics(const fltSemantics &FloatSema) const
Returns true if this fixed-point semantic with its value bits interpreted as an integer can fit in th...
Definition: APFixedPoint.cpp:128
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::APFixedPoint::APFixedPoint
APFixedPoint(const APInt &Val, const FixedPointSemantics &Sema)
Definition: APFixedPoint.h:102
llvm::fltSemantics
Definition: APFloat.cpp:54
llvm::APFixedPoint::mul
APFixedPoint mul(const APFixedPoint &Other, bool *Overflow=nullptr) const
Definition: APFixedPoint.cpp:224
llvm::APFixedPoint::operator==
bool operator==(const APFixedPoint &Other) const
Definition: APFixedPoint.h:184
llvm::APFixedPoint::toString
void toString(SmallVectorImpl< char > &Str) const
Definition: APFixedPoint.cpp:370
llvm::APFixedPoint::promoteFloatSemantics
static const fltSemantics * promoteFloatSemantics(const fltSemantics *S)
Given a floating point semantic, return the next floating point semantic with a larger exponent and l...
Definition: APFixedPoint.cpp:444
llvm::APFixedPoint::toString
std::string toString() const
Definition: APFixedPoint.h:176
llvm::SmallVectorImpl< char >
llvm::APFixedPoint::convert
APFixedPoint convert(const FixedPointSemantics &DstSema, bool *Overflow=nullptr) const
Definition: APFixedPoint.cpp:19
llvm::APFixedPoint::getFromIntValue
static APFixedPoint getFromIntValue(const APSInt &Value, const FixedPointSemantics &DstFXSema, bool *Overflow=nullptr)
Create an APFixedPoint with a value equal to that of the provided integer, and in the same semantics ...
Definition: APFixedPoint.cpp:492
llvm::APFixedPoint::sub
APFixedPoint sub(const APFixedPoint &Other, bool *Overflow=nullptr) const
Definition: APFixedPoint.cpp:200
raw_ostream.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1184
llvm::APFixedPoint::getScale
unsigned getScale() const
Definition: APFixedPoint.h:116