diff options
Diffstat (limited to 'include/llvm/ADT/APInt.h')
-rw-r--r-- | include/llvm/ADT/APInt.h | 142 |
1 files changed, 74 insertions, 68 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 8004cb4..b91d5dc 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -275,12 +275,6 @@ public: /// objects, into FoldingSets. void Profile(FoldingSetNodeID& id) const; - /// @brief Used by the Bitcode serializer to emit APInts to Bitcode. - void Emit(Serializer& S) const; - - /// @brief Used by the Bitcode deserializer to deserialize APInts. - void Read(Deserializer& D); - /// @} /// @name Value Tests /// @{ @@ -302,7 +296,7 @@ public: /// @returns true if this APInt is positive. /// @brief Determine if this APInt Value is positive. bool isStrictlyPositive() const { - return isNonNegative() && (*this) != 0; + return isNonNegative() && !!*this; } /// This checks to see if the value has all bits of the APInt are set or not. @@ -330,15 +324,14 @@ public: /// value for the APInt's bit width. /// @brief Determine if this is the smallest unsigned value. bool isMinValue() const { - return countPopulation() == 0; + return !*this; } /// This checks to see if the value of this APInt is the minimum signed /// value for the APInt's bit width. /// @brief Determine if this is the smallest signed value. bool isMinSignedValue() const { - return BitWidth == 1 ? VAL == 1 : - isNegative() && countPopulation() == 1; + return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2(); } /// @brief Check if this APInt has an N-bits unsigned integer value. @@ -348,10 +341,8 @@ public: return true; if (isSingleWord()) - return VAL == (VAL & (~0ULL >> (64 - N))); - APInt Tmp(N, getNumWords(), pVal); - Tmp.zext(getBitWidth()); - return Tmp == (*this); + return isUIntN(N, VAL); + return APInt(N, getNumWords(), pVal).zext(getBitWidth()) == (*this); } /// @brief Check if this APInt has an N-bits signed integer value. @@ -361,7 +352,11 @@ public: } /// @returns true if the argument APInt value is a power of two > 0. - bool isPowerOf2() const; + bool isPowerOf2() const { + if (isSingleWord()) + return isPowerOf2_64(VAL); + return countPopulationSlowCase() == 1; + } /// isSignBit - Return true if this is the value returned by getSignBit. bool isSignBit() const { return isMinSignedValue(); } @@ -369,7 +364,7 @@ public: /// This converts the APInt to a boolean value as a test against zero. /// @brief Boolean conversion function. bool getBoolValue() const { - return *this != 0; + return !!*this; } /// getLimitedValue - If this value is smaller than the specified limit, @@ -385,12 +380,14 @@ public: /// @{ /// @brief Gets maximum unsigned value of APInt for specific bit width. static APInt getMaxValue(unsigned numBits) { - return APInt(numBits, 0).set(); + return getAllOnesValue(numBits); } /// @brief Gets maximum signed value of APInt for a specific bit width. static APInt getSignedMaxValue(unsigned numBits) { - return APInt(numBits, 0).set().clear(numBits - 1); + APInt API = getAllOnesValue(numBits); + API.clearBit(numBits - 1); + return API; } /// @brief Gets minimum unsigned value of APInt for a specific bit width. @@ -400,7 +397,9 @@ public: /// @brief Gets minimum signed value of APInt for a specific bit width. static APInt getSignedMinValue(unsigned numBits) { - return APInt(numBits, 0).set(numBits - 1); + APInt API(numBits, 0); + API.setBit(numBits - 1); + return API; } /// getSignBit - This is just a wrapper function of getSignedMinValue(), and @@ -413,7 +412,7 @@ public: /// @returns the all-ones value for an APInt of the specified bit-width. /// @brief Get the all-ones value. static APInt getAllOnesValue(unsigned numBits) { - return APInt(numBits, 0).set(); + return APInt(numBits, -1ULL, true); } /// @returns the '0' value for an APInt of the specified bit-width. @@ -432,6 +431,13 @@ public: /// @returns the low "numBits" bits of this APInt. APInt getLoBits(unsigned numBits) const; + /// getOneBitSet - Return an APInt with exactly one bit set in the result. + static APInt getOneBitSet(unsigned numBits, unsigned BitNo) { + APInt Res(numBits, 0); + Res.setBit(BitNo); + return Res; + } + /// Constructs an APInt value that has a contiguous range of bits set. The /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other /// bits will be zero. For example, with parameters(32, 0, 16) you would get @@ -530,7 +536,7 @@ public: /// @brief Unary bitwise complement operator. APInt operator~() const { APInt Result(*this); - Result.flip(); + Result.flipAllBits(); return Result; } @@ -741,11 +747,11 @@ public: /// RHS are treated as unsigned quantities for purposes of this division. /// @returns a new APInt value containing the division result /// @brief Unsigned division operation. - APInt udiv(const APInt& RHS) const; + APInt udiv(const APInt &RHS) const; /// Signed divide this APInt by APInt RHS. /// @brief Signed division function for APInt. - APInt sdiv(const APInt& RHS) const { + APInt sdiv(const APInt &RHS) const { if (isNegative()) if (RHS.isNegative()) return (-(*this)).udiv(-RHS); @@ -763,11 +769,11 @@ public: /// which is *this. /// @returns a new APInt value containing the remainder result /// @brief Unsigned remainder operation. - APInt urem(const APInt& RHS) const; + APInt urem(const APInt &RHS) const; /// Signed remainder operation on APInt. /// @brief Function for signed remainder operation. - APInt srem(const APInt& RHS) const { + APInt srem(const APInt &RHS) const { if (isNegative()) if (RHS.isNegative()) return -((-(*this)).urem(-RHS)); @@ -788,8 +794,7 @@ public: APInt &Quotient, APInt &Remainder); static void sdivrem(const APInt &LHS, const APInt &RHS, - APInt &Quotient, APInt &Remainder) - { + APInt &Quotient, APInt &Remainder) { if (LHS.isNegative()) { if (RHS.isNegative()) APInt::udivrem(-LHS, -RHS, Quotient, Remainder); @@ -804,6 +809,16 @@ public: APInt::udivrem(LHS, RHS, Quotient, Remainder); } } + + + // Operations that return overflow indicators. + APInt sadd_ov(const APInt &RHS, bool &Overflow) const; + APInt uadd_ov(const APInt &RHS, bool &Overflow) const; + APInt ssub_ov(const APInt &RHS, bool &Overflow) const; + APInt usub_ov(const APInt &RHS, bool &Overflow) const; + APInt sdiv_ov(const APInt &RHS, bool &Overflow) const; + APInt smul_ov(const APInt &RHS, bool &Overflow) const; + APInt sshl_ov(unsigned Amt, bool &Overflow) const; /// @returns the bit value at bitPosition /// @brief Array-indexing support. @@ -868,7 +883,7 @@ public: /// the validity of the less-than relationship. /// @returns true if *this < RHS when both are considered unsigned. /// @brief Unsigned less than comparison - bool ult(const APInt& RHS) const; + bool ult(const APInt &RHS) const; /// Regards both *this as an unsigned quantity and compares it with RHS for /// the validity of the less-than relationship. @@ -988,6 +1003,9 @@ public: return sge(APInt(getBitWidth(), RHS)); } + + + /// This operation tests if there are any pairs of corresponding bits /// between this APInt and RHS that are both set. bool intersects(const APInt &RHS) const { @@ -1000,80 +1018,78 @@ public: /// Truncate the APInt to a specified width. It is an error to specify a width /// that is greater than or equal to the current width. /// @brief Truncate to new width. - APInt &trunc(unsigned width); + APInt trunc(unsigned width) const; /// This operation sign extends the APInt to a new width. If the high order /// bit is set, the fill on the left will be done with 1 bits, otherwise zero. /// It is an error to specify a width that is less than or equal to the /// current width. /// @brief Sign extend to a new width. - APInt &sext(unsigned width); + APInt sext(unsigned width) const; /// This operation zero extends the APInt to a new width. The high order bits /// are filled with 0 bits. It is an error to specify a width that is less /// than or equal to the current width. /// @brief Zero extend to a new width. - APInt &zext(unsigned width); + APInt zext(unsigned width) const; /// Make this APInt have the bit width given by \p width. The value is sign /// extended, truncated, or left alone to make it that width. /// @brief Sign extend or truncate to width - APInt &sextOrTrunc(unsigned width); + APInt sextOrTrunc(unsigned width) const; /// Make this APInt have the bit width given by \p width. The value is zero /// extended, truncated, or left alone to make it that width. /// @brief Zero extend or truncate to width - APInt &zextOrTrunc(unsigned width); + APInt zextOrTrunc(unsigned width) const; /// @} /// @name Bit Manipulation Operators /// @{ /// @brief Set every bit to 1. - APInt& set() { - if (isSingleWord()) { + void setAllBits() { + if (isSingleWord()) VAL = -1ULL; - return clearUnusedBits(); + else { + // Set all the bits in all the words. + for (unsigned i = 0; i < getNumWords(); ++i) + pVal[i] = -1ULL; } - - // Set all the bits in all the words. - for (unsigned i = 0; i < getNumWords(); ++i) - pVal[i] = -1ULL; // Clear the unused ones - return clearUnusedBits(); + clearUnusedBits(); } /// Set the given bit to 1 whose position is given as "bitPosition". /// @brief Set a given bit to 1. - APInt& set(unsigned bitPosition); + void setBit(unsigned bitPosition); /// @brief Set every bit to 0. - APInt& clear() { + void clearAllBits() { if (isSingleWord()) VAL = 0; else memset(pVal, 0, getNumWords() * APINT_WORD_SIZE); - return *this; } /// Set the given bit to 0 whose position is given as "bitPosition". /// @brief Set a given bit to 0. - APInt& clear(unsigned bitPosition); + void clearBit(unsigned bitPosition); /// @brief Toggle every bit to its opposite value. - APInt& flip() { - if (isSingleWord()) { + void flipAllBits() { + if (isSingleWord()) VAL ^= -1ULL; - return clearUnusedBits(); + else { + for (unsigned i = 0; i < getNumWords(); ++i) + pVal[i] ^= -1ULL; } - for (unsigned i = 0; i < getNumWords(); ++i) - pVal[i] ^= -1ULL; - return clearUnusedBits(); + clearUnusedBits(); } /// Toggle a given bit to its opposite value whose position is given /// as "bitPosition". /// @brief Toggles a given bit to its opposite value. - APInt& flip(unsigned bitPosition); + void flipBit(unsigned bitPosition); /// @} /// @name Value Characterization Functions @@ -1281,37 +1297,27 @@ public: } /// The conversion does not do a translation from double to integer, it just - /// re-interprets the bits of the double. Note that it is valid to do this on - /// any bit width but bits from V may get truncated. + /// re-interprets the bits of the double. /// @brief Converts a double to APInt bits. - APInt& doubleToBits(double V) { + static APInt doubleToBits(double V) { union { uint64_t I; double D; } T; T.D = V; - if (isSingleWord()) - VAL = T.I; - else - pVal[0] = T.I; - return clearUnusedBits(); + return APInt(sizeof T * CHAR_BIT, T.I); } /// The conversion does not do a translation from float to integer, it just - /// re-interprets the bits of the float. Note that it is valid to do this on - /// any bit width but bits from V may get truncated. + /// re-interprets the bits of the float. /// @brief Converts a float to APInt bits. - APInt& floatToBits(float V) { + static APInt floatToBits(float V) { union { unsigned I; float F; } T; T.F = V; - if (isSingleWord()) - VAL = T.I; - else - pVal[0] = T.I; - return clearUnusedBits(); + return APInt(sizeof T * CHAR_BIT, T.I); } /// @} |