LLVM 20.0.0git
APFixedPoint.cpp
Go to the documentation of this file.
1//===- APFixedPoint.cpp - 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 implementation for the fixed point number interface.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/APFloat.h"
16
17#include <cmath>
18
19namespace llvm {
20
22 OS << "width=" << getWidth() << ", ";
24 OS << "scale=" << getScale() << ", ";
25 OS << "msb=" << getMsbWeight() << ", ";
26 OS << "lsb=" << getLsbWeight() << ", ";
27 OS << "IsSigned=" << IsSigned << ", ";
28 OS << "HasUnsignedPadding=" << HasUnsignedPadding << ", ";
29 OS << "IsSaturated=" << IsSaturated;
30}
31
33 return llvm::bit_cast<uint32_t>(*this);
34}
35
37 FixedPointSemantics F(0, 0, false, false, false);
38 std::memcpy(&F, &I, sizeof(F));
39 return F;
40}
41
43 bool *Overflow) const {
44 APSInt NewVal = Val;
45 int RelativeUpscale = getLsbWeight() - DstSema.getLsbWeight();
46 if (Overflow)
47 *Overflow = false;
48
49 if (RelativeUpscale > 0)
50 NewVal = NewVal.extend(NewVal.getBitWidth() + RelativeUpscale);
51 NewVal = NewVal.relativeShl(RelativeUpscale);
52
53 auto Mask = APInt::getBitsSetFrom(
54 NewVal.getBitWidth(),
55 std::min(DstSema.getIntegralBits() - DstSema.getLsbWeight(),
56 NewVal.getBitWidth()));
57 APInt Masked(NewVal & Mask);
58
59 // Change in the bits above the sign
60 if (!(Masked == Mask || Masked == 0)) {
61 // Found overflow in the bits above the sign
62 if (DstSema.isSaturated())
63 NewVal = NewVal.isNegative() ? Mask : ~Mask;
64 else if (Overflow)
65 *Overflow = true;
66 }
67
68 // If the dst semantics are unsigned, but our value is signed and negative, we
69 // clamp to zero.
70 if (!DstSema.isSigned() && NewVal.isSigned() && NewVal.isNegative()) {
71 // Found negative overflow for unsigned result
72 if (DstSema.isSaturated())
73 NewVal = 0;
74 else if (Overflow)
75 *Overflow = true;
76 }
77
78 NewVal = NewVal.extOrTrunc(DstSema.getWidth());
79 NewVal.setIsSigned(DstSema.isSigned());
80 return APFixedPoint(NewVal, DstSema);
81}
82
84 APSInt ThisVal = getValue();
85 APSInt OtherVal = Other.getValue();
86 bool ThisSigned = Val.isSigned();
87 bool OtherSigned = OtherVal.isSigned();
88
89 int CommonLsb = std::min(getLsbWeight(), Other.getLsbWeight());
90 int CommonMsb = std::max(getMsbWeight(), Other.getMsbWeight());
91 unsigned CommonWidth = CommonMsb - CommonLsb + 1;
92
93 ThisVal = ThisVal.extOrTrunc(CommonWidth);
94 OtherVal = OtherVal.extOrTrunc(CommonWidth);
95
96 ThisVal = ThisVal.shl(getLsbWeight() - CommonLsb);
97 OtherVal = OtherVal.shl(Other.getLsbWeight() - CommonLsb);
98
99 if (ThisSigned && OtherSigned) {
100 if (ThisVal.sgt(OtherVal))
101 return 1;
102 else if (ThisVal.slt(OtherVal))
103 return -1;
104 } else if (!ThisSigned && !OtherSigned) {
105 if (ThisVal.ugt(OtherVal))
106 return 1;
107 else if (ThisVal.ult(OtherVal))
108 return -1;
109 } else if (ThisSigned && !OtherSigned) {
110 if (ThisVal.isSignBitSet())
111 return -1;
112 else if (ThisVal.ugt(OtherVal))
113 return 1;
114 else if (ThisVal.ult(OtherVal))
115 return -1;
116 } else {
117 // !ThisSigned && OtherSigned
118 if (OtherVal.isSignBitSet())
119 return 1;
120 else if (ThisVal.ugt(OtherVal))
121 return 1;
122 else if (ThisVal.ult(OtherVal))
123 return -1;
124 }
125
126 return 0;
127}
128
130 bool IsUnsigned = !Sema.isSigned();
131 auto Val = APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
132 if (IsUnsigned && Sema.hasUnsignedPadding())
133 Val = Val.lshr(1);
134 return APFixedPoint(Val, Sema);
135}
136
138 auto Val = APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned());
139 return APFixedPoint(Val, Sema);
140}
141
143 APSInt Val(Sema.getWidth(), !Sema.isSigned());
144 Val.setBit(/*BitPosition=*/0);
145 return APFixedPoint(Val, Sema);
146}
147
149 const fltSemantics &FloatSema) const {
150 // A fixed point semantic fits in a floating point semantic if the maximum
151 // and minimum values as integers of the fixed point semantic can fit in the
152 // floating point semantic.
153
154 // If these values do not fit, then a floating point rescaling of the true
155 // maximum/minimum value will not fit either, so the floating point semantic
156 // cannot be used to perform such a rescaling.
157
158 APSInt MaxInt = APFixedPoint::getMax(*this).getValue();
159 APFloat F(FloatSema);
160 APFloat::opStatus Status = F.convertFromAPInt(MaxInt, MaxInt.isSigned(),
162 if ((Status & APFloat::opOverflow) || !isSigned())
163 return !(Status & APFloat::opOverflow);
164
165 APSInt MinInt = APFixedPoint::getMin(*this).getValue();
166 Status = F.convertFromAPInt(MinInt, MinInt.isSigned(),
168 return !(Status & APFloat::opOverflow);
169}
170
172 const FixedPointSemantics &Other) const {
173 int CommonLsb = std::min(getLsbWeight(), Other.getLsbWeight());
174 int CommonMSb = std::max(getMsbWeight() - hasSignOrPaddingBit(),
175 Other.getMsbWeight() - Other.hasSignOrPaddingBit());
176 unsigned CommonWidth = CommonMSb - CommonLsb + 1;
177
178 bool ResultIsSigned = isSigned() || Other.isSigned();
179 bool ResultIsSaturated = isSaturated() || Other.isSaturated();
180 bool ResultHasUnsignedPadding = false;
181 if (!ResultIsSigned) {
182 // Both are unsigned.
183 ResultHasUnsignedPadding = hasUnsignedPadding() &&
184 Other.hasUnsignedPadding() && !ResultIsSaturated;
185 }
186
187 // If the result is signed, add an extra bit for the sign. Otherwise, if it is
188 // unsigned and has unsigned padding, we only need to add the extra padding
189 // bit back if we are not saturating.
190 if (ResultIsSigned || ResultHasUnsignedPadding)
191 CommonWidth++;
192
193 return FixedPointSemantics(CommonWidth, Lsb{CommonLsb}, ResultIsSigned,
194 ResultIsSaturated, ResultHasUnsignedPadding);
195}
196
198 bool *Overflow) const {
199 auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
200 APFixedPoint ConvertedThis = convert(CommonFXSema);
201 APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
202 APSInt ThisVal = ConvertedThis.getValue();
203 APSInt OtherVal = ConvertedOther.getValue();
204 bool Overflowed = false;
205
206 APSInt Result;
207 if (CommonFXSema.isSaturated()) {
208 Result = CommonFXSema.isSigned() ? ThisVal.sadd_sat(OtherVal)
209 : ThisVal.uadd_sat(OtherVal);
210 } else {
211 Result = ThisVal.isSigned() ? ThisVal.sadd_ov(OtherVal, Overflowed)
212 : ThisVal.uadd_ov(OtherVal, Overflowed);
213 }
214
215 if (Overflow)
216 *Overflow = Overflowed;
217
218 return APFixedPoint(Result, CommonFXSema);
219}
220
222 bool *Overflow) const {
223 auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
224 APFixedPoint ConvertedThis = convert(CommonFXSema);
225 APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
226 APSInt ThisVal = ConvertedThis.getValue();
227 APSInt OtherVal = ConvertedOther.getValue();
228 bool Overflowed = false;
229
230 APSInt Result;
231 if (CommonFXSema.isSaturated()) {
232 Result = CommonFXSema.isSigned() ? ThisVal.ssub_sat(OtherVal)
233 : ThisVal.usub_sat(OtherVal);
234 } else {
235 Result = ThisVal.isSigned() ? ThisVal.ssub_ov(OtherVal, Overflowed)
236 : ThisVal.usub_ov(OtherVal, Overflowed);
237 }
238
239 if (Overflow)
240 *Overflow = Overflowed;
241
242 return APFixedPoint(Result, CommonFXSema);
243}
244
246 bool *Overflow) const {
247 auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
248 APFixedPoint ConvertedThis = convert(CommonFXSema);
249 APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
250 APSInt ThisVal = ConvertedThis.getValue();
251 APSInt OtherVal = ConvertedOther.getValue();
252 bool Overflowed = false;
253
254 // Widen the LHS and RHS so we can perform a full multiplication.
255 unsigned Wide = CommonFXSema.getWidth() * 2;
256 if (CommonFXSema.isSigned()) {
257 ThisVal = ThisVal.sext(Wide);
258 OtherVal = OtherVal.sext(Wide);
259 } else {
260 ThisVal = ThisVal.zext(Wide);
261 OtherVal = OtherVal.zext(Wide);
262 }
263
264 // Perform the full multiplication and downscale to get the same scale.
265 //
266 // Note that the right shifts here perform an implicit downwards rounding.
267 // This rounding could discard bits that would technically place the result
268 // outside the representable range. We interpret the spec as allowing us to
269 // perform the rounding step first, avoiding the overflow case that would
270 // arise.
271 APSInt Result;
272 if (CommonFXSema.isSigned())
273 Result = ThisVal.smul_ov(OtherVal, Overflowed)
274 .relativeAShl(CommonFXSema.getLsbWeight());
275 else
276 Result = ThisVal.umul_ov(OtherVal, Overflowed)
277 .relativeLShl(CommonFXSema.getLsbWeight());
278 assert(!Overflowed && "Full multiplication cannot overflow!");
279 Result.setIsSigned(CommonFXSema.isSigned());
280
281 // If our result lies outside of the representative range of the common
282 // semantic, we either have overflow or saturation.
283 APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue()
284 .extOrTrunc(Wide);
285 APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue()
286 .extOrTrunc(Wide);
287 if (CommonFXSema.isSaturated()) {
288 if (Result < Min)
289 Result = Min;
290 else if (Result > Max)
291 Result = Max;
292 } else
293 Overflowed = Result < Min || Result > Max;
294
295 if (Overflow)
296 *Overflow = Overflowed;
297
298 return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()),
299 CommonFXSema);
300}
301
303 bool *Overflow) const {
304 auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
305 APFixedPoint ConvertedThis = convert(CommonFXSema);
306 APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
307 APSInt ThisVal = ConvertedThis.getValue();
308 APSInt OtherVal = ConvertedOther.getValue();
309 bool Overflowed = false;
310
311 // Widen the LHS and RHS so we can perform a full division.
312 // Also make sure that there will be enough space for the shift below to not
313 // overflow
314 unsigned Wide =
315 CommonFXSema.getWidth() * 2 + std::max(-CommonFXSema.getMsbWeight(), 0);
316 if (CommonFXSema.isSigned()) {
317 ThisVal = ThisVal.sext(Wide);
318 OtherVal = OtherVal.sext(Wide);
319 } else {
320 ThisVal = ThisVal.zext(Wide);
321 OtherVal = OtherVal.zext(Wide);
322 }
323
324 // Upscale to compensate for the loss of precision from division, and
325 // perform the full division.
326 if (CommonFXSema.getLsbWeight() < 0)
327 ThisVal = ThisVal.shl(-CommonFXSema.getLsbWeight());
328 else if (CommonFXSema.getLsbWeight() > 0)
329 OtherVal = OtherVal.shl(CommonFXSema.getLsbWeight());
330 APSInt Result;
331 if (CommonFXSema.isSigned()) {
332 APInt Rem;
333 APInt::sdivrem(ThisVal, OtherVal, Result, Rem);
334 // If the quotient is negative and the remainder is nonzero, round
335 // towards negative infinity by subtracting epsilon from the result.
336 if (ThisVal.isNegative() != OtherVal.isNegative() && !Rem.isZero())
337 Result = Result - 1;
338 } else
339 Result = ThisVal.udiv(OtherVal);
340 Result.setIsSigned(CommonFXSema.isSigned());
341
342 // If our result lies outside of the representative range of the common
343 // semantic, we either have overflow or saturation.
344 APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue()
345 .extOrTrunc(Wide);
346 APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue()
347 .extOrTrunc(Wide);
348 if (CommonFXSema.isSaturated()) {
349 if (Result < Min)
350 Result = Min;
351 else if (Result > Max)
352 Result = Max;
353 } else
354 Overflowed = Result < Min || Result > Max;
355
356 if (Overflow)
357 *Overflow = Overflowed;
358
359 return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()),
360 CommonFXSema);
361}
362
363APFixedPoint APFixedPoint::shl(unsigned Amt, bool *Overflow) const {
364 APSInt ThisVal = Val;
365 bool Overflowed = false;
366
367 // Widen the LHS.
368 unsigned Wide = Sema.getWidth() * 2;
369 if (Sema.isSigned())
370 ThisVal = ThisVal.sext(Wide);
371 else
372 ThisVal = ThisVal.zext(Wide);
373
374 // Clamp the shift amount at the original width, and perform the shift.
375 Amt = std::min(Amt, ThisVal.getBitWidth());
376 APSInt Result = ThisVal << Amt;
377 Result.setIsSigned(Sema.isSigned());
378
379 // If our result lies outside of the representative range of the
380 // semantic, we either have overflow or saturation.
383 if (Sema.isSaturated()) {
384 if (Result < Min)
385 Result = Min;
386 else if (Result > Max)
387 Result = Max;
388 } else
389 Overflowed = Result < Min || Result > Max;
390
391 if (Overflow)
392 *Overflow = Overflowed;
393
394 return APFixedPoint(Result.sextOrTrunc(Sema.getWidth()), Sema);
395}
396
398 APSInt Val = getValue();
399 int Lsb = getLsbWeight();
400 int OrigWidth = getWidth();
401
402 if (Lsb >= 0) {
403 APSInt IntPart = Val;
404 IntPart = IntPart.extend(IntPart.getBitWidth() + Lsb);
405 IntPart <<= Lsb;
406 IntPart.toString(Str, /*Radix=*/10);
407 Str.push_back('.');
408 Str.push_back('0');
409 return;
410 }
411
412 if (Val.isSigned() && Val.isNegative()) {
413 Val = -Val;
414 Val.setIsUnsigned(true);
415 Str.push_back('-');
416 }
417
418 int Scale = -getLsbWeight();
419 APSInt IntPart = (OrigWidth > Scale) ? (Val >> Scale) : APSInt::get(0);
420
421 // Add 4 digits to hold the value after multiplying 10 (the radix)
422 unsigned Width = std::max(OrigWidth, Scale) + 4;
423 APInt FractPart = Val.zextOrTrunc(Scale).zext(Width);
424 APInt FractPartMask = APInt::getAllOnes(Scale).zext(Width);
425 APInt RadixInt = APInt(Width, 10);
426
427 IntPart.toString(Str, /*Radix=*/10);
428 Str.push_back('.');
429 do {
430 (FractPart * RadixInt)
431 .lshr(Scale)
432 .toString(Str, /*Radix=*/10, Val.isSigned());
433 FractPart = (FractPart * RadixInt) & FractPartMask;
434 } while (FractPart != 0);
435}
436
438 OS << "APFixedPoint(" << toString() << ", {";
439 Sema.print(OS);
440 OS << "})";
441}
443
444APFixedPoint APFixedPoint::negate(bool *Overflow) const {
445 if (!isSaturated()) {
446 if (Overflow)
447 *Overflow =
448 (!isSigned() && Val != 0) || (isSigned() && Val.isMinSignedValue());
449 return APFixedPoint(-Val, Sema);
450 }
451
452 // We never overflow for saturation
453 if (Overflow)
454 *Overflow = false;
455
456 if (isSigned())
457 return Val.isMinSignedValue() ? getMax(Sema) : APFixedPoint(-Val, Sema);
458 else
459 return APFixedPoint(Sema);
460}
461
462APSInt APFixedPoint::convertToInt(unsigned DstWidth, bool DstSign,
463 bool *Overflow) const {
464 APSInt Result = getIntPart();
465 unsigned SrcWidth = getWidth();
466
467 APSInt DstMin = APSInt::getMinValue(DstWidth, !DstSign);
468 APSInt DstMax = APSInt::getMaxValue(DstWidth, !DstSign);
469
470 if (SrcWidth < DstWidth) {
471 Result = Result.extend(DstWidth);
472 } else if (SrcWidth > DstWidth) {
473 DstMin = DstMin.extend(SrcWidth);
474 DstMax = DstMax.extend(SrcWidth);
475 }
476
477 if (Overflow) {
478 if (Result.isSigned() && !DstSign) {
479 *Overflow = Result.isNegative() || Result.ugt(DstMax);
480 } else if (Result.isUnsigned() && DstSign) {
481 *Overflow = Result.ugt(DstMax);
482 } else {
483 *Overflow = Result < DstMin || Result > DstMax;
484 }
485 }
486
487 Result.setIsSigned(DstSign);
488 return Result.extOrTrunc(DstWidth);
489}
490
492 if (S == &APFloat::BFloat())
493 return &APFloat::IEEEdouble();
494 else if (S == &APFloat::IEEEhalf())
495 return &APFloat::IEEEsingle();
496 else if (S == &APFloat::IEEEsingle())
497 return &APFloat::IEEEdouble();
498 else if (S == &APFloat::IEEEdouble())
499 return &APFloat::IEEEquad();
500 llvm_unreachable("Could not promote float type!");
501}
502
504 // For some operations, rounding mode has an effect on the result, while
505 // other operations are lossless and should never result in rounding.
506 // To signify which these operations are, we define two rounding modes here.
509
510 // Make sure that we are operating in a type that works with this fixed-point
511 // semantic.
512 const fltSemantics *OpSema = &FloatSema;
513 while (!Sema.fitsInFloatSemantics(*OpSema))
514 OpSema = promoteFloatSemantics(OpSema);
515
516 // Convert the fixed point value bits as an integer. If the floating point
517 // value does not have the required precision, we will round according to the
518 // given mode.
519 APFloat Flt(*OpSema);
520 APFloat::opStatus S = Flt.convertFromAPInt(Val, Sema.isSigned(), RM);
521
522 // If we cared about checking for precision loss, we could look at this
523 // status.
524 (void)S;
525
526 // Scale down the integer value in the float to match the correct scaling
527 // factor.
528 APFloat ScaleFactor(std::pow(2, Sema.getLsbWeight()));
529 bool Ignored;
530 ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
531 Flt.multiply(ScaleFactor, LosslessRM);
532
533 if (OpSema != &FloatSema)
534 Flt.convert(FloatSema, RM, &Ignored);
535
536 return Flt;
537}
538
540 const FixedPointSemantics &DstFXSema,
541 bool *Overflow) {
543 Value.getBitWidth(), Value.isSigned());
544 return APFixedPoint(Value, IntFXSema).convert(DstFXSema, Overflow);
545}
546
549 const FixedPointSemantics &DstFXSema,
550 bool *Overflow) {
551 // For some operations, rounding mode has an effect on the result, while
552 // other operations are lossless and should never result in rounding.
553 // To signify which these operations are, we define two rounding modes here,
554 // even though they are the same mode.
557
558 const fltSemantics &FloatSema = Value.getSemantics();
559
560 if (Value.isNaN()) {
561 // Handle NaN immediately.
562 if (Overflow)
563 *Overflow = true;
564 return APFixedPoint(DstFXSema);
565 }
566
567 // Make sure that we are operating in a type that works with this fixed-point
568 // semantic.
569 const fltSemantics *OpSema = &FloatSema;
570 while (!DstFXSema.fitsInFloatSemantics(*OpSema))
571 OpSema = promoteFloatSemantics(OpSema);
572
573 APFloat Val = Value;
574
575 bool Ignored;
576 if (&FloatSema != OpSema)
577 Val.convert(*OpSema, LosslessRM, &Ignored);
578
579 // Scale up the float so that the 'fractional' part of the mantissa ends up in
580 // the integer range instead. Rounding mode is irrelevant here.
581 // It is fine if this overflows to infinity even for saturating types,
582 // since we will use floating point comparisons to check for saturation.
583 APFloat ScaleFactor(std::pow(2, -DstFXSema.getLsbWeight()));
584 ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
585 Val.multiply(ScaleFactor, LosslessRM);
586
587 // Convert to the integral representation of the value. This rounding mode
588 // is significant.
589 APSInt Res(DstFXSema.getWidth(), !DstFXSema.isSigned());
590 Val.convertToInteger(Res, RM, &Ignored);
591
592 // Round the integral value and scale back. This makes the
593 // overflow calculations below work properly. If we do not round here,
594 // we risk checking for overflow with a value that is outside the
595 // representable range of the fixed-point semantic even though no overflow
596 // would occur had we rounded first.
597 ScaleFactor = APFloat(std::pow(2, DstFXSema.getLsbWeight()));
598 ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
599 Val.roundToIntegral(RM);
600 Val.multiply(ScaleFactor, LosslessRM);
601
602 // Check for overflow/saturation by checking if the floating point value
603 // is outside the range representable by the fixed-point value.
604 APFloat FloatMax = getMax(DstFXSema).convertToFloat(*OpSema);
605 APFloat FloatMin = getMin(DstFXSema).convertToFloat(*OpSema);
606 bool Overflowed = false;
607 if (DstFXSema.isSaturated()) {
608 if (Val > FloatMax)
609 Res = getMax(DstFXSema).getValue();
610 else if (Val < FloatMin)
611 Res = getMin(DstFXSema).getValue();
612 } else
613 Overflowed = Val > FloatMax || Val < FloatMin;
614
615 if (Overflow)
616 *Overflow = Overflowed;
617
618 return APFixedPoint(Res, DstFXSema);
619}
620
621} // namespace llvm
Defines the fixed point number interface.
This file declares a class to represent arbitrary precision floating point values and provide a varie...
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:622
expand large fp convert
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
The APFixedPoint class works similarly to APInt/APSInt in that it is a functional replacement for a s...
Definition: APFixedPoint.h:162
APFixedPoint convert(const FixedPointSemantics &DstSema, bool *Overflow=nullptr) const
static APFixedPoint getMin(const FixedPointSemantics &Sema)
int getLsbWeight() const
Definition: APFixedPoint.h:181
int compare(const APFixedPoint &Other) const
APSInt convertToInt(unsigned DstWidth, bool DstSign, bool *Overflow=nullptr) const
Return the integral part of this fixed point number, rounded towards zero.
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,...
APFixedPoint sub(const APFixedPoint &Other, bool *Overflow=nullptr) const
APFloat convertToFloat(const fltSemantics &FloatSema) const
Convert this fixed point number to a floating point value with the provided semantics.
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 ...
std::string toString() const
Definition: APFixedPoint.h:245
void print(raw_ostream &) const
APSInt getValue() const
Definition: APFixedPoint.h:178
unsigned getWidth() const
Definition: APFixedPoint.h:179
bool isSigned() const
Definition: APFixedPoint.h:184
APFixedPoint negate(bool *Overflow=nullptr) const
Perform a unary negation (-X) on this fixed point type, taking into account saturation if applicable.
APFixedPoint shl(unsigned Amt, bool *Overflow=nullptr) const
bool isSaturated() const
Definition: APFixedPoint.h:183
static APFixedPoint getEpsilon(const FixedPointSemantics &Sema)
static const fltSemantics * promoteFloatSemantics(const fltSemantics *S)
Given a floating point semantic, return the next floating point semantic with a larger exponent and l...
APFixedPoint div(const APFixedPoint &Other, bool *Overflow=nullptr) const
APFixedPoint mul(const APFixedPoint &Other, bool *Overflow=nullptr) const
APSInt getIntPart() const
Return the integral part of this fixed point number, rounded towards zero.
Definition: APFixedPoint.h:222
APFixedPoint add(const APFixedPoint &Other, bool *Overflow=nullptr) const
int getMsbWeight() const
Definition: APFixedPoint.h:182
static APFixedPoint getMax(const FixedPointSemantics &Sema)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition: APFloat.cpp:5465
opStatus multiply(const APFloat &RHS, roundingMode RM)
Definition: APFloat.h:1196
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Definition: APFloat.h:1321
opStatus roundToIntegral(roundingMode RM)
Definition: APFloat.h:1245
Class for arbitrary precision integers.
Definition: APInt.h:78
APInt umul_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1945
APInt usub_sat(const APInt &RHS) const
Definition: APInt.cpp:2029
APInt udiv(const APInt &RHS) const
Unsigned division operation.
Definition: APInt.cpp:1547
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition: APInt.h:234
APInt zext(unsigned width) const
Zero extend to a new width.
Definition: APInt.cpp:986
bool isMinSignedValue() const
Determine if this is the smallest signed value.
Definition: APInt.h:423
static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
Definition: APInt.cpp:1864
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition: APInt.cpp:1007
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition: APInt.h:1330
APInt relativeLShl(int RelativeShift) const
relative logical shift left
Definition: APInt.h:885
APInt sadd_sat(const APInt &RHS) const
Definition: APInt.cpp:2000
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition: APInt.h:1201
APInt usub_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1922
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
Definition: APInt.h:1182
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition: APInt.h:380
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1468
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition: APInt.h:1111
APInt sadd_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1902
APInt relativeAShl(int RelativeShift) const
relative arithmetic shift left
Definition: APInt.h:895
APInt uadd_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1909
APInt uadd_sat(const APInt &RHS) const
Definition: APInt.cpp:2010
APInt smul_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1934
APInt sext(unsigned width) const
Sign extend to a new width.
Definition: APInt.cpp:959
APInt shl(unsigned shiftAmt) const
Left-shift function.
Definition: APInt.h:873
bool isSignBitSet() const
Determine if sign bit of this APInt is set.
Definition: APInt.h:341
bool slt(const APInt &RHS) const
Signed less than comparison.
Definition: APInt.h:1130
APInt ssub_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1915
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
Definition: APInt.h:286
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition: APInt.h:851
APInt ssub_sat(const APInt &RHS) const
Definition: APInt.cpp:2019
An arbitrary precision integer that knows its signedness.
Definition: APSInt.h:23
APSInt extOrTrunc(uint32_t width) const
Definition: APSInt.h:119
static APSInt getMinValue(uint32_t numBits, bool Unsigned)
Return the APSInt representing the minimum integer value with the given bit width and signedness.
Definition: APSInt.h:311
static APSInt get(int64_t X)
Definition: APSInt.h:349
bool isNegative() const
Determine sign of this APSInt.
Definition: APSInt.h:49
static APSInt getMaxValue(uint32_t numBits, bool Unsigned)
Return the APSInt representing the maximum integer value with the given bit width and signedness.
Definition: APSInt.h:303
void setIsSigned(bool Val)
Definition: APSInt.h:80
APSInt relativeShl(unsigned Amt) const
Definition: APSInt.h:217
void setIsUnsigned(bool Val)
Definition: APSInt.h:79
APSInt extend(uint32_t width) const
Definition: APSInt.h:112
bool isSigned() const
Definition: APSInt.h:77
The fixed point semantics work similarly to fltSemantics.
Definition: APFixedPoint.h:34
static FixedPointSemantics getFromOpaqueInt(uint32_t)
Create a FixedPointSemantics object from an integer created via toOpaqueInt().
unsigned getWidth() const
Definition: APFixedPoint.h:61
bool hasUnsignedPadding() const
Definition: APFixedPoint.h:69
unsigned getScale() const
Definition: APFixedPoint.h:62
unsigned getIntegralBits() const
Return the number of integral bits represented by these semantics.
Definition: APFixedPoint.h:79
FixedPointSemantics getCommonSemantics(const FixedPointSemantics &Other) const
Return the FixedPointSemantics that allows for calculating the full precision semantic that can preci...
void print(llvm::raw_ostream &OS) const
Print semantics for debug purposes.
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...
bool hasSignOrPaddingBit() const
return true if the first bit doesn't have a strictly positive weight
Definition: APFixedPoint.h:74
uint32_t toOpaqueInt() const
Convert the semantics to a 32-bit unsigned integer.
bool isValidLegacySema() const
Check if the Semantic follow the requirements of an older more limited version of this class.
Definition: APFixedPoint.h:58
static FixedPointSemantics GetIntegerSemantics(unsigned Width, bool IsSigned)
Return the FixedPointSemantics for an integer type.
Definition: APFixedPoint.h:103
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Other
Any other memory.
RoundingMode
Rounding mode.
static const fltSemantics & IEEEsingle() LLVM_READNONE
Definition: APFloat.cpp:265
static constexpr roundingMode rmNearestTiesToAway
Definition: APFloat.h:302
static constexpr roundingMode rmNearestTiesToEven
Definition: APFloat.h:297
static constexpr roundingMode rmTowardZero
Definition: APFloat.h:301
static const fltSemantics & IEEEquad() LLVM_READNONE
Definition: APFloat.cpp:267
static const fltSemantics & IEEEdouble() LLVM_READNONE
Definition: APFloat.cpp:266
static const fltSemantics & IEEEhalf() LLVM_READNONE
Definition: APFloat.cpp:263
static const fltSemantics & BFloat() LLVM_READNONE
Definition: APFloat.cpp:264
opStatus
IEEE-754R 7: Default exception handling.
Definition: APFloat.h:313
Used to differentiate between constructors with Width and Lsb from the default Width and scale.
Definition: APFixedPoint.h:40