LLVM 22.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
296 if (Overflow)
297 *Overflow = Overflowed;
298
299 return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()),
300 CommonFXSema);
301}
302
304 bool *Overflow) const {
305 auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
306 APFixedPoint ConvertedThis = convert(CommonFXSema);
307 APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
308 APSInt ThisVal = ConvertedThis.getValue();
309 APSInt OtherVal = ConvertedOther.getValue();
310 bool Overflowed = false;
311
312 // Widen the LHS and RHS so we can perform a full division.
313 // Also make sure that there will be enough space for the shift below to not
314 // overflow
315 unsigned Wide =
316 CommonFXSema.getWidth() * 2 + std::max(-CommonFXSema.getMsbWeight(), 0);
317 if (CommonFXSema.isSigned()) {
318 ThisVal = ThisVal.sext(Wide);
319 OtherVal = OtherVal.sext(Wide);
320 } else {
321 ThisVal = ThisVal.zext(Wide);
322 OtherVal = OtherVal.zext(Wide);
323 }
324
325 // Upscale to compensate for the loss of precision from division, and
326 // perform the full division.
327 if (CommonFXSema.getLsbWeight() < 0)
328 ThisVal = ThisVal.shl(-CommonFXSema.getLsbWeight());
329 else if (CommonFXSema.getLsbWeight() > 0)
330 OtherVal = OtherVal.shl(CommonFXSema.getLsbWeight());
331 APSInt Result;
332 if (CommonFXSema.isSigned()) {
333 APInt Rem;
334 APInt::sdivrem(ThisVal, OtherVal, Result, Rem);
335 // If the quotient is negative and the remainder is nonzero, round
336 // towards negative infinity by subtracting epsilon from the result.
337 if (ThisVal.isNegative() != OtherVal.isNegative() && !Rem.isZero())
338 Result = Result - 1;
339 } else {
340 Result = ThisVal.udiv(OtherVal);
341 }
342 Result.setIsSigned(CommonFXSema.isSigned());
343
344 // If our result lies outside of the representative range of the common
345 // semantic, we either have overflow or saturation.
346 APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue()
347 .extOrTrunc(Wide);
348 APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue()
349 .extOrTrunc(Wide);
350 if (CommonFXSema.isSaturated()) {
351 if (Result < Min)
352 Result = Min;
353 else if (Result > Max)
354 Result = Max;
355 } else {
356 Overflowed = Result < Min || Result > Max;
357 }
358
359 if (Overflow)
360 *Overflow = Overflowed;
361
362 return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()),
363 CommonFXSema);
364}
365
366APFixedPoint APFixedPoint::shl(unsigned Amt, bool *Overflow) const {
367 APSInt ThisVal = Val;
368 bool Overflowed = false;
369
370 // Widen the LHS.
371 unsigned Wide = Sema.getWidth() * 2;
372 if (Sema.isSigned())
373 ThisVal = ThisVal.sext(Wide);
374 else
375 ThisVal = ThisVal.zext(Wide);
376
377 // Clamp the shift amount at the original width, and perform the shift.
378 Amt = std::min(Amt, ThisVal.getBitWidth());
379 APSInt Result = ThisVal << Amt;
380 Result.setIsSigned(Sema.isSigned());
381
382 // If our result lies outside of the representative range of the
383 // semantic, we either have overflow or saturation.
386 if (Sema.isSaturated()) {
387 if (Result < Min)
388 Result = Min;
389 else if (Result > Max)
390 Result = Max;
391 } else {
392 Overflowed = Result < Min || Result > Max;
393 }
394
395 if (Overflow)
396 *Overflow = Overflowed;
397
398 return APFixedPoint(Result.sextOrTrunc(Sema.getWidth()), Sema);
399}
400
402 APSInt Val = getValue();
403 int Lsb = getLsbWeight();
404 int OrigWidth = getWidth();
405
406 if (Lsb >= 0) {
407 APSInt IntPart = Val;
408 IntPart = IntPart.extend(IntPart.getBitWidth() + Lsb);
409 IntPart <<= Lsb;
410 IntPart.toString(Str, /*Radix=*/10);
411 Str.push_back('.');
412 Str.push_back('0');
413 return;
414 }
415
416 if (Val.isSigned() && Val.isNegative()) {
417 Val = -Val;
418 Val.setIsUnsigned(true);
419 Str.push_back('-');
420 }
421
422 int Scale = -getLsbWeight();
423 APSInt IntPart = (OrigWidth > Scale) ? (Val >> Scale) : APSInt::get(0);
424
425 // Add 4 digits to hold the value after multiplying 10 (the radix)
426 unsigned Width = std::max(OrigWidth, Scale) + 4;
427 APInt FractPart = Val.zextOrTrunc(Scale).zext(Width);
428 APInt FractPartMask = APInt::getAllOnes(Scale).zext(Width);
429 APInt RadixInt = APInt(Width, 10);
430
431 IntPart.toString(Str, /*Radix=*/10);
432 Str.push_back('.');
433 do {
434 (FractPart * RadixInt)
435 .lshr(Scale)
436 .toString(Str, /*Radix=*/10, Val.isSigned());
437 FractPart = (FractPart * RadixInt) & FractPartMask;
438 } while (FractPart != 0);
439}
440
442 OS << "APFixedPoint(" << toString() << ", {";
443 Sema.print(OS);
444 OS << "})";
445}
446
447#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
449#endif
450
451APFixedPoint APFixedPoint::negate(bool *Overflow) const {
452 if (!isSaturated()) {
453 if (Overflow)
454 *Overflow =
455 (!isSigned() && Val != 0) || (isSigned() && Val.isMinSignedValue());
456 return APFixedPoint(-Val, Sema);
457 }
458
459 // We never overflow for saturation
460 if (Overflow)
461 *Overflow = false;
462
463 if (isSigned())
464 return Val.isMinSignedValue() ? getMax(Sema) : APFixedPoint(-Val, Sema);
465 else
466 return APFixedPoint(Sema);
467}
468
469APSInt APFixedPoint::convertToInt(unsigned DstWidth, bool DstSign,
470 bool *Overflow) const {
471 APSInt Result = getIntPart();
472 unsigned SrcWidth = getWidth();
473
474 APSInt DstMin = APSInt::getMinValue(DstWidth, !DstSign);
475 APSInt DstMax = APSInt::getMaxValue(DstWidth, !DstSign);
476
477 if (SrcWidth < DstWidth) {
478 Result = Result.extend(DstWidth);
479 } else if (SrcWidth > DstWidth) {
480 DstMin = DstMin.extend(SrcWidth);
481 DstMax = DstMax.extend(SrcWidth);
482 }
483
484 if (Overflow) {
485 if (Result.isSigned() && !DstSign) {
486 *Overflow = Result.isNegative() || Result.ugt(DstMax);
487 } else if (Result.isUnsigned() && DstSign) {
488 *Overflow = Result.ugt(DstMax);
489 } else {
490 *Overflow = Result < DstMin || Result > DstMax;
491 }
492 }
493
494 Result.setIsSigned(DstSign);
495 return Result.extOrTrunc(DstWidth);
496}
497
499 if (S == &APFloat::BFloat())
500 return &APFloat::IEEEdouble();
501 else if (S == &APFloat::IEEEhalf())
502 return &APFloat::IEEEsingle();
503 else if (S == &APFloat::IEEEsingle())
504 return &APFloat::IEEEdouble();
505 else if (S == &APFloat::IEEEdouble())
506 return &APFloat::IEEEquad();
507 llvm_unreachable("Could not promote float type!");
508}
509
511 // For some operations, rounding mode has an effect on the result, while
512 // other operations are lossless and should never result in rounding.
513 // To signify which these operations are, we define two rounding modes here.
516
517 // Make sure that we are operating in a type that works with this fixed-point
518 // semantic.
519 const fltSemantics *OpSema = &FloatSema;
520 while (!Sema.fitsInFloatSemantics(*OpSema))
521 OpSema = promoteFloatSemantics(OpSema);
522
523 // Convert the fixed point value bits as an integer. If the floating point
524 // value does not have the required precision, we will round according to the
525 // given mode.
526 APFloat Flt(*OpSema);
527 APFloat::opStatus S = Flt.convertFromAPInt(Val, Sema.isSigned(), RM);
528
529 // If we cared about checking for precision loss, we could look at this
530 // status.
531 (void)S;
532
533 // Scale down the integer value in the float to match the correct scaling
534 // factor.
535 APFloat ScaleFactor(std::pow(2, Sema.getLsbWeight()));
536 bool Ignored;
537 ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
538 Flt.multiply(ScaleFactor, LosslessRM);
539
540 if (OpSema != &FloatSema)
541 Flt.convert(FloatSema, RM, &Ignored);
542
543 return Flt;
544}
545
547 const FixedPointSemantics &DstFXSema,
548 bool *Overflow) {
550 Value.getBitWidth(), Value.isSigned());
551 return APFixedPoint(Value, IntFXSema).convert(DstFXSema, Overflow);
552}
553
556 const FixedPointSemantics &DstFXSema,
557 bool *Overflow) {
558 // For some operations, rounding mode has an effect on the result, while
559 // other operations are lossless and should never result in rounding.
560 // To signify which these operations are, we define two rounding modes here,
561 // even though they are the same mode.
564
565 const fltSemantics &FloatSema = Value.getSemantics();
566
567 if (Value.isNaN()) {
568 // Handle NaN immediately.
569 if (Overflow)
570 *Overflow = true;
571 return APFixedPoint(DstFXSema);
572 }
573
574 // Make sure that we are operating in a type that works with this fixed-point
575 // semantic.
576 const fltSemantics *OpSema = &FloatSema;
577 while (!DstFXSema.fitsInFloatSemantics(*OpSema))
578 OpSema = promoteFloatSemantics(OpSema);
579
580 APFloat Val = Value;
581
582 bool Ignored;
583 if (&FloatSema != OpSema)
584 Val.convert(*OpSema, LosslessRM, &Ignored);
585
586 // Scale up the float so that the 'fractional' part of the mantissa ends up in
587 // the integer range instead. Rounding mode is irrelevant here.
588 // It is fine if this overflows to infinity even for saturating types,
589 // since we will use floating point comparisons to check for saturation.
590 APFloat ScaleFactor(std::pow(2, -DstFXSema.getLsbWeight()));
591 ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
592 Val.multiply(ScaleFactor, LosslessRM);
593
594 // Convert to the integral representation of the value. This rounding mode
595 // is significant.
596 APSInt Res(DstFXSema.getWidth(), !DstFXSema.isSigned());
597 Val.convertToInteger(Res, RM, &Ignored);
598
599 // Round the integral value and scale back. This makes the
600 // overflow calculations below work properly. If we do not round here,
601 // we risk checking for overflow with a value that is outside the
602 // representable range of the fixed-point semantic even though no overflow
603 // would occur had we rounded first.
604 ScaleFactor = APFloat(std::pow(2, DstFXSema.getLsbWeight()));
605 ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
606 Val.roundToIntegral(RM);
607 Val.multiply(ScaleFactor, LosslessRM);
608
609 // Check for overflow/saturation by checking if the floating point value
610 // is outside the range representable by the fixed-point value.
611 APFloat FloatMax = getMax(DstFXSema).convertToFloat(*OpSema);
612 APFloat FloatMin = getMin(DstFXSema).convertToFloat(*OpSema);
613 bool Overflowed = false;
614 if (DstFXSema.isSaturated()) {
615 if (Val > FloatMax)
616 Res = getMax(DstFXSema).getValue();
617 else if (Val < FloatMin)
618 Res = getMin(DstFXSema).getValue();
619 } else {
620 Overflowed = Val > FloatMax || Val < FloatMin;
621 }
622
623 if (Overflow)
624 *Overflow = Overflowed;
625
626 return APFixedPoint(Res, DstFXSema);
627}
628
629} // namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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:638
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
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:163
LLVM_ABI APFixedPoint convert(const FixedPointSemantics &DstSema, bool *Overflow=nullptr) const
static LLVM_ABI APFixedPoint getMin(const FixedPointSemantics &Sema)
int getLsbWeight() const
Definition: APFixedPoint.h:182
LLVM_ABI int compare(const APFixedPoint &Other) const
LLVM_ABI APSInt convertToInt(unsigned DstWidth, bool DstSign, bool *Overflow=nullptr) const
Return the integral part of this fixed point number, rounded towards zero.
static LLVM_ABI 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,...
LLVM_ABI APFixedPoint sub(const APFixedPoint &Other, bool *Overflow=nullptr) const
LLVM_ABI APFloat convertToFloat(const fltSemantics &FloatSema) const
Convert this fixed point number to a floating point value with the provided semantics.
LLVM_DUMP_METHOD void dump() const
static LLVM_ABI 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:250
LLVM_ABI void print(raw_ostream &) const
APSInt getValue() const
Definition: APFixedPoint.h:179
unsigned getWidth() const
Definition: APFixedPoint.h:180
bool isSigned() const
Definition: APFixedPoint.h:185
LLVM_ABI APFixedPoint negate(bool *Overflow=nullptr) const
Perform a unary negation (-X) on this fixed point type, taking into account saturation if applicable.
LLVM_ABI APFixedPoint shl(unsigned Amt, bool *Overflow=nullptr) const
bool isSaturated() const
Definition: APFixedPoint.h:184
static LLVM_ABI APFixedPoint getEpsilon(const FixedPointSemantics &Sema)
static LLVM_ABI const fltSemantics * promoteFloatSemantics(const fltSemantics *S)
Given a floating point semantic, return the next floating point semantic with a larger exponent and l...
LLVM_ABI APFixedPoint div(const APFixedPoint &Other, bool *Overflow=nullptr) const
LLVM_ABI 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:227
LLVM_ABI APFixedPoint add(const APFixedPoint &Other, bool *Overflow=nullptr) const
int getMsbWeight() const
Definition: APFixedPoint.h:183
static LLVM_ABI APFixedPoint getMax(const FixedPointSemantics &Sema)
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition: APFloat.cpp:6057
opStatus multiply(const APFloat &RHS, roundingMode RM)
Definition: APFloat.h:1199
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Definition: APFloat.h:1332
opStatus roundToIntegral(roundingMode RM)
Definition: APFloat.h:1248
Class for arbitrary precision integers.
Definition: APInt.h:78
LLVM_ABI APInt umul_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1971
LLVM_ABI APInt usub_sat(const APInt &RHS) const
Definition: APInt.cpp:2055
LLVM_ABI APInt udiv(const APInt &RHS) const
Unsigned division operation.
Definition: APInt.cpp:1573
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition: APInt.h:234
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition: APInt.cpp:1012
bool isMinSignedValue() const
Determine if this is the smallest signed value.
Definition: APInt.h:423
static LLVM_ABI void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
Definition: APInt.cpp:1890
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition: APInt.cpp:1033
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
LLVM_ABI APInt sadd_sat(const APInt &RHS) const
Definition: APInt.cpp:2026
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition: APInt.h:1201
LLVM_ABI APInt usub_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1948
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:1488
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition: APInt.h:1111
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1928
APInt relativeAShl(int RelativeShift) const
relative arithmetic shift left
Definition: APInt.h:895
LLVM_ABI APInt uadd_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1935
LLVM_ABI APInt uadd_sat(const APInt &RHS) const
Definition: APInt.cpp:2036
LLVM_ABI APInt smul_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1960
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
Definition: APInt.cpp:985
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
LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const
Definition: APInt.cpp:1941
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
LLVM_ABI APInt ssub_sat(const APInt &RHS) const
Definition: APInt.cpp:2045
An arbitrary precision integer that knows its signedness.
Definition: APSInt.h:24
APSInt extOrTrunc(uint32_t width) const
Definition: APSInt.h:120
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:312
static APSInt get(int64_t X)
Definition: APSInt.h:350
bool isNegative() const
Determine sign of this APSInt.
Definition: APSInt.h:50
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:304
void setIsSigned(bool Val)
Definition: APSInt.h:81
APSInt relativeShl(unsigned Amt) const
Definition: APSInt.h:218
void setIsUnsigned(bool Val)
Definition: APSInt.h:80
APSInt extend(uint32_t width) const
Definition: APSInt.h:113
bool isSigned() const
Definition: APSInt.h:78
The fixed point semantics work similarly to fltSemantics.
Definition: APFixedPoint.h:35
static LLVM_ABI FixedPointSemantics getFromOpaqueInt(uint32_t)
Create a FixedPointSemantics object from an integer created via toOpaqueInt().
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
LLVM_ABI FixedPointSemantics getCommonSemantics(const FixedPointSemantics &Other) const
Return the FixedPointSemantics that allows for calculating the full precision semantic that can preci...
LLVM_ABI void print(llvm::raw_ostream &OS) const
Print semantics for debug purposes.
LLVM_ABI 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
LLVM_ABI 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: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:574
LLVM Value Representation.
Definition: Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
#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
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Other
Any other memory.
RoundingMode
Rounding mode.
static LLVM_ABI const fltSemantics & IEEEsingle() LLVM_READNONE
Definition: APFloat.cpp:266
static constexpr roundingMode rmNearestTiesToAway
Definition: APFloat.h:309
static constexpr roundingMode rmNearestTiesToEven
Definition: APFloat.h:304
static constexpr roundingMode rmTowardZero
Definition: APFloat.h:308
static LLVM_ABI const fltSemantics & IEEEquad() LLVM_READNONE
Definition: APFloat.cpp:268
static LLVM_ABI const fltSemantics & IEEEdouble() LLVM_READNONE
Definition: APFloat.cpp:267
static LLVM_ABI const fltSemantics & IEEEhalf() LLVM_READNONE
Definition: APFloat.cpp:264
static LLVM_ABI const fltSemantics & BFloat() LLVM_READNONE
Definition: APFloat.cpp:265
opStatus
IEEE-754R 7: Default exception handling.
Definition: APFloat.h:320
Used to differentiate between constructors with Width and Lsb from the default Width and scale.
Definition: APFixedPoint.h:41