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
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
The APFixedPoint class works similarly to APInt/APSInt in that it is a functional replacement for a s...
LLVM_ABI APFixedPoint convert(const FixedPointSemantics &DstSema, bool *Overflow=nullptr) const
APFixedPoint(const APInt &Val, const FixedPointSemantics &Sema)
static LLVM_ABI APFixedPoint getMin(const FixedPointSemantics &Sema)
int getLsbWeight() const
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
LLVM_ABI void print(raw_ostream &) const
APSInt getValue() const
unsigned getWidth() const
bool isSigned() const
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
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.
LLVM_ABI APFixedPoint add(const APFixedPoint &Other, bool *Overflow=nullptr) const
int getMsbWeight() const
static LLVM_ABI APFixedPoint getMax(const FixedPointSemantics &Sema)
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition APFloat.cpp:6057
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
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
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
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
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.
static LLVM_ABI FixedPointSemantics getFromOpaqueInt(uint32_t)
Create a FixedPointSemantics object from an integer created via toOpaqueInt().
unsigned getWidth() const
bool hasUnsignedPadding() const
unsigned getScale() const
unsigned getIntegralBits() const
Return the number of integral bits represented by these semantics.
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
LLVM_ABI uint32_t toOpaqueInt() const
Convert the semantics to a 32-bit unsigned integer.
FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned, bool IsSaturated, bool HasUnsignedPadding)
bool isValidLegacySema() const
Check if the Semantic follow the requirements of an older more limited version of this class.
static FixedPointSemantics GetIntegerSemantics(unsigned Width, bool IsSigned)
Return the FixedPointSemantics for an integer type.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Other
Any other memory.
Definition ModRef.h:68
To bit_cast(const From &from) noexcept
Definition bit.h:90
static LLVM_ABI const fltSemantics & IEEEsingle() LLVM_READNONE
Definition APFloat.cpp:266
static constexpr roundingMode rmNearestTiesToAway
Definition APFloat.h:309
llvm::RoundingMode roundingMode
IEEE-754R 4.3: Rounding-direction attributes.
Definition APFloat.h:302
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.