summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Support/APInt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support/APInt.cpp')
-rw-r--r--contrib/llvm/lib/Support/APInt.cpp150
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;
OpenPOWER on IntegriCloud