19 bool *Overflow)
const {
20 llvm::APSInt NewVal = Val;
21 unsigned DstWidth = DstSema.
getWidth();
22 unsigned DstScale = DstSema.
getScale();
23 bool Upscaling = DstScale >
getScale();
28 NewVal = NewVal.extend(NewVal.getBitWidth() + DstScale -
getScale());
34 auto Mask = llvm::APInt::getBitsSetFrom(
37 llvm::APInt Masked(NewVal & Mask);
40 if (!(Masked == Mask || Masked == 0)) {
43 NewVal = NewVal.isNegative() ? Mask : ~Mask;
50 if (!DstSema.
isSigned() && NewVal.isSigned() && NewVal.isNegative()) {
58 NewVal = NewVal.extOrTrunc(DstWidth);
59 NewVal.setIsSigned(DstSema.
isSigned());
65 llvm::APSInt OtherVal = Other.
getValue();
66 bool ThisSigned = Val.isSigned();
67 bool OtherSigned = OtherVal.isSigned();
68 unsigned OtherScale = Other.
getScale();
69 unsigned OtherWidth = OtherVal.getBitWidth();
71 unsigned CommonWidth =
std::max(Val.getBitWidth(), OtherWidth);
77 ThisVal = ThisVal.extOrTrunc(CommonWidth);
78 OtherVal = OtherVal.extOrTrunc(CommonWidth);
81 ThisVal = ThisVal.shl(CommonScale -
getScale());
82 OtherVal = OtherVal.shl(CommonScale - OtherScale);
84 if (ThisSigned && OtherSigned) {
85 if (ThisVal.sgt(OtherVal))
87 else if (ThisVal.slt(OtherVal))
89 }
else if (!ThisSigned && !OtherSigned) {
90 if (ThisVal.ugt(OtherVal))
92 else if (ThisVal.ult(OtherVal))
94 }
else if (ThisSigned && !OtherSigned) {
95 if (ThisVal.isSignBitSet())
97 else if (ThisVal.ugt(OtherVal))
99 else if (ThisVal.ult(OtherVal))
103 if (OtherVal.isSignBitSet())
105 else if (ThisVal.ugt(OtherVal))
107 else if (ThisVal.ult(OtherVal))
116 auto Val = llvm::APSInt::getMaxValue(Sema.
getWidth(), IsUnsigned);
130 unsigned CommonWidth =
135 bool ResultHasUnsignedPadding =
false;
136 if (!ResultIsSigned) {
138 ResultHasUnsignedPadding = hasUnsignedPadding() &&
145 if (ResultIsSigned || ResultHasUnsignedPadding)
149 ResultIsSaturated, ResultHasUnsignedPadding);
153 bool *Overflow)
const {
157 llvm::APSInt ThisVal = ConvertedThis.
getValue();
158 llvm::APSInt OtherVal = ConvertedOther.
getValue();
159 bool Overflowed =
false;
162 if (CommonFXSema.isSaturated()) {
163 Result = CommonFXSema.isSigned() ? ThisVal.sadd_sat(OtherVal)
164 : ThisVal.uadd_sat(OtherVal);
166 Result = ThisVal.isSigned() ? ThisVal.sadd_ov(OtherVal, Overflowed)
167 : ThisVal.uadd_ov(OtherVal, Overflowed);
171 *Overflow = Overflowed;
180 if (Val.isSigned() && Val.isNegative() && Val != -Val) {
185 llvm::APSInt IntPart = Val >> Scale;
188 unsigned Width = Val.getBitWidth() + 4;
189 llvm::APInt FractPart = Val.zextOrTrunc(Scale).zext(Width);
190 llvm::APInt FractPartMask = llvm::APInt::getAllOnesValue(Scale).zext(Width);
191 llvm::APInt RadixInt = llvm::APInt(Width, 10);
193 IntPart.toString(Str, 10);
196 (FractPart * RadixInt)
198 .toString(Str, 10, Val.isSigned());
199 FractPart = (FractPart * RadixInt) & FractPartMask;
200 }
while (FractPart != 0);
222 bool *Overflow)
const {
226 llvm::APSInt DstMin = llvm::APSInt::getMinValue(DstWidth, !DstSign);
227 llvm::APSInt DstMax = llvm::APSInt::getMaxValue(DstWidth, !DstSign);
229 if (SrcWidth < DstWidth) {
230 Result = Result.extend(DstWidth);
231 }
else if (SrcWidth > DstWidth) {
232 DstMin = DstMin.extend(SrcWidth);
233 DstMax = DstMax.extend(SrcWidth);
237 if (Result.isSigned() && !DstSign) {
238 *Overflow = Result.isNegative() || Result.ugt(DstMax);
239 }
else if (Result.isUnsigned() && DstSign) {
240 *Overflow = Result.ugt(DstMax);
242 *Overflow = Result < DstMin || Result > DstMax;
246 Result.setIsSigned(DstSign);
247 return Result.extOrTrunc(DstWidth);
254 Value.getBitWidth(), Value.isSigned());
255 return APFixedPoint(Value, IntFXSema).convert(DstFXSema, Overflow);
static APFixedPoint getFromIntValue(const llvm::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 ...
static APFixedPoint getMax(const FixedPointSemantics &Sema)
llvm::APSInt getValue() const
The fixed point semantics work similarly to llvm::fltSemantics.
unsigned getScale() const
unsigned getWidth() const
APFixedPoint add(const APFixedPoint &Other, bool *Overflow=nullptr) const
llvm::APSInt getIntPart() const
Return the integral part of this fixed point number, rounded towards zero.
int compare(const APFixedPoint &Other) const
unsigned getIntegralBits() const
Return the number of integral bits represented by these semantics.
__DEVICE__ int max(int __a, int __b)
static APFixedPoint getMin(const FixedPointSemantics &Sema)
unsigned getScale() const
std::string toString() const
The APFixedPoint class works similarly to APInt/APSInt in that it is a functional replacement for a s...
APFixedPoint negate(bool *Overflow=nullptr) const
Perform a unary negation (-X) on this fixed point type, taking into account saturation if applicable...
Sema - This implements semantic analysis and AST building for C.
bool hasUnsignedPadding() const
FixedPointSemantics getCommonSemantics(const FixedPointSemantics &Other) const
Return the FixedPointSemantics that allows for calculating the full precision semantic that can preci...
The result type of a method or function.
FixedPointSemantics getSemantics() const
Defines the fixed point number interface.
Dataflow Directional Tag Classes.
static FixedPointSemantics GetIntegerSemantics(unsigned Width, bool IsSigned)
Return the FixedPointSemantics for an integer type.
APFixedPoint convert(const FixedPointSemantics &DstSema, bool *Overflow=nullptr) const
unsigned getWidth() const
APFixedPoint(const llvm::APInt &Val, const FixedPointSemantics &Sema)
__DEVICE__ int min(int __a, int __b)
llvm::APSInt convertToInt(unsigned DstWidth, bool DstSign, bool *Overflow=nullptr) const
Return the integral part of this fixed point number, rounded towards zero.