diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 39294bf23b0..79330572341 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -24,8 +24,8 @@ namespace llvm { /// Forward declaration. class APInt; namespace APIntOps { - APInt UDiv(const APInt& LHS, const APInt& RHS); - APInt URem(const APInt& LHS, const APInt& RHS); + APInt udiv(const APInt& LHS, const APInt& RHS); + APInt urem(const APInt& LHS, const APInt& RHS); } //===----------------------------------------------------------------------===// @@ -35,17 +35,31 @@ namespace APIntOps { /// APInt - This class represents arbitrary precision constant integral values. /// It is a functional replacement for common case unsigned integer type like /// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width -/// integer type and large integer value types such as 3-bits, 15-bits, or more +/// integer sizes and large integer value types such as 3-bits, 15-bits, or more /// than 64-bits of precision. APInt provides a variety of arithmetic operators -/// and methods to manipulate integer values of any bit-width. It supports not -/// only all the operations of uint64_t but also bitwise manipulation. +/// and methods to manipulate integer values of any bit-width. It supports both +/// the typical integer arithmetic and comparison operations as well as bitwise +/// manipulation. +/// +/// The class has several invariants worth noting: +/// * All bit, byte, and word positions are zero-based. +/// * Once the bit width is set, it doesn't change except by the Truncate, +/// SignExtend, or ZeroExtend operations. +/// * All binary operators must be on APInt instances of the same bit width. +/// Attempting to use these operators on instances with different bit +/// widths will yield an assertion. +/// * The value is stored canonically as an unsigned value. For operations +/// where it makes a difference, there are both signed and unsigned variants +/// of the operation. For example, sdiv and udiv. However, because the bit +/// widths must be the same, operations such as Mul and Add produce the same +/// results regardless of whether the values are interpreted as signed or +/// not. +/// * In general, the class tries to follow the style of computation that LLVM +/// uses in its IR. This simplifies its use for LLVM. /// /// @brief Class for arbitrary precision integers. -/// -/// Note: In this class, all bit/byte/word positions are zero-based. -/// class APInt { - unsigned BitsNum; ///< The number of bits. + unsigned BitWidth; ///< The number of bits in this APInt. /// This union is used to store the integer value. When the /// integer bit-width <= 64, it uses VAL; @@ -64,67 +78,79 @@ class APInt { /// @returns the number of words to hold the integer value of this APInt. /// @brief Get the number of words. inline unsigned getNumWords() const { - return (BitsNum + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; + return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; } /// @returns true if the number of bits <= 64, false otherwise. /// @brief Determine if this APInt just has one word to store value. - inline bool isSingleWord() const - { return BitsNum <= APINT_BITS_PER_WORD; } + inline bool isSingleWord() const { + return BitWidth <= APINT_BITS_PER_WORD; + } /// @returns the word position for the specified bit position. - static inline unsigned whichWord(unsigned bitPosition) - { return bitPosition / APINT_BITS_PER_WORD; } + static inline unsigned whichWord(unsigned bitPosition) { + return bitPosition / APINT_BITS_PER_WORD; + } /// @returns the byte position for the specified bit position. - static inline unsigned whichByte(unsigned bitPosition) - { return (bitPosition % APINT_BITS_PER_WORD) / 8; } + static inline unsigned whichByte(unsigned bitPosition) { + return (bitPosition % APINT_BITS_PER_WORD) / 8; + } /// @returns the bit position in a word for the specified bit position /// in APInt. - static inline unsigned whichBit(unsigned bitPosition) - { return bitPosition % APINT_BITS_PER_WORD; } + static inline unsigned whichBit(unsigned bitPosition) { + return bitPosition % APINT_BITS_PER_WORD; + } /// @returns a uint64_t type integer with just bit position at /// "whichBit(bitPosition)" setting, others zero. - static inline uint64_t maskBit(unsigned bitPosition) - { return (static_cast(1)) << whichBit(bitPosition); } + static inline uint64_t maskBit(unsigned bitPosition) { + return (static_cast(1)) << whichBit(bitPosition); + } - inline void TruncToBits() { + /// This method is used internally to clear the to "N" bits that are not used + /// by the APInt. This is needed after a word is assigned a value to ensure + /// that those bits are zero'd out. + /// @brief Clear high order bits + inline void clearUnusedBits() { if (isSingleWord()) - VAL &= ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitsNum); + VAL &= ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitWidth); else pVal[getNumWords() - 1] &= ~uint64_t(0ULL) >> - (APINT_BITS_PER_WORD - (whichBit(BitsNum - 1) + 1)); + (APINT_BITS_PER_WORD - (whichBit(BitWidth - 1) + 1)); } /// @returns the corresponding word for the specified bit position. - inline uint64_t& getWord(unsigned bitPosition) - { return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; } + inline uint64_t& getWord(unsigned bitPosition) { + return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; + } /// @returns the corresponding word for the specified bit position. /// This is a constant version. - inline uint64_t getWord(unsigned bitPosition) const - { return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; } + inline uint64_t getWord(unsigned bitPosition) const { + return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; + } /// @brief Converts a char array into an integer. - void StrToAPInt(const char *StrStart, unsigned slen, uint8_t radix); + void fromString(unsigned numBits, const char *StrStart, unsigned slen, + uint8_t radix); public: /// @brief Create a new APInt of numBits bit-width, and initialized as val. - APInt(uint64_t val = 0, unsigned numBits = APINT_BITS_PER_WORD); + APInt(unsigned numBits, uint64_t val); /// @brief Create a new APInt of numBits bit-width, and initialized as /// bigVal[]. - APInt(unsigned numBits, uint64_t bigVal[]); + APInt(unsigned numBits, unsigned numWords, uint64_t bigVal[]); /// @brief Create a new APInt by translating the string represented /// integer value. - APInt(const std::string& Val, uint8_t radix = 10); + APInt(unsigned numBits, const std::string& Val, uint8_t radix); /// @brief Create a new APInt by translating the char array represented /// integer value. - APInt(const char StrStart[], unsigned slen, uint8_t radix); + APInt(unsigned numBits, const char StrStart[], unsigned slen, uint8_t radix); /// @brief Copy Constructor. APInt(const APInt& API); @@ -210,14 +236,6 @@ public: /// @brief Bitwise XOR operator. APInt operator^(const APInt& RHS) const; - /// Performs logical AND operation on this APInt and the given APInt& RHS. - /// @brief Logical AND operator. - bool operator&&(const APInt& RHS) const; - - /// Performs logical OR operation on this APInt and the given APInt& RHS. - /// @brief Logical OR operator. - bool operator||(const APInt& RHS) const; - /// Performs logical negation operation on this APInt. /// @brief Logical negation operator. bool operator !() const; @@ -234,9 +252,9 @@ public: /// @brief Subtraction operator. APInt operator-(const APInt& RHS) const; - /// + /// @brief Unary negation operator inline APInt operator-() const { - return APInt(0, BitsNum) - (*this); + return APInt(0, BitWidth) - (*this); } /// @brief Array-indexing support. @@ -266,32 +284,147 @@ public: return !((*this) == Val); } - /// Compare this APInt with the given APInt& RHS for - /// the validity of the less-than relationship. - /// @brief Less-than operator. - bool operator <(const APInt& RHS) const; + /// @brief Equality comparison + bool eq(const APInt &RHS) const { + return (*this) == RHS; + } - /// Compare this APInt with the given APInt& RHS for the validity - /// of the less-than-or-equal relationship. - /// @brief Less-than-or-equal operator. - bool operator<=(const APInt& RHS) const; + /// @brief Inequality comparison + bool ne(const APInt &RHS) const { + return !((*this) == RHS); + } - /// Compare this APInt with the given APInt& RHS for the validity - /// of the greater-than relationship. - /// @brief Greater-than operator. - bool operator> (const APInt& RHS) const; + /// @brief Unsigned less than comparison + bool ult(const APInt& RHS) const; - /// @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 operator>=(const APInt& RHS) const; + /// @brief Signed less than comparison + bool slt(const APInt& RHS) const; + + /// @brief Unsigned less or equal comparison + bool ule(const APInt& RHS) const { + return ult(RHS) || eq(RHS); + } + + /// @brief Signed less or equal comparison + bool sle(const APInt& RHS) const { + return slt(RHS) || eq(RHS); + } + + /// @brief Unsigned greather than comparison + bool ugt(const APInt& RHS) const { + return !ult(RHS) && !eq(RHS); + } + + /// @brief Signed greather than comparison + bool sgt(const APInt& RHS) const { + return !slt(RHS) && !eq(RHS); + } + + /// @brief Unsigned greater or equal comparison + bool uge(const APInt& RHS) const { + return !ult(RHS); + } + + /// @brief Signed greather or equal comparison + bool sge(const APInt& RHS) const { + return !slt(RHS); + } + + /// Arithmetic right-shift this APInt by shiftAmt. + /// @brief Arithmetic right-shift function. + APInt ashr(unsigned shiftAmt) const; + + /// Logical right-shift this APInt by shiftAmt. + /// @brief Logical right-shift function. + APInt lshr(unsigned shiftAmt) const; + + /// Left-shift this APInt by shiftAmt. + /// @brief Left-shift function. + APInt shl(unsigned shiftAmt) const; + + /// Signed divide this APInt by APInt RHS. + /// @brief Signed division function for APInt. + inline APInt sdiv(const APInt& RHS) const { + bool isNegativeLHS = (*this)[BitWidth - 1]; + bool isNegativeRHS = RHS[RHS.BitWidth - 1]; + APInt API = APIntOps::udiv( + isNegativeLHS ? -(*this) : (*this), isNegativeRHS ? -RHS : RHS); + return isNegativeLHS != isNegativeRHS ? -API : API;; + } + + /// Unsigned divide this APInt by APInt RHS. + /// @brief Unsigned division function for APInt. + APInt udiv(const APInt& RHS) const; + + /// Signed remainder operation on APInt. + /// @brief Function for signed remainder operation. + inline APInt srem(const APInt& RHS) const { + bool isNegativeLHS = (*this)[BitWidth - 1]; + bool isNegativeRHS = RHS[RHS.BitWidth - 1]; + APInt API = APIntOps::urem( + isNegativeLHS ? -(*this) : (*this), isNegativeRHS ? -RHS : RHS); + return isNegativeLHS ? -API : API; + } + + /// Unsigned remainder operation on APInt. + /// @brief Function for unsigned remainder operation. + APInt urem(const APInt& RHS) const; + + /// 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. + void trunc(unsigned width); + + /// 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. + void sext(unsigned width); + + /// This operation zero extends the APInt to a new width. Thie 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. + void zext(unsigned width); + + /// @brief Set every bit to 1. + APInt& set(); + + /// Set the given bit to 1 whose position is given as "bitPosition". + /// @brief Set a given bit to 1. + APInt& set(unsigned bitPosition); + + /// @brief Set every bit to 0. + APInt& clear(); + + /// Set the given bit to 0 whose position is given as "bitPosition". + /// @brief Set a given bit to 0. + APInt& clear(unsigned bitPosition); + + /// @brief Toggle every bit to its opposite value. + APInt& flip(); + + /// 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); + + /// This function returns the number of active bits which is defined as the + /// bit width minus the number of leading zeros. This is used in several + /// computations to see how "wide" the value is. + /// @brief Compute the number of active bits in the value + inline unsigned getActiveBits() const { + return getNumWords() * APINT_BITS_PER_WORD - countLeadingZeros(); + } /// @returns a uint64_t value from this APInt. If this APInt contains a single /// word, just returns VAL, otherwise pVal[0]. inline uint64_t getValue(bool isSigned = false) const { if (isSingleWord()) - return isSigned ? int64_t(VAL << (64 - BitsNum)) >> (64 - BitsNum) : VAL; - unsigned n = getNumWords() * 64 - CountLeadingZeros(); + return isSigned ? int64_t(VAL << (64 - BitWidth)) >> + (64 - BitWidth) : VAL; + unsigned n = getActiveBits(); if (n <= 64) return pVal[0]; assert(0 && "This APInt's bitwidth > 64"); @@ -316,119 +449,65 @@ public: /// @brief Get the '0' value. static APInt getNullValue(unsigned numBits); - /// @brief Set every bit to 1. - APInt& set(); - - /// Set the given bit to 1 whose position is given as "bitPosition". - /// @brief Set a given bit to 1. - APInt& set(unsigned bitPosition); - - /// @brief Set every bit to 0. - APInt& clear(); - - /// Set the given bit to 0 whose position is given as "bitPosition". - /// @brief Set a given bit to 0. - APInt& clear(unsigned bitPosition); - - /// @brief Toggle every bit to its opposite value. - APInt& flip(); - - /// 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); + /// This converts the APInt to a boolean valy as a test against zero. + /// @brief Boolean conversion function. + inline bool getBoolValue() const { + return countLeadingZeros() != BitWidth; + } /// @returns a character interpretation of the APInt. - std::string to_string(uint8_t radix = 10) const; + std::string toString(uint8_t radix = 10) const; - /// Get an APInt with the same BitsNum as this APInt, just zero mask + /// Get an APInt with the same BitWidth as this APInt, just zero mask /// the low bits and right shift to the least significant bit. /// @returns the high "numBits" bits of this APInt. - APInt HiBits(unsigned numBits) const; + APInt getHiBits(unsigned numBits) const; - /// Get an APInt with the same BitsNum as this APInt, just zero mask + /// Get an APInt with the same BitWidth as this APInt, just zero mask /// the high bits. /// @returns the low "numBits" bits of this APInt. - APInt LoBits(unsigned numBits) const; + APInt getLoBits(unsigned numBits) const; /// @returns true if the argument APInt value is a power of two > 0. - inline const bool isPowerOf2() const { - return (!!*this) && !(*this & (*this - 1)); - } + inline bool isPowerOf2() const; /// @returns the number of zeros from the most significant bit to the first /// one bits. - unsigned CountLeadingZeros() const; + unsigned countLeadingZeros() const; /// @returns the number of zeros from the least significant bit to the first /// one bit. - unsigned CountTrailingZeros() const; + unsigned countTrailingZeros() const; /// @returns the number of set bits. - unsigned CountPopulation() const; + unsigned countPopulation() const; /// @returns the total number of bits. - inline unsigned getNumBits() const - { return BitsNum; } + inline unsigned getNumBits() const { + return BitWidth; + } /// @brief Check if this APInt has a N-bits integer value. - inline bool IsIntN(unsigned N) const { + inline bool isIntN(unsigned N) const { assert(N && "N == 0 ???"); if (isSingleWord()) { return VAL == (VAL & (~0ULL >> (64 - N))); } else { - APInt Tmp(N, pVal); + APInt Tmp(N, getNumWords(), pVal); return Tmp == (*this); } } /// @returns a byte-swapped representation of this APInt Value. - APInt ByteSwap() const; + APInt byteSwap() const; /// @returns the floor log base 2 of this APInt. - inline unsigned LogBase2() const { - return getNumWords() * APINT_BITS_PER_WORD - 1 - - CountLeadingZeros(); + inline unsigned logBase2() const { + return getNumWords() * APINT_BITS_PER_WORD - 1 - countLeadingZeros(); } /// @brief Converts this APInt to a double value. - double RoundToDouble(bool isSigned = false) const; - - /// Arithmetic right-shift this APInt by shiftAmt. - /// @brief Arithmetic right-shift function. - APInt AShr(unsigned shiftAmt) const; - - /// Logical right-shift this APInt by shiftAmt. - /// @brief Logical right-shift function. - APInt LShr(unsigned shiftAmt) const; - - /// Left-shift this APInt by shiftAmt. - /// @brief Left-shift function. - APInt Shl(unsigned shiftAmt) const; - - /// Signed divide this APInt by APInt RHS. - /// @brief Signed division function for APInt. - inline APInt SDiv(const APInt& RHS) const { - bool isSignedLHS = (*this)[BitsNum - 1], isSignedRHS = RHS[RHS.BitsNum - 1]; - APInt API = APIntOps::UDiv(isSignedLHS ? -(*this) : (*this), isSignedRHS ? -RHS : RHS); - return isSignedLHS != isSignedRHS ? -API : API;; - } - - /// Unsigned divide this APInt by APInt RHS. - /// @brief Unsigned division function for APInt. - APInt UDiv(const APInt& RHS) const; - - /// Signed remainder operation on APInt. - /// @brief Function for signed remainder operation. - inline APInt SRem(const APInt& RHS) const { - bool isSignedLHS = (*this)[BitsNum - 1], isSignedRHS = RHS[RHS.BitsNum - 1]; - APInt API = APIntOps::URem(isSignedLHS ? -(*this) : (*this), isSignedRHS ? -RHS : RHS); - return isSignedLHS ? -API : API; - } - - /// Unsigned remainder operation on APInt. - /// @brief Function for unsigned remainder operation. - APInt URem(const APInt& RHS) const; + double roundToDouble(bool isSigned = false) const; }; @@ -436,29 +515,29 @@ namespace APIntOps { /// @brief Check if the specified APInt has a N-bits integer value. inline bool isIntN(unsigned N, const APInt& APIVal) { - return APIVal.IsIntN(N); + return APIVal.isIntN(N); } /// @returns true if the argument APInt value is a sequence of ones /// starting at the least significant bit with the remainder zero. inline const bool isMask(unsigned numBits, const APInt& APIVal) { - return APIVal && ((APIVal + 1) & APIVal) == 0; + return APIVal.getBoolValue() && ((APIVal + APInt(numBits,1)) & APIVal) == 0; } /// @returns true if the argument APInt value contains a sequence of ones /// with the remainder zero. inline const bool isShiftedMask(unsigned numBits, const APInt& APIVal) { - return isMask(numBits, (APIVal - 1) | APIVal); + return isMask(numBits, (APIVal - APInt(numBits,1)) | APIVal); } /// @returns a byte-swapped representation of the specified APInt Value. -inline APInt ByteSwap(const APInt& APIVal) { - return APIVal.ByteSwap(); +inline APInt byteSwap(const APInt& APIVal) { + return APIVal.byteSwap(); } /// @returns the floor log base 2 of the specified APInt value. -inline unsigned LogBase2(const APInt& APIVal) { - return APIVal.LogBase2(); +inline unsigned logBase2(const APInt& APIVal) { + return APIVal.logBase2(); } /// @returns the greatest common divisor of the two values @@ -466,80 +545,80 @@ inline unsigned LogBase2(const APInt& APIVal) { APInt GreatestCommonDivisor(const APInt& API1, const APInt& API2); /// @brief Converts the given APInt to a double value. -inline double APIntRoundToDouble(const APInt& APIVal, bool isSigned = false) { - return APIVal.RoundToDouble(isSigned); +inline double RoundAPIntToDouble(const APInt& APIVal, bool isSigned = false) { + return APIVal.roundToDouble(isSigned); } /// @brief Converts the given APInt to a float vlalue. -inline float APIntRoundToFloat(const APInt& APIVal) { - return float(APIntRoundToDouble(APIVal)); +inline float RoundAPIntToFloat(const APInt& APIVal) { + return float(RoundAPIntToDouble(APIVal)); } /// @brief Converts the given double value into a APInt. -APInt DoubleRoundToAPInt(double Double); +APInt RoundDoubleToAPInt(double Double); /// @brief Converts the given float value into a APInt. -inline APInt FloatRoundToAPInt(float Float) { - return DoubleRoundToAPInt(double(Float)); +inline APInt RoundFloatToAPInt(float Float) { + return RoundDoubleToAPInt(double(Float)); } /// Arithmetic right-shift the APInt by shiftAmt. /// @brief Arithmetic right-shift function. -inline APInt AShr(const APInt& LHS, unsigned shiftAmt) { - return LHS.AShr(shiftAmt); +inline APInt ashr(const APInt& LHS, unsigned shiftAmt) { + return LHS.ashr(shiftAmt); } /// Logical right-shift the APInt by shiftAmt. /// @brief Logical right-shift function. -inline APInt LShr(const APInt& LHS, unsigned shiftAmt) { - return LHS.LShr(shiftAmt); +inline APInt lshr(const APInt& LHS, unsigned shiftAmt) { + return LHS.lshr(shiftAmt); } /// Left-shift the APInt by shiftAmt. /// @brief Left-shift function. -inline APInt Shl(const APInt& LHS, unsigned shiftAmt) { - return LHS.Shl(shiftAmt); +inline APInt shl(const APInt& LHS, unsigned shiftAmt) { + return LHS.shl(shiftAmt); } /// Signed divide APInt LHS by APInt RHS. /// @brief Signed division function for APInt. -inline APInt SDiv(const APInt& LHS, const APInt& RHS) { - return LHS.SDiv(RHS); +inline APInt sdiv(const APInt& LHS, const APInt& RHS) { + return LHS.sdiv(RHS); } /// Unsigned divide APInt LHS by APInt RHS. /// @brief Unsigned division function for APInt. -inline APInt UDiv(const APInt& LHS, const APInt& RHS) { - return LHS.UDiv(RHS); +inline APInt udiv(const APInt& LHS, const APInt& RHS) { + return LHS.udiv(RHS); } /// Signed remainder operation on APInt. /// @brief Function for signed remainder operation. -inline APInt SRem(const APInt& LHS, const APInt& RHS) { - return LHS.SRem(RHS); +inline APInt srem(const APInt& LHS, const APInt& RHS) { + return LHS.srem(RHS); } /// Unsigned remainder operation on APInt. /// @brief Function for unsigned remainder operation. -inline APInt URem(const APInt& LHS, const APInt& RHS) { - return LHS.URem(RHS); +inline APInt urem(const APInt& LHS, const APInt& RHS) { + return LHS.urem(RHS); } /// Performs multiplication on APInt values. /// @brief Function for multiplication operation. -inline APInt Mul(const APInt& LHS, const APInt& RHS) { +inline APInt mul(const APInt& LHS, const APInt& RHS) { return LHS * RHS; } /// Performs addition on APInt values. /// @brief Function for addition operation. -inline APInt Add(const APInt& LHS, const APInt& RHS) { +inline APInt add(const APInt& LHS, const APInt& RHS) { return LHS + RHS; } /// Performs subtraction on APInt values. /// @brief Function for subtraction operation. -inline APInt Sub(const APInt& LHS, const APInt& RHS) { +inline APInt sub(const APInt& LHS, const APInt& RHS) { return LHS - RHS; } diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 8989b01af81..7f18ca28b42 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(n, getNumWords()); - unsigned minN = std::min(n, getNumWords()); + unsigned maxN = std::max(numWords, getNumWords()); + unsigned minN = std::min(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 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 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 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);