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 | 79bdd88fa4dcba91091ce6f631b86ea13eb2a954 (patch) | |
tree | 264d6b418f9539d99eed185c7d76821bc3d33442 /llvm/lib/Support/APInt.cpp | |
parent | 340cd5174b78ef41f74edb42cb3e847c408d05b4 (diff) | |
download | bcm5719-llvm-79bdd88fa4dcba91091ce6f631b86ea13eb2a954.tar.gz bcm5719-llvm-79bdd88fa4dcba91091ce6f631b86ea13eb2a954.zip |
add a few operations for signed operations that also
return an overflow flag.
llvm-svn: 116452
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r-- | llvm/lib/Support/APInt.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 8a212a291f2..51203f6091d 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/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"); |