diff options
author | Chris Lattner <sabre@nondot.org> | 2010-10-13 23:46:33 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-10-13 23:46:33 +0000 |
commit | f2ddc64c8701e432cc220f26c48d596cc0f30a97 (patch) | |
tree | 60d171d48d09077977109d838b4df9f7134e5f50 /lib/Support/APInt.cpp | |
parent | 95369599c61ab1b35ae3afe349763b886225c5be (diff) |
add a few operations for signed operations that also
return an overflow flag.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116452 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/APInt.cpp')
-rw-r--r-- | lib/Support/APInt.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 8a212a291f..51203f6091 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -2046,6 +2046,52 @@ void APInt::udivrem(const APInt &LHS, const APInt &RHS, divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder); } +APInt APInt::sadd_ov(const APInt &RHS, bool &Overflow) { + APInt Res = *this+RHS; + Overflow = isNonNegative() == RHS.isNonNegative() && + Res.isNonNegative() != isNonNegative(); + return Res; +} + +APInt APInt::ssub_ov(const APInt &RHS, bool &Overflow) { + APInt Res = *this - RHS; + Overflow = isNonNegative() != RHS.isNonNegative() && + Res.isNonNegative() != isNonNegative(); + return Res; +} + +APInt APInt::sdiv_ov(const APInt &RHS, bool &Overflow) { + // MININT/-1 --> overflow. + Overflow = isMinSignedValue() && RHS.isAllOnesValue(); + return sdiv(RHS); +} + +APInt APInt::smul_ov(const APInt &RHS, bool &Overflow) { + APInt Res = *this * RHS; + + if (*this != 0 && RHS != 0) + Overflow = Res.sdiv(RHS) != *this || Res.sdiv(*this) != RHS; + else + Overflow = false; + return Res; +} + +APInt APInt::sshl_ov(unsigned ShAmt, bool &Overflow) { + Overflow = ShAmt >= getBitWidth(); + if (Overflow) + ShAmt = getBitWidth()-1; + + if (isNonNegative()) // Don't allow sign change. + Overflow = ShAmt >= countLeadingZeros(); + else + Overflow = ShAmt >= countLeadingOnes(); + + return *this << ShAmt; +} + + + + void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) { // Check our assumptions here assert(!str.empty() && "Invalid string length"); |