From f2ddc64c8701e432cc220f26c48d596cc0f30a97 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 13 Oct 2010 23:46:33 +0000 Subject: 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 --- lib/Support/APInt.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'lib/Support/APInt.cpp') 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"); -- cgit v1.2.3-18-g5258