diff options
Diffstat (limited to 'contrib/llvm/lib/Support/APInt.cpp')
-rw-r--r-- | contrib/llvm/lib/Support/APInt.cpp | 75 |
1 files changed, 57 insertions, 18 deletions
diff --git a/contrib/llvm/lib/Support/APInt.cpp b/contrib/llvm/lib/Support/APInt.cpp index fa929eb..0ddc2ab 100644 --- a/contrib/llvm/lib/Support/APInt.cpp +++ b/contrib/llvm/lib/Support/APInt.cpp @@ -454,8 +454,10 @@ APInt APInt::XorSlowCase(const APInt& RHS) const { for (unsigned i = 0; i < numWords; ++i) val[i] = pVal[i] ^ RHS.pVal[i]; + APInt Result(val, getBitWidth()); // 0^0==1 so clear the high bits in case they got set. - return APInt(val, getBitWidth()).clearUnusedBits(); + Result.clearUnusedBits(); + return Result; } APInt APInt::operator*(const APInt& RHS) const { @@ -473,7 +475,8 @@ APInt APInt::operator+(const APInt& RHS) const { return APInt(BitWidth, VAL + RHS.VAL); APInt Result(BitWidth, 0); add(Result.pVal, this->pVal, RHS.pVal, getNumWords()); - return Result.clearUnusedBits(); + Result.clearUnusedBits(); + return Result; } APInt APInt::operator-(const APInt& RHS) const { @@ -482,7 +485,8 @@ APInt APInt::operator-(const APInt& RHS) const { return APInt(BitWidth, VAL - RHS.VAL); APInt Result(BitWidth, 0); sub(Result.pVal, this->pVal, RHS.pVal, getNumWords()); - return Result.clearUnusedBits(); + Result.clearUnusedBits(); + return Result; } bool APInt::EqualSlowCase(const APInt& RHS) const { @@ -1114,7 +1118,9 @@ APInt APInt::ashr(unsigned shiftAmt) const { uint64_t fillValue = (isNegative() ? -1ULL : 0); for (unsigned i = breakWord+1; i < getNumWords(); ++i) val[i] = fillValue; - return APInt(val, BitWidth).clearUnusedBits(); + APInt Result(val, BitWidth); + Result.clearUnusedBits(); + return Result; } /// Logical right-shift this APInt by shiftAmt. @@ -1151,7 +1157,9 @@ APInt APInt::lshr(unsigned shiftAmt) const { // If we are shifting less than a word, compute the shift with a simple carry if (shiftAmt < APINT_BITS_PER_WORD) { lshrNear(val, pVal, getNumWords(), shiftAmt); - return APInt(val, BitWidth).clearUnusedBits(); + APInt Result(val, BitWidth); + Result.clearUnusedBits(); + return Result; } // Compute some values needed by the remaining shift algorithms @@ -1164,7 +1172,9 @@ APInt APInt::lshr(unsigned shiftAmt) const { val[i] = pVal[i+offset]; for (unsigned i = getNumWords()-offset; i < getNumWords(); i++) val[i] = 0; - return APInt(val,BitWidth).clearUnusedBits(); + APInt Result(val, BitWidth); + Result.clearUnusedBits(); + return Result; } // Shift the low order words @@ -1178,7 +1188,9 @@ APInt APInt::lshr(unsigned shiftAmt) const { // Remaining words are 0 for (unsigned i = breakWord+1; i < getNumWords(); ++i) val[i] = 0; - return APInt(val, BitWidth).clearUnusedBits(); + APInt Result(val, BitWidth); + Result.clearUnusedBits(); + return Result; } /// Left-shift this APInt by shiftAmt. @@ -1211,7 +1223,9 @@ APInt APInt::shlSlowCase(unsigned shiftAmt) const { val[i] = pVal[i] << shiftAmt | carry; carry = pVal[i] >> (APINT_BITS_PER_WORD - shiftAmt); } - return APInt(val, BitWidth).clearUnusedBits(); + APInt Result(val, BitWidth); + Result.clearUnusedBits(); + return Result; } // Compute some values needed by the remaining shift algorithms @@ -1224,7 +1238,9 @@ APInt APInt::shlSlowCase(unsigned shiftAmt) const { val[i] = 0; for (unsigned i = offset; i < getNumWords(); i++) val[i] = pVal[i-offset]; - return APInt(val,BitWidth).clearUnusedBits(); + APInt Result(val, BitWidth); + Result.clearUnusedBits(); + return Result; } // Copy whole words from this to Result. @@ -1235,7 +1251,9 @@ APInt APInt::shlSlowCase(unsigned shiftAmt) const { val[offset] = pVal[0] << wordShift; for (i = 0; i < offset; ++i) val[i] = 0; - return APInt(val, BitWidth).clearUnusedBits(); + APInt Result(val, BitWidth); + Result.clearUnusedBits(); + return Result; } APInt APInt::rotl(const APInt &rotateAmt) const { @@ -1303,7 +1321,7 @@ APInt APInt::sqrt() const { // Okay, all the short cuts are exhausted. We must compute it. The following // is a classical Babylonian method for computing the square root. This code - // was adapted to APINt from a wikipedia article on such computations. + // was adapted to APInt from a wikipedia article on such computations. // See http://www.wikipedia.org/ and go to the page named // Calculate_an_integer_square_root. unsigned nbits = BitWidth, i = 4; @@ -1938,6 +1956,18 @@ APInt APInt::srem(const APInt &RHS) const { void APInt::udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder) { + assert(LHS.BitWidth == RHS.BitWidth && "Bit widths must be the same"); + + // First, deal with the easy case + if (LHS.isSingleWord()) { + assert(RHS.VAL != 0 && "Divide by zero?"); + uint64_t QuotVal = LHS.VAL / RHS.VAL; + uint64_t RemVal = LHS.VAL % RHS.VAL; + Quotient = APInt(LHS.BitWidth, QuotVal); + Remainder = APInt(LHS.BitWidth, RemVal); + return; + } + // Get some size facts about the dividend and divisor unsigned lhsBits = LHS.getActiveBits(); unsigned lhsWords = !lhsBits ? 0 : (APInt::whichWord(lhsBits - 1) + 1); @@ -2046,19 +2076,29 @@ APInt APInt::umul_ov(const APInt &RHS, bool &Overflow) const { return Res; } -APInt APInt::sshl_ov(unsigned ShAmt, bool &Overflow) const { - Overflow = ShAmt >= getBitWidth(); +APInt APInt::sshl_ov(const APInt &ShAmt, bool &Overflow) const { + Overflow = ShAmt.uge(getBitWidth()); if (Overflow) - ShAmt = getBitWidth()-1; + return APInt(BitWidth, 0); if (isNonNegative()) // Don't allow sign change. - Overflow = ShAmt >= countLeadingZeros(); + Overflow = ShAmt.uge(countLeadingZeros()); else - Overflow = ShAmt >= countLeadingOnes(); + Overflow = ShAmt.uge(countLeadingOnes()); return *this << ShAmt; } +APInt APInt::ushl_ov(const APInt &ShAmt, bool &Overflow) const { + Overflow = ShAmt.uge(getBitWidth()); + if (Overflow) + return APInt(BitWidth, 0); + + Overflow = ShAmt.ugt(countLeadingZeros()); + + return *this << ShAmt; +} + @@ -2270,8 +2310,7 @@ void APInt::print(raw_ostream &OS, bool isSigned) const { // Assumed by lowHalf, highHalf, partMSB and partLSB. A fairly safe // and unrestricting assumption. -#define COMPILE_TIME_ASSERT(cond) extern int CTAssert[(cond) ? 1 : -1] -COMPILE_TIME_ASSERT(integerPartWidth % 2 == 0); +static_assert(integerPartWidth % 2 == 0, "Part width must be divisible by 2!"); /* Some handy functions local to this file. */ namespace { |