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