X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FAPInt.cpp;h=50a639cc51e84975d4c432e7454381a9e57bf54e;hb=8617b3bb3e7b95c27f3ffa7220a2b7754d918adb;hp=91895f360a11e0223fc31f4bbe206d347510dbb3;hpb=338692246d5a764f202e2a1a1c9c3398e186fb3e;p=oota-llvm.git diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 91895f360a1..50a639cc51e 100644 --- a/lib/Support/APInt.cpp +++ b/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 { @@ -709,7 +713,7 @@ unsigned APInt::countLeadingZerosSlowCase() const { unsigned APInt::countLeadingOnes() const { if (isSingleWord()) - return CountLeadingOnes_64(VAL << (APINT_BITS_PER_WORD - BitWidth)); + return llvm::countLeadingOnes(VAL << (APINT_BITS_PER_WORD - BitWidth)); unsigned highWordBits = BitWidth % APINT_BITS_PER_WORD; unsigned shift; @@ -720,13 +724,13 @@ unsigned APInt::countLeadingOnes() const { shift = APINT_BITS_PER_WORD - highWordBits; } int i = getNumWords() - 1; - unsigned Count = CountLeadingOnes_64(pVal[i] << shift); + unsigned Count = llvm::countLeadingOnes(pVal[i] << shift); if (Count == highWordBits) { for (i--; i >= 0; --i) { if (pVal[i] == -1ULL) Count += APINT_BITS_PER_WORD; else { - Count += CountLeadingOnes_64(pVal[i]); + Count += llvm::countLeadingOnes(pVal[i]); break; } } @@ -752,14 +756,14 @@ unsigned APInt::countTrailingOnesSlowCase() const { for (; i < getNumWords() && pVal[i] == -1ULL; ++i) Count += APINT_BITS_PER_WORD; if (i < getNumWords()) - Count += CountTrailingOnes_64(pVal[i]); + Count += llvm::countTrailingOnes(pVal[i]); return std::min(Count, BitWidth); } unsigned APInt::countPopulationSlowCase() const { unsigned Count = 0; for (unsigned i = 0; i < getNumWords(); ++i) - Count += CountPopulation_64(pVal[i]); + Count += llvm::countPopulation(pVal[i]); return Count; } @@ -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 { @@ -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 {