diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/Support/APInt.cpp | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r-- | llvm/lib/Support/APInt.cpp | 79 |
1 files changed, 76 insertions, 3 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 758fe8b4f866..9b9cd70078b3 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -187,7 +187,7 @@ APInt& APInt::operator--() { return clearUnusedBits(); } -/// Adds the RHS APint to this APInt. +/// Adds the RHS APInt to this APInt. /// @returns this, after addition of RHS. /// Addition assignment operator. APInt& APInt::operator+=(const APInt& RHS) { @@ -884,6 +884,31 @@ APInt APInt::trunc(unsigned width) const { return Result; } +// Truncate to new width with unsigned saturation. +APInt APInt::truncUSat(unsigned width) const { + assert(width < BitWidth && "Invalid APInt Truncate request"); + assert(width && "Can't truncate to 0 bits"); + + // Can we just losslessly truncate it? + if (isIntN(width)) + return trunc(width); + // If not, then just return the new limit. + return APInt::getMaxValue(width); +} + +// Truncate to new width with signed saturation. +APInt APInt::truncSSat(unsigned width) const { + assert(width < BitWidth && "Invalid APInt Truncate request"); + assert(width && "Can't truncate to 0 bits"); + + // Can we just losslessly truncate it? + if (isSignedIntN(width)) + return trunc(width); + // If not, then just return the new limits. + return isNegative() ? APInt::getSignedMinValue(width) + : APInt::getSignedMaxValue(width); +} + // Sign extend to a new width. APInt APInt::sext(unsigned Width) const { assert(Width > BitWidth && "Invalid APInt SignExtend request"); @@ -2048,6 +2073,46 @@ APInt APInt::usub_sat(const APInt &RHS) const { return APInt(BitWidth, 0); } +APInt APInt::smul_sat(const APInt &RHS) const { + bool Overflow; + APInt Res = smul_ov(RHS, Overflow); + if (!Overflow) + return Res; + + // The result is negative if one and only one of inputs is negative. + bool ResIsNegative = isNegative() ^ RHS.isNegative(); + + return ResIsNegative ? APInt::getSignedMinValue(BitWidth) + : APInt::getSignedMaxValue(BitWidth); +} + +APInt APInt::umul_sat(const APInt &RHS) const { + bool Overflow; + APInt Res = umul_ov(RHS, Overflow); + if (!Overflow) + return Res; + + return APInt::getMaxValue(BitWidth); +} + +APInt APInt::sshl_sat(const APInt &RHS) const { + bool Overflow; + APInt Res = sshl_ov(RHS, Overflow); + if (!Overflow) + return Res; + + return isNegative() ? APInt::getSignedMinValue(BitWidth) + : APInt::getSignedMaxValue(BitWidth); +} + +APInt APInt::ushl_sat(const APInt &RHS) const { + bool Overflow; + APInt Res = ushl_ov(RHS, Overflow); + if (!Overflow) + return Res; + + return APInt::getMaxValue(BitWidth); +} void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) { // Check our assumptions here @@ -2790,7 +2855,7 @@ APInt llvm::APIntOps::RoundingSDiv(const APInt &A, const APInt &B, return Quo; return Quo + 1; } - // Currently sdiv rounds twards zero. + // Currently sdiv rounds towards zero. case APInt::Rounding::TOWARD_ZERO: return A.sdiv(B); } @@ -2933,7 +2998,7 @@ llvm::APIntOps::SolveQuadraticEquationWrap(APInt A, APInt B, APInt C, APInt Q = SQ * SQ; bool InexactSQ = Q != D; // The calculated SQ may actually be greater than the exact (non-integer) - // value. If that's the case, decremement SQ to get a value that is lower. + // value. If that's the case, decrement SQ to get a value that is lower. if (Q.sgt(D)) SQ -= 1; @@ -2987,6 +3052,14 @@ llvm::APIntOps::SolveQuadraticEquationWrap(APInt A, APInt B, APInt C, return X; } +Optional<unsigned> +llvm::APIntOps::GetMostSignificantDifferentBit(const APInt &A, const APInt &B) { + assert(A.getBitWidth() == B.getBitWidth() && "Must have the same bitwidth"); + if (A == B) + return llvm::None; + return A.getBitWidth() - ((A ^ B).countLeadingZeros() + 1); +} + /// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst /// with the integer held in IntVal. void llvm::StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, |