/// 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);
}
//===----------------------------------------------------------------------===//
/// 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.
///
-/// @brief Class for arbitrary precision integers.
-///
-/// Note: In this class, all bit/byte/word positions are zero-based.
+/// 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.
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;
/// @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<uint64_t>(1)) << whichBit(bitPosition); }
+ static inline uint64_t maskBit(unsigned bitPosition) {
+ return (static_cast<uint64_t>(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);
/// @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;
/// @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.
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;
-
- /// 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;
-
- /// 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 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 Equality comparison
+ bool eq(const APInt &RHS) const {
+ return (*this) == RHS;
+ }
+
+ /// @brief Inequality comparison
+ bool ne(const APInt &RHS) const {
+ return !((*this) == RHS);
+ }
+
+ /// @brief Unsigned less than comparison
+ bool ult(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");
/// @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;
};
/// @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
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;
}
} 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
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()]) &&
}
}
-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!");
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);
}
APInt::APInt(const APInt& APIVal)
- : BitsNum(APIVal.BitsNum) {
+ : BitWidth(APIVal.BitWidth) {
if (isSingleWord()) VAL = APIVal.VAL;
else {
// Memory allocation and check if successful.
/// @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);
/// @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;
}
if (isSingleWord()) --VAL;
else
sub_1(pVal, getNumWords(), 1);
- TruncToBits();
+ clearUnusedBits();
return *this;
}
}
}
}
- TruncToBits();
+ clearUnusedBits();
return *this;
}
sub(pVal, pVal, RHS.pVal, getNumWords());
}
}
- TruncToBits();
+ clearUnusedBits();
return *this;
}
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);
delete[] dest;
}
}
- TruncToBits();
+ clearUnusedBits();
return *this;
}
pVal[i] |= RHS.pVal[i];
}
}
- TruncToBits();
+ clearUnusedBits();
return *this;
}
pVal[i] ^= 0;
}
}
- TruncToBits();
+ clearUnusedBits();
return *this;
}
APInt APInt::operator|(const APInt& RHS) const {
APInt API(RHS);
API |= *this;
- API.TruncToBits();
+ API.clearUnusedBits();
return API;
}
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.
APInt APInt::operator*(const APInt& RHS) const {
APInt API(RHS);
API *= *this;
- API.TruncToBits();
+ API.clearUnusedBits();
return API;
}
APInt APInt::operator+(const APInt& RHS) const {
APInt API(*this);
API += RHS;
- API.TruncToBits();
+ API.clearUnusedBits();
return API;
}
/// @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]);
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
}
}
-/// @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;
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) {
/// @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;
}
/// @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;
/// 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" :
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;
}
/// 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;
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;
}
-/// 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;
}
APInt A = API1, B = API2;
while (!!B) {
APInt T = B;
- B = APIntOps::URem(A, B);
+ B = APIntOps::urem(A, B);
A = T;
}
return A;
/// 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;
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;
}
/// |-------------------------------------- |
/// | 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
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);
}
/// 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;
/// 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) {
(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);
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,
/// 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);
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);