#ifndef LLVM_APINT_H
#define LLVM_APINT_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <climits>
/// not assume that the string is well-formed and (2) grows the
/// result to hold the input.
///
- /// @param radix 2, 8, 10, or 16
+ /// @param radix 2, 8, 10, 16, or 36
/// @brief Convert a char array into an APInt
void fromString(unsigned numBits, StringRef str, uint8_t radix);
/// out-of-line slow case for inline constructor
void initSlowCase(unsigned numBits, uint64_t val, bool isSigned);
+ /// shared code between two array constructors
+ void initFromArray(ArrayRef<uint64_t> array);
+
/// out-of-line slow case for inline copy constructor
void initSlowCase(const APInt& that);
clearUnusedBits();
}
- /// Note that numWords can be smaller or larger than the corresponding bit
- /// width but any extraneous bits will be dropped.
+ /// Note that bigVal.size() can be smaller or larger than the corresponding
+ /// bit width but any extraneous bits will be dropped.
/// @param numBits the bit width of the constructed APInt
- /// @param numWords the number of words in bigVal
/// @param bigVal a sequence of words to form the initial value of the APInt
/// @brief Construct an APInt of numBits width, initialized as bigVal[].
+ APInt(unsigned numBits, ArrayRef<uint64_t> bigVal);
+ /// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but
+ /// deprecated because this constructor is prone to ambiguity with the
+ /// APInt(unsigned, uint64_t, bool) constructor.
+ ///
+ /// If this overload is ever deleted, care should be taken to prevent calls
+ /// from being incorrectly captured by the APInt(unsigned, uint64_t, bool)
+ /// constructor.
APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
/// 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.
+ /// are 2, 8, 10, 16, and 36. 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 str the string to be interpreted
/// objects, into FoldingSets.
void Profile(FoldingSetNodeID& id) const;
- /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
- void Emit(Serializer& S) const;
-
- /// @brief Used by the Bitcode deserializer to deserialize APInts.
- void Read(Deserializer& D);
-
/// @}
/// @name Value Tests
/// @{
/// @returns true if this APInt is positive.
/// @brief Determine if this APInt Value is positive.
bool isStrictlyPositive() const {
- return isNonNegative() && (*this) != 0;
+ return isNonNegative() && !!*this;
}
/// This checks to see if the value has all bits of the APInt are set or not.
/// value for the APInt's bit width.
/// @brief Determine if this is the smallest unsigned value.
bool isMinValue() const {
- return countPopulation() == 0;
+ return !*this;
}
/// This checks to see if the value of this APInt is the minimum signed
/// value for the APInt's bit width.
/// @brief Determine if this is the smallest signed value.
bool isMinSignedValue() const {
- return BitWidth == 1 ? VAL == 1 :
- isNegative() && countPopulation() == 1;
+ return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2();
}
/// @brief Check if this APInt has an N-bits unsigned integer value.
return true;
if (isSingleWord())
- return VAL == (VAL & (~0ULL >> (64 - N)));
- APInt Tmp(N, getNumWords(), pVal);
- Tmp.zext(getBitWidth());
- return Tmp == (*this);
+ return isUIntN(N, VAL);
+ return APInt(N, makeArrayRef(pVal, getNumWords())).zext(getBitWidth())
+ == (*this);
}
/// @brief Check if this APInt has an N-bits signed integer value.
}
/// @returns true if the argument APInt value is a power of two > 0.
- bool isPowerOf2() const;
+ bool isPowerOf2() const {
+ if (isSingleWord())
+ return isPowerOf2_64(VAL);
+ return countPopulationSlowCase() == 1;
+ }
/// isSignBit - Return true if this is the value returned by getSignBit.
bool isSignBit() const { return isMinSignedValue(); }
/// This converts the APInt to a boolean value as a test against zero.
/// @brief Boolean conversion function.
bool getBoolValue() const {
- return *this != 0;
+ return !!*this;
}
/// getLimitedValue - If this value is smaller than the specified limit,
/// @{
/// @brief Gets maximum unsigned value of APInt for specific bit width.
static APInt getMaxValue(unsigned numBits) {
- return APInt(numBits, 0).set();
+ return getAllOnesValue(numBits);
}
/// @brief Gets maximum signed value of APInt for a specific bit width.
static APInt getSignedMaxValue(unsigned numBits) {
- return APInt(numBits, 0).set().clear(numBits - 1);
+ APInt API = getAllOnesValue(numBits);
+ API.clearBit(numBits - 1);
+ return API;
}
/// @brief Gets minimum unsigned value of APInt for a specific bit width.
/// @brief Gets minimum signed value of APInt for a specific bit width.
static APInt getSignedMinValue(unsigned numBits) {
- return APInt(numBits, 0).set(numBits - 1);
+ APInt API(numBits, 0);
+ API.setBit(numBits - 1);
+ return API;
}
/// getSignBit - This is just a wrapper function of getSignedMinValue(), and
/// @returns the all-ones value for an APInt of the specified bit-width.
/// @brief Get the all-ones value.
static APInt getAllOnesValue(unsigned numBits) {
- return APInt(numBits, 0).set();
+ return APInt(numBits, -1ULL, true);
}
/// @returns the '0' value for an APInt of the specified bit-width.
/// @returns the low "numBits" bits of this APInt.
APInt getLoBits(unsigned numBits) const;
+ /// getOneBitSet - Return an APInt with exactly one bit set in the result.
+ static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {
+ APInt Res(numBits, 0);
+ Res.setBit(BitNo);
+ return Res;
+ }
+
/// Constructs an APInt value that has a contiguous range of bits set. The
/// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other
/// bits will be zero. For example, with parameters(32, 0, 16) you would get
/// @brief Unary bitwise complement operator.
APInt operator~() const {
APInt Result(*this);
- Result.flip();
+ Result.flipAllBits();
return Result;
}
// Operations that return overflow indicators.
-
- // ssub_ov - Signed subtraction. Unsigned subtraction never overflows.
- APInt sadd_ov(const APInt &RHS, bool &Overflow);
- APInt ssub_ov(const APInt &RHS, bool &Overflow);
- APInt sdiv_ov(const APInt &RHS, bool &Overflow);
- APInt smul_ov(const APInt &RHS, bool &Overflow);
- APInt sshl_ov(unsigned Amt, bool &Overflow);
+ APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
+ APInt uadd_ov(const APInt &RHS, bool &Overflow) const;
+ APInt ssub_ov(const APInt &RHS, bool &Overflow) const;
+ APInt usub_ov(const APInt &RHS, bool &Overflow) const;
+ APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
+ APInt smul_ov(const APInt &RHS, bool &Overflow) const;
+ APInt umul_ov(const APInt &RHS, bool &Overflow) const;
+ APInt sshl_ov(unsigned Amt, bool &Overflow) const;
/// @returns the bit value at bitPosition
/// @brief Array-indexing support.
/// the validity of the less-than relationship.
/// @returns true if *this < RHS when both are considered unsigned.
/// @brief Unsigned less than comparison
- bool ult(const APInt& RHS) const;
+ bool ult(const APInt &RHS) const;
/// Regards both *this as an unsigned quantity and compares it with RHS for
/// the validity of the less-than relationship.
/// Truncate the APInt to a specified width. It is an error to specify a width
/// that is greater than or equal to the current width.
/// @brief Truncate to new width.
- APInt &trunc(unsigned width);
+ APInt trunc(unsigned width) const;
/// This operation sign extends the APInt to a new width. If the high order
/// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
/// It is an error to specify a width that is less than or equal to the
/// current width.
/// @brief Sign extend to a new width.
- APInt &sext(unsigned width);
+ APInt sext(unsigned width) const;
/// This operation zero extends the APInt to a new width. The high order bits
/// are filled with 0 bits. It is an error to specify a width that is less
/// than or equal to the current width.
/// @brief Zero extend to a new width.
- APInt &zext(unsigned width);
+ APInt zext(unsigned width) const;
/// Make this APInt have the bit width given by \p width. The value is sign
/// extended, truncated, or left alone to make it that width.
/// @brief Sign extend or truncate to width
- APInt &sextOrTrunc(unsigned width);
+ APInt sextOrTrunc(unsigned width) const;
/// Make this APInt have the bit width given by \p width. The value is zero
/// extended, truncated, or left alone to make it that width.
/// @brief Zero extend or truncate to width
- APInt &zextOrTrunc(unsigned width);
+ APInt zextOrTrunc(unsigned width) const;
/// @}
/// @name Bit Manipulation Operators
/// @{
/// @brief Set every bit to 1.
- APInt &set() {
- if (isSingleWord()) {
+ void setAllBits() {
+ if (isSingleWord())
VAL = -1ULL;
- return clearUnusedBits();
+ else {
+ // Set all the bits in all the words.
+ for (unsigned i = 0; i < getNumWords(); ++i)
+ pVal[i] = -1ULL;
}
-
- // Set all the bits in all the words.
- for (unsigned i = 0; i < getNumWords(); ++i)
- pVal[i] = -1ULL;
// Clear the unused ones
- return clearUnusedBits();
+ clearUnusedBits();
}
/// Set the given bit to 1 whose position is given as "bitPosition".
/// @brief Set a given bit to 1.
- APInt &set(unsigned bitPosition);
+ void setBit(unsigned bitPosition);
/// @brief Set every bit to 0.
- APInt &clear() {
+ void clearAllBits() {
if (isSingleWord())
VAL = 0;
else
memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
- return *this;
}
/// Set the given bit to 0 whose position is given as "bitPosition".
/// @brief Set a given bit to 0.
- APInt &clear(unsigned bitPosition);
+ void clearBit(unsigned bitPosition);
/// @brief Toggle every bit to its opposite value.
- APInt &flip() {
- if (isSingleWord()) {
+ void flipAllBits() {
+ if (isSingleWord())
VAL ^= -1ULL;
- return clearUnusedBits();
+ else {
+ for (unsigned i = 0; i < getNumWords(); ++i)
+ pVal[i] ^= -1ULL;
}
- for (unsigned i = 0; i < getNumWords(); ++i)
- pVal[i] ^= -1ULL;
- return clearUnusedBits();
+ clearUnusedBits();
}
/// Toggle a given bit to its opposite value whose position is given
/// as "bitPosition".
/// @brief Toggles a given bit to its opposite value.
- APInt& flip(unsigned bitPosition);
+ void flipBit(unsigned bitPosition);
/// @}
/// @name Value Characterization Functions
/// @brief Count the number of leading one bits.
unsigned countLeadingOnes() const;
+ /// Computes the number of leading bits of this APInt that are equal to its
+ /// sign bit.
+ unsigned getNumSignBits() const {
+ return isNegative() ? countLeadingOnes() : countLeadingZeros();
+ }
+
/// countTrailingZeros - This function is an APInt version of the
/// countTrailingZeros_{32,64} functions in MathExtras.h. It counts
/// the number of zeros from the least significant bit to the first set bit.
/// toString - Converts an APInt to a string and append it to Str. Str is
/// commonly a SmallString.
- void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed) const;
+ void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
+ bool formatAsCLiteral = false) const;
/// Considers the APInt to be unsigned and converts it into a string in the
- /// radix given. The radix can be 2, 8, 10 or 16.
+ /// radix given. The radix can be 2, 8, 10 16, or 36.
void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
- toString(Str, Radix, false);
+ toString(Str, Radix, false, false);
}
/// Considers the APInt to be signed and converts it into a string in the
- /// radix given. The radix can be 2, 8, 10 or 16.
+ /// radix given. The radix can be 2, 8, 10, 16, or 36.
void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
- toString(Str, Radix, true);
+ toString(Str, Radix, true, false);
}
/// toString - This returns the APInt as a std::string. Note that this is an
}
/// The conversion does not do a translation from double to integer, it just
- /// re-interprets the bits of the double. Note that it is valid to do this on
- /// any bit width but bits from V may get truncated.
+ /// re-interprets the bits of the double.
/// @brief Converts a double to APInt bits.
- APInt& doubleToBits(double V) {
+ static APInt doubleToBits(double V) {
union {
uint64_t I;
double D;
} T;
T.D = V;
- if (isSingleWord())
- VAL = T.I;
- else
- pVal[0] = T.I;
- return clearUnusedBits();
+ return APInt(sizeof T * CHAR_BIT, T.I);
}
/// The conversion does not do a translation from float to integer, it just
- /// re-interprets the bits of the float. Note that it is valid to do this on
- /// any bit width but bits from V may get truncated.
+ /// re-interprets the bits of the float.
/// @brief Converts a float to APInt bits.
- APInt& floatToBits(float V) {
+ static APInt floatToBits(float V) {
union {
unsigned I;
float F;
} T;
T.F = V;
- if (isSingleWord())
- VAL = T.I;
- else
- pVal[0] = T.I;
- return clearUnusedBits();
+ return APInt(sizeof T * CHAR_BIT, T.I);
}
/// @}
/// Calculate the magic number for unsigned division by a constant.
struct mu;
- mu magicu() const;
+ mu magicu(unsigned LeadingZeros = 0) const;
/// @}
/// @name Building-block Operations for APInt and APFloat