diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2007-02-16 22:36:51 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2007-02-16 22:36:51 +0000 |
commit | e81d2dad2c54014d36c73573307db5852c5caf8e (patch) | |
tree | 5875211881cbeea392a2f3ec6657fd8990ee675e /lib/Support/APInt.cpp | |
parent | ae6f1fa36b020c89b0f44c4b4222d0f5fd9b6326 (diff) |
Review changes:
1. Function style changes.
2. 80-col violations.
3. Better names for things.
4. Arrange constructors so they all take bit width first.
5. Add named signed and unsigned comparison functions and remove the
corresponding operators.
6. Remove operator&& and operator|| but provide a getBoolValue function which
converts to bool as comparison against 0. This allows the normal && and
|| operators to be used as if (X.getBoolValue() && Y.getBoolValue())
Note: this still doesn't function 100% yet. I'm working on the bugs now.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34353 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/APInt.cpp')
-rw-r--r-- | lib/Support/APInt.cpp | 369 |
1 files changed, 183 insertions, 186 deletions
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 8989b01af8..7f18ca28b4 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -241,6 +241,7 @@ static void div(unsigned zds[], unsigned nx, unsigned y[], unsigned ny) { } while (--j >= ny); } +#if 0 /// lshift - This function shift x[0:len-1] left by shiftAmt bits, and /// store the len least significant words of the result in /// dest[d_offset:d_offset+len-1]. It returns the bits shifted out from @@ -259,13 +260,14 @@ static uint64_t lshift(uint64_t dest[], unsigned d_offset, dest[d_offset+i] = high_word << shiftAmt; return retVal; } +#endif -APInt::APInt(uint64_t val, unsigned numBits) - : BitsNum(numBits) { - assert(BitsNum >= IntegerType::MIN_INT_BITS && "bitwidth too small"); - assert(BitsNum <= IntegerType::MAX_INT_BITS && "bitwidth too large"); +APInt::APInt(unsigned numBits, uint64_t val) + : BitWidth(numBits) { + assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small"); + assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large"); if (isSingleWord()) - VAL = val & (~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitsNum)); + VAL = val & (~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitWidth)); else { // Memory allocation and check if successful. assert((pVal = new uint64_t[getNumWords()]) && @@ -275,53 +277,54 @@ APInt::APInt(uint64_t val, unsigned numBits) } } -APInt::APInt(unsigned numBits, uint64_t bigVal[]) - : BitsNum(numBits) { - assert(BitsNum >= IntegerType::MIN_INT_BITS && "bitwidth too small"); - assert(BitsNum <= IntegerType::MAX_INT_BITS && "bitwidth too large"); +APInt::APInt(unsigned numBits, unsigned numWords, uint64_t bigVal[]) + : BitWidth(numBits) { + assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small"); + assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large"); assert(bigVal && "Null pointer detected!"); if (isSingleWord()) - VAL = bigVal[0] & (~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitsNum)); + VAL = bigVal[0] & (~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitWidth)); else { // Memory allocation and check if successful. assert((pVal = new uint64_t[getNumWords()]) && "APInt memory allocation fails!"); // Calculate the actual length of bigVal[]. - unsigned n = sizeof(*bigVal) / sizeof(bigVal[0]); - unsigned maxN = std::max<unsigned>(n, getNumWords()); - unsigned minN = std::min<unsigned>(n, getNumWords()); + unsigned maxN = std::max<unsigned>(numWords, getNumWords()); + unsigned minN = std::min<unsigned>(numWords, getNumWords()); memcpy(pVal, bigVal, (minN - 1) * 8); - pVal[minN-1] = bigVal[minN-1] & (~uint64_t(0ULL) >> (64 - BitsNum % 64)); + pVal[minN-1] = bigVal[minN-1] & (~uint64_t(0ULL) >> (64 - BitWidth % 64)); if (maxN == getNumWords()) - memset(pVal+n, 0, (getNumWords() - n) * 8); + memset(pVal+numWords, 0, (getNumWords() - numWords) * 8); } } /// @brief Create a new APInt by translating the char array represented /// integer value. -APInt::APInt(const char StrStart[], unsigned slen, uint8_t radix) { - StrToAPInt(StrStart, slen, radix); +APInt::APInt(unsigned numbits, const char StrStart[], unsigned slen, + uint8_t radix) { + fromString(numbits, StrStart, slen, radix); } /// @brief Create a new APInt by translating the string represented /// integer value. -APInt::APInt(const std::string& Val, uint8_t radix) { +APInt::APInt(unsigned numbits, const std::string& Val, uint8_t radix) { assert(!Val.empty() && "String empty?"); - StrToAPInt(Val.c_str(), Val.size(), radix); + fromString(numbits, Val.c_str(), Val.size(), radix); } /// @brief Converts a char array into an integer. -void APInt::StrToAPInt(const char *StrStart, unsigned slen, uint8_t radix) { +void APInt::fromString(unsigned numbits, const char *StrStart, unsigned slen, + uint8_t radix) { assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && "Radix should be 2, 8, 10, or 16!"); - assert(StrStart && "String empty?"); + assert(StrStart && "String is null?"); unsigned size = 0; // If the radix is a power of 2, read the input // from most significant to least significant. if ((radix & (radix - 1)) == 0) { unsigned nextBitPos = 0, bits_per_digit = radix / 8 + 2; uint64_t resDigit = 0; - BitsNum = slen * bits_per_digit; + BitWidth = slen * bits_per_digit; if (getNumWords() > 1) assert((pVal = new uint64_t[getNumWords()]) && "APInt memory allocation fails!"); @@ -348,10 +351,10 @@ void APInt::StrToAPInt(const char *StrStart, unsigned slen, uint8_t radix) { if (slen < chars_per_word || (slen == chars_per_word && // In case the value <= 2^64 - 1 strcmp(StrStart, "18446744073709551615") <= 0)) { - BitsNum = 64; + BitWidth = 64; VAL = strtoull(StrStart, 0, 10); } else { // In case the value > 2^64 - 1 - BitsNum = (slen / chars_per_word + 1) * 64; + BitWidth = (slen / chars_per_word + 1) * 64; assert((pVal = new uint64_t[getNumWords()]) && "APInt memory allocation fails!"); memset(pVal, 0, getNumWords() * 8); @@ -382,7 +385,7 @@ void APInt::StrToAPInt(const char *StrStart, unsigned slen, uint8_t radix) { } APInt::APInt(const APInt& APIVal) - : BitsNum(APIVal.BitsNum) { + : BitWidth(APIVal.BitWidth) { if (isSingleWord()) VAL = APIVal.VAL; else { // Memory allocation and check if successful. @@ -399,7 +402,9 @@ APInt::~APInt() { /// @brief Copy assignment operator. Create a new object from the given /// APInt one by initialization. APInt& APInt::operator=(const APInt& RHS) { - if (isSingleWord()) VAL = RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]; + assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + if (isSingleWord()) + VAL = RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]; else { unsigned minN = std::min(getNumWords(), RHS.getNumWords()); memcpy(pVal, RHS.isSingleWord() ? &RHS.VAL : RHS.pVal, minN * 8); @@ -412,21 +417,23 @@ APInt& APInt::operator=(const APInt& RHS) { /// @brief Assignment operator. Assigns a common case integer value to /// the APInt. APInt& APInt::operator=(uint64_t RHS) { - if (isSingleWord()) VAL = RHS; + if (isSingleWord()) + VAL = RHS; else { pVal[0] = RHS; memset(pVal, 0, (getNumWords() - 1) * 8); } - TruncToBits(); + clearUnusedBits(); return *this; } /// @brief Prefix increment operator. Increments the APInt by one. APInt& APInt::operator++() { - if (isSingleWord()) ++VAL; + if (isSingleWord()) + ++VAL; else add_1(pVal, pVal, getNumWords(), 1); - TruncToBits(); + clearUnusedBits(); return *this; } @@ -435,7 +442,7 @@ APInt& APInt::operator--() { if (isSingleWord()) --VAL; else sub_1(pVal, getNumWords(), 1); - TruncToBits(); + clearUnusedBits(); return *this; } @@ -455,7 +462,7 @@ APInt& APInt::operator+=(const APInt& RHS) { } } } - TruncToBits(); + clearUnusedBits(); return *this; } @@ -476,7 +483,7 @@ APInt& APInt::operator-=(const APInt& RHS) { sub(pVal, pVal, RHS.pVal, getNumWords()); } } - TruncToBits(); + clearUnusedBits(); return *this; } @@ -486,14 +493,14 @@ APInt& APInt::operator*=(const APInt& RHS) { if (isSingleWord()) VAL *= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]; else { // one-based first non-zero bit position. - unsigned first = getNumWords() * APINT_BITS_PER_WORD - CountLeadingZeros(); + unsigned first = getActiveBits(); unsigned xlen = !first ? 0 : whichWord(first - 1) + 1; if (!xlen) return *this; else if (RHS.isSingleWord()) mul_1(pVal, pVal, xlen, RHS.VAL); else { - first = RHS.getNumWords() * APINT_BITS_PER_WORD - RHS.CountLeadingZeros(); + first = RHS.getActiveBits(); unsigned ylen = !first ? 0 : whichWord(first - 1) + 1; if (!ylen) { memset(pVal, 0, getNumWords() * 8); @@ -507,7 +514,7 @@ APInt& APInt::operator*=(const APInt& RHS) { delete[] dest; } } - TruncToBits(); + clearUnusedBits(); return *this; } @@ -549,7 +556,7 @@ APInt& APInt::operator|=(const APInt& RHS) { pVal[i] |= RHS.pVal[i]; } } - TruncToBits(); + clearUnusedBits(); return *this; } @@ -573,7 +580,7 @@ APInt& APInt::operator^=(const APInt& RHS) { pVal[i] ^= 0; } } - TruncToBits(); + clearUnusedBits(); return *this; } @@ -589,7 +596,7 @@ APInt APInt::operator&(const APInt& RHS) const { APInt APInt::operator|(const APInt& RHS) const { APInt API(RHS); API |= *this; - API.TruncToBits(); + API.clearUnusedBits(); return API; } @@ -598,41 +605,10 @@ APInt APInt::operator|(const APInt& RHS) const { APInt APInt::operator^(const APInt& RHS) const { APInt API(RHS); API ^= *this; - API.TruncToBits(); + API.clearUnusedBits(); return API; } -/// @brief Logical AND operator. Performs logical AND operation on this APInt -/// and the given APInt& RHS. -bool APInt::operator&&(const APInt& RHS) const { - if (isSingleWord()) - return RHS.isSingleWord() ? VAL && RHS.VAL : VAL && RHS.pVal[0]; - else if (RHS.isSingleWord()) - return RHS.VAL && pVal[0]; - else { - unsigned minN = std::min(getNumWords(), RHS.getNumWords()); - for (unsigned i = 0; i < minN; ++i) - if (pVal[i] && RHS.pVal[i]) - return true; - } - return false; -} - -/// @brief Logical OR operator. Performs logical OR operation on this APInt -/// and the given APInt& RHS. -bool APInt::operator||(const APInt& RHS) const { - if (isSingleWord()) - return RHS.isSingleWord() ? VAL || RHS.VAL : VAL || RHS.pVal[0]; - else if (RHS.isSingleWord()) - return RHS.VAL || pVal[0]; - else { - unsigned minN = std::min(getNumWords(), RHS.getNumWords()); - for (unsigned i = 0; i < minN; ++i) - if (pVal[i] || RHS.pVal[i]) - return true; - } - return false; -} /// @brief Logical negation operator. Performs logical negation operation on /// this APInt. @@ -651,7 +627,7 @@ bool APInt::operator !() const { APInt APInt::operator*(const APInt& RHS) const { APInt API(RHS); API *= *this; - API.TruncToBits(); + API.clearUnusedBits(); return API; } @@ -659,7 +635,7 @@ APInt APInt::operator*(const APInt& RHS) const { APInt APInt::operator+(const APInt& RHS) const { APInt API(*this); API += RHS; - API.TruncToBits(); + API.clearUnusedBits(); return API; } @@ -679,8 +655,8 @@ bool APInt::operator[](unsigned bitPosition) const { /// @brief Equality operator. Compare this APInt with the given APInt& RHS /// for the validity of the equality relationship. bool APInt::operator==(const APInt& RHS) const { - unsigned n1 = getNumWords() * APINT_BITS_PER_WORD - CountLeadingZeros(), - n2 = RHS.getNumWords() * APINT_BITS_PER_WORD - RHS.CountLeadingZeros(); + unsigned n1 = getActiveBits(); + unsigned n2 = RHS.getActiveBits(); if (n1 != n2) return false; else if (isSingleWord()) return VAL == (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]); @@ -699,7 +675,7 @@ bool APInt::operator==(uint64_t Val) const { if (isSingleWord()) return VAL == Val; else { - unsigned n = getNumWords() * APINT_BITS_PER_WORD - CountLeadingZeros(); + unsigned n = getActiveBits(); if (n <= 64) return pVal[0] == Val; else @@ -707,18 +683,20 @@ bool APInt::operator==(uint64_t Val) const { } } -/// @brief Less-than operator. Compare this APInt with the given APInt& RHS -/// for the validity of the less-than relationship. -bool APInt::operator <(const APInt& RHS) const { - unsigned n1 = getNumWords() * 64 - CountLeadingZeros(), - n2 = RHS.getNumWords() * 64 - RHS.CountLeadingZeros(); - if (n1 < n2) return true; - else if (n1 > n2) return false; - else if (isSingleWord()) - return VAL < (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]); +/// @brief Unsigned less than comparison +bool APInt::ult(const APInt& RHS) const { + assert(BitWidth == RHS.BitWidth && "Bit widths must be same for comparison"); + if (isSingleWord()) + return VAL < RHS.VAL; else { - if (n1 <= 64) - return pVal[0] < (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]); + unsigned n1 = getActiveBits(); + unsigned n2 = RHS.getActiveBits(); + if (n1 < n2) + return true; + else if (n2 < n1) + return false; + else if (n1 <= 64 && n2 <= 64) + return pVal[0] < RHS.pVal[0]; for (int i = whichWord(n1 - 1); i >= 0; --i) { if (pVal[i] > RHS.pVal[i]) return false; else if (pVal[i] < RHS.pVal[i]) return true; @@ -727,24 +705,28 @@ bool APInt::operator <(const APInt& RHS) const { return false; } -/// @brief Less-than-or-equal operator. Compare this APInt with the given -/// APInt& RHS for the validity of the less-than-or-equal relationship. -bool APInt::operator<=(const APInt& RHS) const { - return (*this) == RHS || (*this) < RHS; -} - -/// @brief Greater-than operator. Compare this APInt with the given APInt& RHS -/// for the validity of the greater-than relationship. -bool APInt::operator >(const APInt& RHS) const { - return !((*this) <= RHS); +/// @brief Signed less than comparison +bool APInt::slt(const APInt& RHS) const { + assert(BitWidth == RHS.BitWidth && "Bit widths must be same for comparison"); + if (isSingleWord()) + return VAL < RHS.VAL; + else { + unsigned n1 = getActiveBits(); + unsigned n2 = RHS.getActiveBits(); + if (n1 < n2) + return true; + else if (n2 < n1) + return false; + else if (n1 <= 64 && n2 <= 64) + return pVal[0] < RHS.pVal[0]; + for (int i = whichWord(n1 - 1); i >= 0; --i) { + if (pVal[i] > RHS.pVal[i]) return false; + else if (pVal[i] < RHS.pVal[i]) return true; + } + } + return false; } -/// @brief Greater-than-or-equal operator. Compare this APInt with the given -/// APInt& RHS for the validity of the greater-than-or-equal relationship. -bool APInt::operator>=(const APInt& RHS) const { - return !((*this) < RHS); -} - /// Set the given bit to 1 whose poition is given as "bitPosition". /// @brief Set a given bit to 1. APInt& APInt::set(unsigned bitPosition) { @@ -755,11 +737,11 @@ APInt& APInt::set(unsigned bitPosition) { /// @brief Set every bit to 1. APInt& APInt::set() { - if (isSingleWord()) VAL = ~0ULL >> (64 - BitsNum); + if (isSingleWord()) VAL = ~0ULL >> (64 - BitWidth); else { for (unsigned i = 0; i < getNumWords() - 1; ++i) pVal[i] = -1ULL; - pVal[getNumWords() - 1] = ~0ULL >> (64 - BitsNum % 64); + pVal[getNumWords() - 1] = ~0ULL >> (64 - BitWidth % 64); } return *this; } @@ -790,12 +772,12 @@ APInt APInt::operator~() const { /// @brief Toggle every bit to its opposite value. APInt& APInt::flip() { - if (isSingleWord()) VAL = (~(VAL << (64 - BitsNum))) >> (64 - BitsNum); + if (isSingleWord()) VAL = (~(VAL << (64 - BitWidth))) >> (64 - BitWidth); else { unsigned i = 0; for (; i < getNumWords() - 1; ++i) pVal[i] = ~pVal[i]; - unsigned offset = 64 - (BitsNum - 64 * (i - 1)); + unsigned offset = 64 - (BitWidth - 64 * (i - 1)); pVal[i] = (~(pVal[i] << offset)) >> offset; } return *this; @@ -805,21 +787,21 @@ APInt& APInt::flip() { /// as "bitPosition". /// @brief Toggles a given bit to its opposite value. APInt& APInt::flip(unsigned bitPosition) { - assert(bitPosition < BitsNum && "Out of the bit-width range!"); + assert(bitPosition < BitWidth && "Out of the bit-width range!"); if ((*this)[bitPosition]) clear(bitPosition); else set(bitPosition); return *this; } /// to_string - This function translates the APInt into a string. -std::string APInt::to_string(uint8_t radix) const { +std::string APInt::toString(uint8_t radix) const { assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && "Radix should be 2, 8, 10, or 16!"); static const char *digits[] = { "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F" }; std::string result; - unsigned bits_used = getNumWords() * 64 - CountLeadingZeros(); + unsigned bits_used = getActiveBits(); if (isSingleWord()) { char buf[65]; const char *format = (radix == 10 ? "%llu" : @@ -845,11 +827,11 @@ std::string APInt::to_string(uint8_t radix) const { if (tmp == 0) result = "0"; else while (tmp != 0) { - APInt APdigit = APIntOps::URem(tmp,divisor); + APInt APdigit = APIntOps::urem(tmp,divisor); unsigned digit = APdigit.getValue(); - assert(digit < radix && "URem failed"); + assert(digit < radix && "urem failed"); result.insert(0,digits[digit]); - tmp = APIntOps::UDiv(tmp, divisor); + tmp = APIntOps::udiv(tmp, divisor); } return result; @@ -887,22 +869,26 @@ APInt APInt::getNullValue(unsigned numBits) { } /// HiBits - This function returns the high "numBits" bits of this APInt. -APInt APInt::HiBits(unsigned numBits) const { - return APIntOps::LShr(*this, BitsNum - numBits); +APInt APInt::getHiBits(unsigned numBits) const { + return APIntOps::lshr(*this, BitWidth - numBits); } /// LoBits - This function returns the low "numBits" bits of this APInt. -APInt APInt::LoBits(unsigned numBits) const { - return APIntOps::LShr(APIntOps::Shl(*this, BitsNum - numBits), - BitsNum - numBits); +APInt APInt::getLoBits(unsigned numBits) const { + return APIntOps::lshr(APIntOps::shl(*this, BitWidth - numBits), + BitWidth - numBits); } -/// CountLeadingZeros - This function is a APInt version corresponding to +bool APInt::isPowerOf2() const { + return (!!*this) && !(*this & (*this - APInt(BitWidth,1))); +} + +/// countLeadingZeros - This function is a APInt version corresponding to /// llvm/include/llvm/Support/MathExtras.h's function -/// CountLeadingZeros_{32, 64}. It performs platform optimal form of counting +/// countLeadingZeros_{32, 64}. It performs platform optimal form of counting /// the number of zeros from the most significant bit to the first one bit. /// @returns numWord() * 64 if the value is zero. -unsigned APInt::CountLeadingZeros() const { +unsigned APInt::countLeadingZeros() const { if (isSingleWord()) return CountLeadingZeros_64(VAL); unsigned Count = 0; @@ -915,23 +901,23 @@ unsigned APInt::CountLeadingZeros() const { return Count; } -/// CountTrailingZero - This function is a APInt version corresponding to +/// countTrailingZeros - This function is a APInt version corresponding to /// llvm/include/llvm/Support/MathExtras.h's function -/// CountTrailingZeros_{32, 64}. It performs platform optimal form of counting +/// countTrailingZeros_{32, 64}. It performs platform optimal form of counting /// the number of zeros from the least significant bit to the first one bit. /// @returns numWord() * 64 if the value is zero. -unsigned APInt::CountTrailingZeros() const { +unsigned APInt::countTrailingZeros() const { if (isSingleWord()) return CountTrailingZeros_64(~VAL & (VAL - 1)); - APInt Tmp = ~(*this) & ((*this) - 1); - return getNumWords() * 64 - Tmp.CountLeadingZeros(); + APInt Tmp = ~(*this) & ((*this) - APInt(BitWidth,1)); + return getNumWords() * APINT_BITS_PER_WORD - Tmp.countLeadingZeros(); } -/// CountPopulation - This function is a APInt version corresponding to +/// countPopulation - This function is a APInt version corresponding to /// llvm/include/llvm/Support/MathExtras.h's function -/// CountPopulation_{32, 64}. It counts the number of set bits in a value. +/// countPopulation_{32, 64}. It counts the number of set bits in a value. /// @returns 0 if the value is zero. -unsigned APInt::CountPopulation() const { +unsigned APInt::countPopulation() const { if (isSingleWord()) return CountPopulation_64(VAL); unsigned Count = 0; @@ -941,31 +927,31 @@ unsigned APInt::CountPopulation() const { } -/// ByteSwap - This function returns a byte-swapped representation of the +/// byteSwap - This function returns a byte-swapped representation of the /// this APInt. -APInt APInt::ByteSwap() const { - assert(BitsNum >= 16 && BitsNum % 16 == 0 && "Cannot byteswap!"); - if (BitsNum == 16) - return APInt(ByteSwap_16(VAL), BitsNum); - else if (BitsNum == 32) - return APInt(ByteSwap_32(VAL), BitsNum); - else if (BitsNum == 48) { +APInt APInt::byteSwap() const { + assert(BitWidth >= 16 && BitWidth % 16 == 0 && "Cannot byteswap!"); + if (BitWidth == 16) + return APInt(ByteSwap_16(VAL), BitWidth); + else if (BitWidth == 32) + return APInt(ByteSwap_32(VAL), BitWidth); + else if (BitWidth == 48) { uint64_t Tmp1 = ((VAL >> 32) << 16) | (VAL & 0xFFFF); Tmp1 = ByteSwap_32(Tmp1); uint64_t Tmp2 = (VAL >> 16) & 0xFFFF; Tmp2 = ByteSwap_16(Tmp2); return APInt((Tmp1 & 0xff) | ((Tmp1<<16) & 0xffff00000000ULL) | (Tmp2 << 16), - BitsNum); - } else if (BitsNum == 64) - return APInt(ByteSwap_64(VAL), BitsNum); + BitWidth); + } else if (BitWidth == 64) + return APInt(ByteSwap_64(VAL), BitWidth); else { - APInt Result(0, BitsNum); + APInt Result(0, BitWidth); char *pByte = (char*)Result.pVal; - for (unsigned i = 0; i < BitsNum / 8 / 2; ++i) { + for (unsigned i = 0; i < BitWidth / 8 / 2; ++i) { char Tmp = pByte[i]; - pByte[i] = pByte[BitsNum / 8 - 1 - i]; - pByte[BitsNum / 8 - i - 1] = Tmp; + pByte[i] = pByte[BitWidth / 8 - 1 - i]; + pByte[BitWidth / 8 - i - 1] = Tmp; } return Result; } @@ -978,7 +964,7 @@ APInt llvm::APIntOps::GreatestCommonDivisor(const APInt& API1, APInt A = API1, B = API2; while (!!B) { APInt T = B; - B = APIntOps::URem(A, B); + B = APIntOps::urem(A, B); A = T; } return A; @@ -986,7 +972,7 @@ APInt llvm::APIntOps::GreatestCommonDivisor(const APInt& API1, /// DoubleRoundToAPInt - This function convert a double value to /// a APInt value. -APInt llvm::APIntOps::DoubleRoundToAPInt(double Double) { +APInt llvm::APIntOps::RoundDoubleToAPInt(double Double) { union { double D; uint64_t I; @@ -995,13 +981,13 @@ APInt llvm::APIntOps::DoubleRoundToAPInt(double Double) { bool isNeg = T.I >> 63; int64_t exp = ((T.I >> 52) & 0x7ff) - 1023; if (exp < 0) - return APInt(0); + return APInt(64ull, 0u); uint64_t mantissa = ((T.I << 12) >> 12) | (1ULL << 52); if (exp < 52) - return isNeg ? -APInt(mantissa >> (52 - exp)) : - APInt(mantissa >> (52 - exp)); - APInt Tmp(mantissa, exp + 1); - Tmp = Tmp.Shl(exp - 52); + return isNeg ? -APInt(64u, mantissa >> (52 - exp)) : + APInt(64u, mantissa >> (52 - exp)); + APInt Tmp(exp + 1, mantissa); + Tmp = Tmp.shl(exp - 52); return isNeg ? -Tmp : Tmp; } @@ -1012,12 +998,12 @@ APInt llvm::APIntOps::DoubleRoundToAPInt(double Double) { /// |-------------------------------------- | /// | 1[63] 11[62-52] 52[51-00] 1023 | /// -------------------------------------- -double APInt::RoundToDouble(bool isSigned) const { - bool isNeg = isSigned ? (*this)[BitsNum-1] : false; +double APInt::roundToDouble(bool isSigned) const { + bool isNeg = isSigned ? (*this)[BitWidth-1] : false; APInt Tmp(isNeg ? -(*this) : (*this)); if (Tmp.isSingleWord()) return isSigned ? double(int64_t(Tmp.VAL)) : double(Tmp.VAL); - unsigned n = Tmp.getNumWords() * 64 - Tmp.CountLeadingZeros(); + unsigned n = Tmp.getActiveBits(); if (n <= 64) return isSigned ? double(int64_t(Tmp.pVal[0])) : double(Tmp.pVal[0]); // Exponent when normalized to have decimal point directly after @@ -1047,27 +1033,42 @@ double APInt::RoundToDouble(bool isSigned) const { return T.D; } +// Truncate to new width. +void APInt::trunc(unsigned width) { + assert(width < BitWidth && "Invalid APInt Truncate request"); +} + +// Sign extend to a new width. +void APInt::sext(unsigned width) { + assert(width > BitWidth && "Invalid APInt SignExtend request"); +} + +// Zero extend to a new width. +void APInt::zext(unsigned width) { + assert(width > BitWidth && "Invalid APInt ZeroExtend request"); +} + /// Arithmetic right-shift this APInt by shiftAmt. /// @brief Arithmetic right-shift function. -APInt APInt::AShr(unsigned shiftAmt) const { +APInt APInt::ashr(unsigned shiftAmt) const { APInt API(*this); if (API.isSingleWord()) - API.VAL = (((int64_t(API.VAL) << (64 - API.BitsNum)) >> (64 - API.BitsNum)) - >> shiftAmt) & (~uint64_t(0UL) >> (64 - API.BitsNum)); + API.VAL = (((int64_t(API.VAL) << (64 - API.BitWidth)) >> (64 - API.BitWidth)) + >> shiftAmt) & (~uint64_t(0UL) >> (64 - API.BitWidth)); else { - if (shiftAmt >= API.BitsNum) { - memset(API.pVal, API[API.BitsNum-1] ? 1 : 0, (API.getNumWords()-1) * 8); + if (shiftAmt >= API.BitWidth) { + memset(API.pVal, API[API.BitWidth-1] ? 1 : 0, (API.getNumWords()-1) * 8); API.pVal[API.getNumWords() - 1] = ~uint64_t(0UL) >> - (64 - API.BitsNum % 64); + (64 - API.BitWidth % 64); } else { unsigned i = 0; - for (; i < API.BitsNum - shiftAmt; ++i) + for (; i < API.BitWidth - shiftAmt; ++i) if (API[i+shiftAmt]) API.set(i); else API.clear(i); - for (; i < API.BitsNum; ++i) - if (API[API.BitsNum-1]) + for (; i < API.BitWidth; ++i) + if (API[API.BitWidth-1]) API.set(i); else API.clear(i); } @@ -1077,18 +1078,18 @@ APInt APInt::AShr(unsigned shiftAmt) const { /// Logical right-shift this APInt by shiftAmt. /// @brief Logical right-shift function. -APInt APInt::LShr(unsigned shiftAmt) const { +APInt APInt::lshr(unsigned shiftAmt) const { APInt API(*this); if (API.isSingleWord()) API.VAL >>= shiftAmt; else { - if (shiftAmt >= API.BitsNum) + if (shiftAmt >= API.BitWidth) memset(API.pVal, 0, API.getNumWords() * 8); unsigned i = 0; - for (i = 0; i < API.BitsNum - shiftAmt; ++i) + for (i = 0; i < API.BitWidth - shiftAmt; ++i) if (API[i+shiftAmt]) API.set(i); else API.clear(i); - for (; i < API.BitsNum; ++i) + for (; i < API.BitWidth; ++i) API.clear(i); } return API; @@ -1096,11 +1097,11 @@ APInt APInt::LShr(unsigned shiftAmt) const { /// Left-shift this APInt by shiftAmt. /// @brief Left-shift function. -APInt APInt::Shl(unsigned shiftAmt) const { +APInt APInt::shl(unsigned shiftAmt) const { APInt API(*this); if (API.isSingleWord()) API.VAL <<= shiftAmt; - else if (shiftAmt >= API.BitsNum) + else if (shiftAmt >= API.BitWidth) memset(API.pVal, 0, API.getNumWords() * 8); else { if (unsigned offset = shiftAmt / 64) { @@ -1115,28 +1116,26 @@ APInt APInt::Shl(unsigned shiftAmt) const { (API.pVal[i-1] >> (64-shiftAmt)); API.pVal[i] <<= shiftAmt; } - API.TruncToBits(); + API.clearUnusedBits(); return API; } /// Unsigned divide this APInt by APInt RHS. /// @brief Unsigned division function for APInt. -APInt APInt::UDiv(const APInt& RHS) const { +APInt APInt::udiv(const APInt& RHS) const { APInt API(*this); - unsigned first = RHS.getNumWords() * APInt::APINT_BITS_PER_WORD - - RHS.CountLeadingZeros(); + unsigned first = RHS.getActiveBits(); unsigned ylen = !first ? 0 : APInt::whichWord(first - 1) + 1; assert(ylen && "Divided by zero???"); if (API.isSingleWord()) { API.VAL = RHS.isSingleWord() ? (API.VAL / RHS.VAL) : (ylen > 1 ? 0 : API.VAL / RHS.pVal[0]); } else { - unsigned first2 = API.getNumWords() * APInt::APINT_BITS_PER_WORD - - API.CountLeadingZeros(); + unsigned first2 = API.getActiveBits(); unsigned xlen = !first2 ? 0 : APInt::whichWord(first2 - 1) + 1; if (!xlen) return API; - else if (xlen < ylen || API < RHS) + else if (xlen < ylen || API.ult(RHS)) memset(API.pVal, 0, API.getNumWords() * 8); else if (API == RHS) { memset(API.pVal, 0, API.getNumWords() * 8); @@ -1146,8 +1145,8 @@ APInt APInt::UDiv(const APInt& RHS) const { else { APInt X(0, (xlen+1)*64), Y(0, ylen*64); if (unsigned nshift = 63 - (first - 1) % 64) { - Y = APIntOps::Shl(RHS, nshift); - X = APIntOps::Shl(API, nshift); + Y = APIntOps::shl(RHS, nshift); + X = APIntOps::shl(API, nshift); ++xlen; } div((unsigned*)X.pVal, xlen*2-1, @@ -1161,20 +1160,18 @@ APInt APInt::UDiv(const APInt& RHS) const { /// Unsigned remainder operation on APInt. /// @brief Function for unsigned remainder operation. -APInt APInt::URem(const APInt& RHS) const { +APInt APInt::urem(const APInt& RHS) const { APInt API(*this); - unsigned first = RHS.getNumWords() * APInt::APINT_BITS_PER_WORD - - RHS.CountLeadingZeros(); + unsigned first = RHS.getActiveBits(); unsigned ylen = !first ? 0 : APInt::whichWord(first - 1) + 1; assert(ylen && "Performing remainder operation by zero ???"); if (API.isSingleWord()) { API.VAL = RHS.isSingleWord() ? (API.VAL % RHS.VAL) : (ylen > 1 ? API.VAL : API.VAL % RHS.pVal[0]); } else { - unsigned first2 = API.getNumWords() * APInt::APINT_BITS_PER_WORD - - API.CountLeadingZeros(); + unsigned first2 = API.getActiveBits(); unsigned xlen = !first2 ? 0 : API.whichWord(first2 - 1) + 1; - if (!xlen || xlen < ylen || API < RHS) + if (!xlen || xlen < ylen || API.ult(RHS)) return API; else if (API == RHS) memset(API.pVal, 0, API.getNumWords() * 8); @@ -1184,8 +1181,8 @@ APInt APInt::URem(const APInt& RHS) const { APInt X(0, (xlen+1)*64), Y(0, ylen*64); unsigned nshift = 63 - (first - 1) % 64; if (nshift) { - APIntOps::Shl(Y, nshift); - APIntOps::Shl(X, nshift); + APIntOps::shl(Y, nshift); + APIntOps::shl(X, nshift); } div((unsigned*)X.pVal, xlen*2-1, (unsigned*)(Y.isSingleWord() ? &Y.VAL : Y.pVal), ylen*2); |