#ifndef LLVM_APINT_H
#define LLVM_APINT_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
+#include <climits>
#include <cstring>
#include <string>
class Deserializer;
class FoldingSetNodeID;
class raw_ostream;
+ class StringRef;
template<typename T>
class SmallVectorImpl;
- /* An unsigned host type used as a single part of a multi-part
- bignum. */
+ // An unsigned host type used as a single part of a multi-part
+ // bignum.
typedef uint64_t integerPart;
const unsigned int host_char_bit = 8;
/// This enum is used to hold the constants we needed for APInt.
enum {
/// Bits in a word
- APINT_BITS_PER_WORD = static_cast<unsigned int>(sizeof(uint64_t)) * 8,
+ APINT_BITS_PER_WORD = static_cast<unsigned int>(sizeof(uint64_t)) *
+ CHAR_BIT,
/// Byte size of a word
APINT_WORD_SIZE = static_cast<unsigned int>(sizeof(uint64_t))
};
return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
}
+ /// Converts a string into a number. The string must be non-empty
+ /// and well-formed as a number of the given base. The bit-width
+ /// must be sufficient to hold the result.
+ ///
/// This is used by the constructors that take string arguments.
+ ///
+ /// StringRef::getAsInteger is superficially similar but (1) does
+ /// not assume that the string is well-formed and (2) grows the
+ /// result to hold the input.
+ ///
+ /// @param radix 2, 8, 10, or 16
/// @brief Convert a char array into an APInt
- void fromString(unsigned numBits, const char *strStart, unsigned slen,
- uint8_t radix);
+ void fromString(unsigned numBits, StringRef str, uint8_t radix);
/// This is used by the toString method to divide by the radix. It simply
/// provides a more convenient form of divide for internal use since KnuthDiv
/// @brief Construct an APInt of numBits width, initialized as bigVal[].
APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
- /// This constructor interprets the slen characters starting at StrStart as
- /// a string in the given radix. The interpretation stops when the first
- /// character that is not suitable for the radix is encountered. Acceptable
- /// radix values are 2, 8, 10 and 16. It is an error for the value implied by
- /// the string to require more bits than numBits.
+ /// This constructor interprets the string \arg str in the given radix. The
+ /// interpretation stops when the first character that is not suitable for the
+ /// radix is encountered, or the end of the string. Acceptable radix values
+ /// are 2, 8, 10 and 16. It is an error for the value implied by the string to
+ /// require more bits than numBits.
+ ///
/// @param numBits the bit width of the constructed APInt
- /// @param strStart the start of the string to be interpreted
- /// @param slen the maximum number of characters to interpret
- /// @param radix the radix to use for the conversion
+ /// @param str the string to be interpreted
+ /// @param radix the radix to use for the conversion
/// @brief Construct an APInt from a string representation.
- APInt(unsigned numBits, const char strStart[], unsigned slen, uint8_t radix);
+ APInt(unsigned numBits, StringRef str, uint8_t radix);
/// Simply makes *this a copy of that.
/// @brief Copy Constructor.
// For small values, return quickly
if (numBits <= APINT_BITS_PER_WORD)
return APInt(numBits, ~0ULL << shiftAmt);
- return (~APInt(numBits, 0)).shl(shiftAmt);
+ return getAllOnesValue(numBits).shl(shiftAmt);
}
/// Constructs an APInt value that has the bottom loBitsSet bits set.
// For small values, return quickly.
if (numBits < APINT_BITS_PER_WORD)
return APInt(numBits, (1ULL << loBitsSet) - 1);
- return (~APInt(numBits, 0)).lshr(numBits - loBitsSet);
+ return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
}
/// The hash value is computed as the sum of the words and the bit width.
/// @brief Bitwise OR assignment operator.
APInt& operator|=(const APInt& RHS);
+ /// Performs a bitwise OR operation on this APInt and RHS. RHS is
+ /// logically zero-extended or truncated to match the bit-width of
+ /// the LHS.
+ ///
+ /// @brief Bitwise OR assignment operator.
+ APInt& operator|=(uint64_t RHS) {
+ if (isSingleWord()) {
+ VAL |= RHS;
+ clearUnusedBits();
+ } else {
+ pVal[0] |= RHS;
+ }
+ return *this;
+ }
+
/// Performs a bitwise XOR operation on this APInt and RHS. The result is
/// assigned to *this.
/// @returns *this after XORing with RHS.
/// @brief Unsigned less than comparison
bool ult(const APInt& RHS) const;
+ /// Regards both *this as an unsigned quantity and compares it with RHS for
+ /// the validity of the less-than relationship.
+ /// @returns true if *this < RHS when considered unsigned.
+ /// @brief Unsigned less than comparison
+ bool ult(uint64_t RHS) const {
+ return ult(APInt(getBitWidth(), RHS));
+ }
+
/// Regards both *this and RHS as signed quantities and compares them for
/// validity of the less-than relationship.
/// @returns true if *this < RHS when both are considered signed.
/// @brief Signed less than comparison
bool slt(const APInt& RHS) const;
+ /// Regards both *this as a signed quantity and compares it with RHS for
+ /// the validity of the less-than relationship.
+ /// @returns true if *this < RHS when considered signed.
+ /// @brief Signed less than comparison
+ bool slt(uint64_t RHS) const {
+ return slt(APInt(getBitWidth(), RHS));
+ }
+
/// Regards both *this and RHS as unsigned quantities and compares them for
/// validity of the less-or-equal relationship.
/// @returns true if *this <= RHS when both are considered unsigned.
return ult(RHS) || eq(RHS);
}
+ /// Regards both *this as an unsigned quantity and compares it with RHS for
+ /// the validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when considered unsigned.
+ /// @brief Unsigned less or equal comparison
+ bool ule(uint64_t RHS) const {
+ return ule(APInt(getBitWidth(), RHS));
+ }
+
/// Regards both *this and RHS as signed quantities and compares them for
/// validity of the less-or-equal relationship.
/// @returns true if *this <= RHS when both are considered signed.
return slt(RHS) || eq(RHS);
}
+ /// Regards both *this as a signed quantity and compares it with RHS for
+ /// the validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when considered signed.
+ /// @brief Signed less or equal comparison
+ bool sle(uint64_t RHS) const {
+ return sle(APInt(getBitWidth(), RHS));
+ }
+
/// Regards both *this and RHS as unsigned quantities and compares them for
/// the validity of the greater-than relationship.
/// @returns true if *this > RHS when both are considered unsigned.
return !ult(RHS) && !eq(RHS);
}
+ /// Regards both *this as an unsigned quantity and compares it with RHS for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when considered unsigned.
+ /// @brief Unsigned greater than comparison
+ bool ugt(uint64_t RHS) const {
+ return ugt(APInt(getBitWidth(), RHS));
+ }
+
/// Regards both *this and RHS as signed quantities and compares them for
/// the validity of the greater-than relationship.
/// @returns true if *this > RHS when both are considered signed.
return !slt(RHS) && !eq(RHS);
}
+ /// Regards both *this as a signed quantity and compares it with RHS for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when considered signed.
+ /// @brief Signed greater than comparison
+ bool sgt(uint64_t RHS) const {
+ return sgt(APInt(getBitWidth(), RHS));
+ }
+
/// Regards both *this and RHS as unsigned quantities and compares them for
/// validity of the greater-or-equal relationship.
/// @returns true if *this >= RHS when both are considered unsigned.
return !ult(RHS);
}
+ /// Regards both *this as an unsigned quantity and compares it with RHS for
+ /// the validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when considered unsigned.
+ /// @brief Unsigned greater or equal comparison
+ bool uge(uint64_t RHS) const {
+ return uge(APInt(getBitWidth(), RHS));
+ }
+
/// Regards both *this and RHS as signed quantities and compares them for
/// validity of the greater-or-equal relationship.
/// @returns true if *this >= RHS when both are considered signed.
return !slt(RHS);
}
+ /// Regards both *this as a signed quantity and compares it with RHS for
+ /// the validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when considered signed.
+ /// @brief Signed greater or equal comparison
+ bool sge(uint64_t RHS) const {
+ return sge(APInt(getBitWidth(), RHS));
+ }
+
/// This operation tests if there are any pairs of corresponding bits
/// between this APInt and RHS that are both set.
bool intersects(const APInt &RHS) const {
/// @returns the number of words to hold the integer value of this APInt.
/// @brief Get the number of words.
unsigned getNumWords() const {
+ return getNumWords(BitWidth);
+ }
+
+ /// Here one word's bitwidth equals to that of uint64_t.
+ /// @returns the number of words to hold the integer value with a
+ /// given bit width.
+ /// @brief Get the number of words.
+ static unsigned getNumWords(unsigned BitWidth) {
return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
}
}
/// This method determines how many bits are required to hold the APInt
- /// equivalent of the string given by \p str of length \p slen.
+ /// equivalent of the string given by \arg str.
/// @brief Get bits required for string value.
- static unsigned getBitsNeeded(const char* str, unsigned slen, uint8_t radix);
+ static unsigned getBitsNeeded(StringRef str, uint8_t radix);
/// countLeadingZeros - This function is an APInt version of the
/// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
return BitWidth - 1 - countLeadingZeros();
}
+ /// @returns the ceil log base 2 of this APInt.
+ unsigned ceilLogBase2() const {
+ return BitWidth - (*this - 1).countLeadingZeros();
+ }
+
/// @returns the log base 2 of this APInt if its an exact power of two, -1
/// otherwise
int32_t exactLogBase2() const {
/// @returns the multiplicative inverse for a given modulo.
APInt multiplicativeInverse(const APInt& modulo) const;
+ /// @}
+ /// @name Support for division by constant
+ /// @{
+
+ /// Calculate the magic number for signed division by a constant.
+ struct ms;
+ ms magic() const;
+
+ /// Calculate the magic number for unsigned division by a constant.
+ struct mu;
+ mu magicu() const;
+
/// @}
/// @name Building-block Operations for APInt and APFloat
/// @{
/// srcLSB, to DST, of dstCOUNT parts, such that the bit srcLSB
/// becomes the least significant bit of DST. All high bits above
/// srcBITS in DST are zero-filled.
- static void tcExtract(integerPart *, unsigned int dstCount, const integerPart *,
+ static void tcExtract(integerPart *, unsigned int dstCount,
+ const integerPart *,
unsigned int srcBits, unsigned int srcLSB);
/// Set the given bit of a bignum. Zero-based.
static void tcSetBit(integerPart *, unsigned int bit);
+ /// Clear the given bit of a bignum. Zero-based.
+ static void tcClearBit(integerPart *, unsigned int bit);
+
/// Returns the bit number of the least or most significant set bit
/// of a number. If the input number has no bits set -1U is
/// returned.
/// @}
};
+/// Magic data for optimising signed division by a constant.
+struct APInt::ms {
+ APInt m; ///< magic number
+ unsigned s; ///< shift amount
+};
+
+/// Magic data for optimising unsigned division by a constant.
+struct APInt::mu {
+ APInt m; ///< magic number
+ bool a; ///< add indicator
+ unsigned s; ///< shift amount
+};
+
inline bool operator==(uint64_t V1, const APInt& V2) {
return V2 == V1;
}