diff options
Diffstat (limited to 'contrib/llvm/lib/Support/APInt.cpp')
-rw-r--r-- | contrib/llvm/lib/Support/APInt.cpp | 150 |
1 files changed, 78 insertions, 72 deletions
diff --git a/contrib/llvm/lib/Support/APInt.cpp b/contrib/llvm/lib/Support/APInt.cpp index 23f89bb..66eee99 100644 --- a/contrib/llvm/lib/Support/APInt.cpp +++ b/contrib/llvm/lib/Support/APInt.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/APInt.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallString.h" @@ -74,7 +75,7 @@ inline static unsigned getDigit(char cdigit, uint8_t radix) { } -void APInt::initSlowCase(unsigned numBits, uint64_t val, bool isSigned) { +void APInt::initSlowCase(uint64_t val, bool isSigned) { pVal = getClearedMemory(getNumWords()); pVal[0] = val; if (isSigned && int64_t(val) < 0) @@ -479,6 +480,15 @@ APInt APInt::operator+(const APInt& RHS) const { return Result; } +APInt APInt::operator+(uint64_t RHS) const { + if (isSingleWord()) + return APInt(BitWidth, VAL + RHS); + APInt Result(*this); + add_1(Result.pVal, Result.pVal, getNumWords(), RHS); + Result.clearUnusedBits(); + return Result; +} + APInt APInt::operator-(const APInt& RHS) const { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); if (isSingleWord()) @@ -489,24 +499,17 @@ APInt APInt::operator-(const APInt& RHS) const { return Result; } -bool APInt::EqualSlowCase(const APInt& RHS) const { - // Get some facts about the number of bits used in the two operands. - unsigned n1 = getActiveBits(); - unsigned n2 = RHS.getActiveBits(); - - // If the number of bits isn't the same, they aren't equal - if (n1 != n2) - return false; - - // If the number of bits fits in a word, we only need to compare the low word. - if (n1 <= APINT_BITS_PER_WORD) - return pVal[0] == RHS.pVal[0]; +APInt APInt::operator-(uint64_t RHS) const { + if (isSingleWord()) + return APInt(BitWidth, VAL - RHS); + APInt Result(*this); + sub_1(Result.pVal, getNumWords(), RHS); + Result.clearUnusedBits(); + return Result; +} - // Otherwise, compare everything - for (int i = whichWord(n1 - 1); i >= 0; --i) - if (pVal[i] != RHS.pVal[i]) - return false; - return true; +bool APInt::EqualSlowCase(const APInt& RHS) const { + return std::equal(pVal, pVal + getNumWords(), RHS.pVal); } bool APInt::EqualSlowCase(uint64_t Val) const { @@ -552,37 +555,21 @@ bool APInt::ult(const APInt& RHS) const { bool APInt::slt(const APInt& RHS) const { assert(BitWidth == RHS.BitWidth && "Bit widths must be same for comparison"); if (isSingleWord()) { - int64_t lhsSext = (int64_t(VAL) << (64-BitWidth)) >> (64-BitWidth); - int64_t rhsSext = (int64_t(RHS.VAL) << (64-BitWidth)) >> (64-BitWidth); + int64_t lhsSext = SignExtend64(VAL, BitWidth); + int64_t rhsSext = SignExtend64(RHS.VAL, BitWidth); return lhsSext < rhsSext; } - APInt lhs(*this); - APInt rhs(RHS); bool lhsNeg = isNegative(); - bool rhsNeg = rhs.isNegative(); - if (lhsNeg) { - // Sign bit is set so perform two's complement to make it positive - lhs.flipAllBits(); - ++lhs; - } - if (rhsNeg) { - // Sign bit is set so perform two's complement to make it positive - rhs.flipAllBits(); - ++rhs; - } - - // Now we have unsigned values to compare so do the comparison if necessary - // based on the negativeness of the values. - if (lhsNeg) - if (rhsNeg) - return lhs.ugt(rhs); - else - return true; - else if (rhsNeg) - return false; - else - return lhs.ult(rhs); + bool rhsNeg = RHS.isNegative(); + + // If the sign bits don't match, then (LHS < RHS) if LHS is negative + if (lhsNeg != rhsNeg) + return lhsNeg; + + // Otherwise we can just use an unsigned comparision, because even negative + // numbers compare correctly this way if both have the same signed-ness. + return ult(RHS); } void APInt::setBit(unsigned bitPosition) { @@ -692,30 +679,19 @@ APInt APInt::getLoBits(unsigned numBits) const { } unsigned APInt::countLeadingZerosSlowCase() const { - // Treat the most significand word differently because it might have - // meaningless bits set beyond the precision. - unsigned BitsInMSW = BitWidth % APINT_BITS_PER_WORD; - integerPart MSWMask; - if (BitsInMSW) MSWMask = (integerPart(1) << BitsInMSW) - 1; - else { - MSWMask = ~integerPart(0); - BitsInMSW = APINT_BITS_PER_WORD; - } - - unsigned i = getNumWords(); - integerPart MSW = pVal[i-1] & MSWMask; - if (MSW) - return llvm::countLeadingZeros(MSW) - (APINT_BITS_PER_WORD - BitsInMSW); - - unsigned Count = BitsInMSW; - for (--i; i > 0u; --i) { - if (pVal[i-1] == 0) + unsigned Count = 0; + for (int i = getNumWords()-1; i >= 0; --i) { + integerPart V = pVal[i]; + if (V == 0) Count += APINT_BITS_PER_WORD; else { - Count += llvm::countLeadingZeros(pVal[i-1]); + Count += llvm::countLeadingZeros(V); break; } } + // Adjust for unused bits in the most significant word (they are zero). + unsigned Mod = BitWidth % APINT_BITS_PER_WORD; + Count -= Mod > 0 ? APINT_BITS_PER_WORD - Mod : 0; return Count; } @@ -814,6 +790,36 @@ APInt APInt::byteSwap() const { return Result; } +APInt APInt::reverseBits() const { + switch (BitWidth) { + case 64: + return APInt(BitWidth, llvm::reverseBits<uint64_t>(VAL)); + case 32: + return APInt(BitWidth, llvm::reverseBits<uint32_t>(VAL)); + case 16: + return APInt(BitWidth, llvm::reverseBits<uint16_t>(VAL)); + case 8: + return APInt(BitWidth, llvm::reverseBits<uint8_t>(VAL)); + default: + break; + } + + APInt Val(*this); + APInt Reversed(*this); + int S = BitWidth - 1; + + const APInt One(BitWidth, 1); + + for ((Val = Val.lshr(1)); Val != 0; (Val = Val.lshr(1))) { + Reversed <<= 1; + Reversed |= (Val & One); + --S; + } + + Reversed <<= S; + return Reversed; +} + APInt llvm::APIntOps::GreatestCommonDivisor(const APInt& API1, const APInt& API2) { APInt A = API1, B = API2; @@ -874,7 +880,7 @@ double APInt::roundToDouble(bool isSigned) const { // It is wrong to optimize getWord(0) to VAL; there might be more than one word. if (isSingleWord() || getActiveBits() <= APINT_BITS_PER_WORD) { if (isSigned) { - int64_t sext = (int64_t(getWord(0)) << (64-BitWidth)) >> (64-BitWidth); + int64_t sext = SignExtend64(getWord(0), BitWidth); return double(sext); } else return double(getWord(0)); @@ -1658,10 +1664,8 @@ static void KnuthDiv(unsigned *u, unsigned *v, unsigned *q, unsigned* r, DEBUG(dbgs() << '\n'); } -void APInt::divide(const APInt LHS, unsigned lhsWords, - const APInt &RHS, unsigned rhsWords, - APInt *Quotient, APInt *Remainder) -{ +void APInt::divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS, + unsigned rhsWords, APInt *Quotient, APInt *Remainder) { assert(lhsWords >= rhsWords && "Fractional result"); // First, compose the values into an array of 32-bit words instead of @@ -2268,7 +2272,7 @@ std::string APInt::toString(unsigned Radix = 10, bool Signed = true) const { } -void APInt::dump() const { +LLVM_DUMP_METHOD void APInt::dump() const { SmallString<40> S, U; this->toStringUnsigned(U); this->toStringSigned(S); @@ -2725,8 +2729,10 @@ APInt::tcDivide(integerPart *lhs, const integerPart *rhs, break; shiftCount--; tcShiftRight(srhs, parts, 1); - if ((mask >>= 1) == 0) - mask = (integerPart) 1 << (integerPartWidth - 1), n--; + if ((mask >>= 1) == 0) { + mask = (integerPart) 1 << (integerPartWidth - 1); + n--; + } } return false; |