diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:25:46 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:25:46 +0000 | 
| commit | 7a7e6055035bfd93ab507051819373a6f171258b (patch) | |
| tree | dc9ac22b4fea4f445748feaf7232a146623f0dfa /contrib/llvm/lib/Support/APInt.cpp | |
| parent | b96a714f453e7f5aeeb3c2df2c3e1e8ad749f96f (diff) | |
| parent | 71d5a2540a98c81f5bcaeb48805e0e2881f530ef (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/lib/Support/APInt.cpp')
| -rw-r--r-- | contrib/llvm/lib/Support/APInt.cpp | 938 | 
1 files changed, 432 insertions, 506 deletions
diff --git a/contrib/llvm/lib/Support/APInt.cpp b/contrib/llvm/lib/Support/APInt.cpp index fb8b45166a41..0c7da1dad0d2 100644 --- a/contrib/llvm/lib/Support/APInt.cpp +++ b/contrib/llvm/lib/Support/APInt.cpp @@ -63,7 +63,7 @@ inline static unsigned getDigit(char cdigit, uint8_t radix) {      r = cdigit - 'a';      if (r <= radix - 11U)        return r + 10; -     +      radix = 10;    } @@ -76,14 +76,17 @@ inline static unsigned getDigit(char cdigit, uint8_t radix) {  void APInt::initSlowCase(uint64_t val, bool isSigned) { +  VAL = 0;    pVal = getClearedMemory(getNumWords());    pVal[0] = val;    if (isSigned && int64_t(val) < 0)      for (unsigned i = 1; i < getNumWords(); ++i)        pVal[i] = -1ULL; +  clearUnusedBits();  }  void APInt::initSlowCase(const APInt& that) { +  VAL = 0;    pVal = getMemory(getNumWords());    memcpy(pVal, that.pVal, getNumWords() * APINT_WORD_SIZE);  } @@ -95,6 +98,7 @@ void APInt::initFromArray(ArrayRef<uint64_t> bigVal) {      VAL = bigVal[0];    else {      // Get memory, cleared to 0 +    VAL = 0;      pVal = getClearedMemory(getNumWords());      // Calculate the number of words to copy      unsigned words = std::min<unsigned>(bigVal.size(), getNumWords()); @@ -106,17 +110,17 @@ void APInt::initFromArray(ArrayRef<uint64_t> bigVal) {  }  APInt::APInt(unsigned numBits, ArrayRef<uint64_t> bigVal) -  : BitWidth(numBits), VAL(0) { +  : BitWidth(numBits) {    initFromArray(bigVal);  }  APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]) -  : BitWidth(numBits), VAL(0) { +  : BitWidth(numBits) {    initFromArray(makeArrayRef(bigVal, numWords));  }  APInt::APInt(unsigned numbits, StringRef Str, uint8_t radix) -  : BitWidth(numbits), VAL(0) { +  : VAL(0), BitWidth(numbits) {    assert(BitWidth && "Bitwidth too small");    fromString(numbits, Str, radix);  } @@ -153,16 +157,6 @@ APInt& APInt::AssignSlowCase(const APInt& RHS) {    return clearUnusedBits();  } -APInt& APInt::operator=(uint64_t RHS) { -  if (isSingleWord()) -    VAL = RHS; -  else { -    pVal[0] = RHS; -    memset(pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE); -  } -  return clearUnusedBits(); -} -  /// This method 'profiles' an APInt for use with FoldingSet.  void APInt::Profile(FoldingSetNodeID& ID) const {    ID.AddInteger(BitWidth); @@ -177,76 +171,24 @@ void APInt::Profile(FoldingSetNodeID& ID) const {      ID.AddInteger(pVal[i]);  } -/// This function adds a single "digit" integer, y, to the multiple -/// "digit" integer array,  x[]. x[] is modified to reflect the addition and -/// 1 is returned if there is a carry out, otherwise 0 is returned. -/// @returns the carry of the addition. -static bool add_1(uint64_t dest[], uint64_t x[], unsigned len, uint64_t y) { -  for (unsigned i = 0; i < len; ++i) { -    dest[i] = y + x[i]; -    if (dest[i] < y) -      y = 1; // Carry one to next digit. -    else { -      y = 0; // No need to carry so exit early -      break; -    } -  } -  return y; -} -  /// @brief Prefix increment operator. Increments the APInt by one.  APInt& APInt::operator++() {    if (isSingleWord())      ++VAL;    else -    add_1(pVal, pVal, getNumWords(), 1); +    tcIncrement(pVal, getNumWords());    return clearUnusedBits();  } -/// This function subtracts a single "digit" (64-bit word), y, from -/// the multi-digit integer array, x[], propagating the borrowed 1 value until -/// no further borrowing is needed or it runs out of "digits" in x.  The result -/// is 1 if "borrowing" exhausted the digits in x, or 0 if x was not exhausted. -/// In other words, if y > x then this function returns 1, otherwise 0. -/// @returns the borrow out of the subtraction -static bool sub_1(uint64_t x[], unsigned len, uint64_t y) { -  for (unsigned i = 0; i < len; ++i) { -    uint64_t X = x[i]; -    x[i] -= y; -    if (y > X) -      y = 1;  // We have to "borrow 1" from next "digit" -    else { -      y = 0;  // No need to borrow -      break;  // Remaining digits are unchanged so exit early -    } -  } -  return bool(y); -} -  /// @brief Prefix decrement operator. Decrements the APInt by one.  APInt& APInt::operator--() {    if (isSingleWord())      --VAL;    else -    sub_1(pVal, getNumWords(), 1); +    tcDecrement(pVal, getNumWords());    return clearUnusedBits();  } -/// This function adds the integer array x to the integer array Y and -/// places the result in dest. -/// @returns the carry out from the addition -/// @brief General addition of 64-bit integer arrays -static bool add(uint64_t *dest, const uint64_t *x, const uint64_t *y, -                unsigned len) { -  bool carry = false; -  for (unsigned i = 0; i< len; ++i) { -    uint64_t limit = std::min(x[i],y[i]); // must come first in case dest == x -    dest[i] = x[i] + y[i] + carry; -    carry = dest[i] < limit || (carry && dest[i] == limit); -  } -  return carry; -} -  /// Adds the RHS APint to this APInt.  /// @returns this, after addition of RHS.  /// @brief Addition assignment operator. @@ -254,9 +196,8 @@ APInt& APInt::operator+=(const APInt& RHS) {    assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");    if (isSingleWord())      VAL += RHS.VAL; -  else { -    add(pVal, pVal, RHS.pVal, getNumWords()); -  } +  else +    tcAdd(pVal, RHS.pVal, 0, getNumWords());    return clearUnusedBits();  } @@ -264,24 +205,10 @@ APInt& APInt::operator+=(uint64_t RHS) {    if (isSingleWord())      VAL += RHS;    else -    add_1(pVal, pVal, getNumWords(), RHS); +    tcAddPart(pVal, RHS, getNumWords());    return clearUnusedBits();  } -/// Subtracts the integer array y from the integer array x -/// @returns returns the borrow out. -/// @brief Generalized subtraction of 64-bit integer arrays. -static bool sub(uint64_t *dest, const uint64_t *x, const uint64_t *y, -                unsigned len) { -  bool borrow = false; -  for (unsigned i = 0; i < len; ++i) { -    uint64_t x_tmp = borrow ? x[i] - 1 : x[i]; -    borrow = y[i] > x_tmp || (borrow && x[i] == 0); -    dest[i] = x_tmp - y[i]; -  } -  return borrow; -} -  /// Subtracts the RHS APInt from this APInt  /// @returns this, after subtraction  /// @brief Subtraction assignment operator. @@ -290,7 +217,7 @@ APInt& APInt::operator-=(const APInt& RHS) {    if (isSingleWord())      VAL -= RHS.VAL;    else -    sub(pVal, pVal, RHS.pVal, getNumWords()); +    tcSubtract(pVal, RHS.pVal, 0, getNumWords());    return clearUnusedBits();  } @@ -298,7 +225,7 @@ APInt& APInt::operator-=(uint64_t RHS) {    if (isSingleWord())      VAL -= RHS;    else -    sub_1(pVal, getNumWords(), RHS); +    tcSubtractPart(pVal, RHS, getNumWords());    return clearUnusedBits();  } @@ -339,7 +266,7 @@ static uint64_t mul_1(uint64_t dest[], uint64_t x[], unsigned len, uint64_t y) {  /// Multiplies integer array x by integer array y and stores the result into  /// the integer array dest. Note that dest's size must be >= xlen + ylen. -/// @brief Generalized multiplicate of integer arrays. +/// @brief Generalized multiplication of integer arrays.  static void mul(uint64_t dest[], uint64_t x[], unsigned xlen, uint64_t y[],                  unsigned ylen) {    dest[xlen] = mul_1(dest, x, xlen, y[0]); @@ -412,69 +339,19 @@ APInt& APInt::operator*=(const APInt& RHS) {    return *this;  } -APInt& APInt::operator&=(const APInt& RHS) { -  assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); -  if (isSingleWord()) { -    VAL &= RHS.VAL; -    return *this; -  } -  unsigned numWords = getNumWords(); -  for (unsigned i = 0; i < numWords; ++i) -    pVal[i] &= RHS.pVal[i]; +APInt& APInt::AndAssignSlowCase(const APInt& RHS) { +  tcAnd(pVal, RHS.pVal, getNumWords());    return *this;  } -APInt& APInt::operator|=(const APInt& RHS) { -  assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); -  if (isSingleWord()) { -    VAL |= RHS.VAL; -    return *this; -  } -  unsigned numWords = getNumWords(); -  for (unsigned i = 0; i < numWords; ++i) -    pVal[i] |= RHS.pVal[i]; +APInt& APInt::OrAssignSlowCase(const APInt& RHS) { +  tcOr(pVal, RHS.pVal, getNumWords());    return *this;  } -APInt& APInt::operator^=(const APInt& RHS) { -  assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); -  if (isSingleWord()) { -    VAL ^= RHS.VAL; -    this->clearUnusedBits(); -    return *this; -  } -  unsigned numWords = getNumWords(); -  for (unsigned i = 0; i < numWords; ++i) -    pVal[i] ^= RHS.pVal[i]; -  return clearUnusedBits(); -} - -APInt APInt::AndSlowCase(const APInt& RHS) const { -  unsigned numWords = getNumWords(); -  uint64_t* val = getMemory(numWords); -  for (unsigned i = 0; i < numWords; ++i) -    val[i] = pVal[i] & RHS.pVal[i]; -  return APInt(val, getBitWidth()); -} - -APInt APInt::OrSlowCase(const APInt& RHS) const { -  unsigned numWords = getNumWords(); -  uint64_t *val = getMemory(numWords); -  for (unsigned i = 0; i < numWords; ++i) -    val[i] = pVal[i] | RHS.pVal[i]; -  return APInt(val, getBitWidth()); -} - -APInt APInt::XorSlowCase(const APInt& RHS) const { -  unsigned numWords = getNumWords(); -  uint64_t *val = getMemory(numWords); -  for (unsigned i = 0; i < numWords; ++i) -    val[i] = pVal[i] ^ RHS.pVal[i]; - -  APInt Result(val, getBitWidth()); -  // 0^0==1 so clear the high bits in case they got set. -  Result.clearUnusedBits(); -  return Result; +APInt& APInt::XorAssignSlowCase(const APInt& RHS) { +  tcXor(pVal, RHS.pVal, getNumWords()); +  return *this;  }  APInt APInt::operator*(const APInt& RHS) const { @@ -511,11 +388,11 @@ bool APInt::ult(const APInt& RHS) const {    if (n1 < n2)      return true; -  // If magnitude of RHS is greather than LHS, return false. +  // If magnitude of RHS is greater than LHS, return false.    if (n2 < n1)      return false; -  // If they bot fit in a word, just compare the low order word +  // If they both fit in a word, just compare the low order word    if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD)      return pVal[0] < RHS.pVal[0]; @@ -545,7 +422,7 @@ bool APInt::slt(const APInt& RHS) const {    if (lhsNeg != rhsNeg)      return lhsNeg; -  // Otherwise we can just use an unsigned comparision, because even negative +  // Otherwise we can just use an unsigned comparison, because even negative    // numbers compare correctly this way if both have the same signed-ness.    return ult(RHS);  } @@ -557,6 +434,33 @@ void APInt::setBit(unsigned bitPosition) {      pVal[whichWord(bitPosition)] |= maskBit(bitPosition);  } +void APInt::setBitsSlowCase(unsigned loBit, unsigned hiBit) { +  unsigned loWord = whichWord(loBit); +  unsigned hiWord = whichWord(hiBit); + +  // Create an initial mask for the low word with zeros below loBit. +  uint64_t loMask = UINT64_MAX << whichBit(loBit); + +  // If hiBit is not aligned, we need a high mask. +  unsigned hiShiftAmt = whichBit(hiBit); +  if (hiShiftAmt != 0) { +    // Create a high mask with zeros above hiBit. +    uint64_t hiMask = UINT64_MAX >> (APINT_BITS_PER_WORD - hiShiftAmt); +    // If loWord and hiWord are equal, then we combine the masks. Otherwise, +    // set the bits in hiWord. +    if (hiWord == loWord) +      loMask &= hiMask; +    else +      pVal[hiWord] |= hiMask; +  } +  // Apply the mask to the low word. +  pVal[loWord] |= loMask; + +  // Fill any words between loWord and hiWord with all ones. +  for (unsigned word = loWord + 1; word < hiWord; ++word) +    pVal[word] = UINT64_MAX; +} +  /// Set the given bit to 0 whose position is given as "bitPosition".  /// @brief Set a given bit to 0.  void APInt::clearBit(unsigned bitPosition) { @@ -567,6 +471,10 @@ void APInt::clearBit(unsigned bitPosition) {  }  /// @brief Toggle every bit to its opposite value. +void APInt::flipAllBitsSlowCase() { +  tcComplement(pVal, getNumWords()); +  clearUnusedBits(); +}  /// Toggle a given bit to its opposite value whose position is given  /// as "bitPosition". @@ -577,9 +485,104 @@ void APInt::flipBit(unsigned bitPosition) {    else setBit(bitPosition);  } +void APInt::insertBits(const APInt &subBits, unsigned bitPosition) { +  unsigned subBitWidth = subBits.getBitWidth(); +  assert(0 < subBitWidth && (subBitWidth + bitPosition) <= BitWidth && +         "Illegal bit insertion"); + +  // Insertion is a direct copy. +  if (subBitWidth == BitWidth) { +    *this = subBits; +    return; +  } + +  // Single word result can be done as a direct bitmask. +  if (isSingleWord()) { +    uint64_t mask = UINT64_MAX >> (APINT_BITS_PER_WORD - subBitWidth); +    VAL &= ~(mask << bitPosition); +    VAL |= (subBits.VAL << bitPosition); +    return; +  } + +  unsigned loBit = whichBit(bitPosition); +  unsigned loWord = whichWord(bitPosition); +  unsigned hi1Word = whichWord(bitPosition + subBitWidth - 1); + +  // Insertion within a single word can be done as a direct bitmask. +  if (loWord == hi1Word) { +    uint64_t mask = UINT64_MAX >> (APINT_BITS_PER_WORD - subBitWidth); +    pVal[loWord] &= ~(mask << loBit); +    pVal[loWord] |= (subBits.VAL << loBit); +    return; +  } + +  // Insert on word boundaries. +  if (loBit == 0) { +    // Direct copy whole words. +    unsigned numWholeSubWords = subBitWidth / APINT_BITS_PER_WORD; +    memcpy(pVal + loWord, subBits.getRawData(), +           numWholeSubWords * APINT_WORD_SIZE); + +    // Mask+insert remaining bits. +    unsigned remainingBits = subBitWidth % APINT_BITS_PER_WORD; +    if (remainingBits != 0) { +      uint64_t mask = UINT64_MAX >> (APINT_BITS_PER_WORD - remainingBits); +      pVal[hi1Word] &= ~mask; +      pVal[hi1Word] |= subBits.getWord(subBitWidth - 1); +    } +    return; +  } + +  // General case - set/clear individual bits in dst based on src. +  // TODO - there is scope for optimization here, but at the moment this code +  // path is barely used so prefer readability over performance. +  for (unsigned i = 0; i != subBitWidth; ++i) { +    if (subBits[i]) +      setBit(bitPosition + i); +    else +      clearBit(bitPosition + i); +  } +} + +APInt APInt::extractBits(unsigned numBits, unsigned bitPosition) const { +  assert(numBits > 0 && "Can't extract zero bits"); +  assert(bitPosition < BitWidth && (numBits + bitPosition) <= BitWidth && +         "Illegal bit extraction"); + +  if (isSingleWord()) +    return APInt(numBits, VAL >> bitPosition); + +  unsigned loBit = whichBit(bitPosition); +  unsigned loWord = whichWord(bitPosition); +  unsigned hiWord = whichWord(bitPosition + numBits - 1); + +  // Single word result extracting bits from a single word source. +  if (loWord == hiWord) +    return APInt(numBits, pVal[loWord] >> loBit); + +  // Extracting bits that start on a source word boundary can be done +  // as a fast memory copy. +  if (loBit == 0) +    return APInt(numBits, makeArrayRef(pVal + loWord, 1 + hiWord - loWord)); + +  // General case - shift + copy source words directly into place. +  APInt Result(numBits, 0); +  unsigned NumSrcWords = getNumWords(); +  unsigned NumDstWords = Result.getNumWords(); + +  for (unsigned word = 0; word < NumDstWords; ++word) { +    uint64_t w0 = pVal[loWord + word]; +    uint64_t w1 = +        (loWord + word + 1) < NumSrcWords ? pVal[loWord + word + 1] : 0; +    Result.pVal[word] = (w0 >> loBit) | (w1 << (APINT_BITS_PER_WORD - loBit)); +  } + +  return Result.clearUnusedBits(); +} +  unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) {    assert(!str.empty() && "Invalid string length"); -  assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 ||  +  assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 ||            radix == 36) &&           "Radix should be 2, 8, 10, 16, or 36!"); @@ -604,7 +607,7 @@ unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) {      return slen * 4 + isNegative;    // FIXME: base 36 -   +    // This is grossly inefficient but accurate. We could probably do something    // with a computation of roughly slen*64/20 and then adjust by the value of    // the first few digits. But, I'm not sure how accurate that could be. @@ -613,7 +616,7 @@ unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) {    // be too large. This avoids the assertion in the constructor. This    // calculation doesn't work appropriately for the numbers 0-9, so just use 4    // bits in that case. -  unsigned sufficient  +  unsigned sufficient      = radix == 10? (slen == 1 ? 4 : slen * 64/18)                   : (slen == 1 ? 7 : slen * 16/3); @@ -647,19 +650,20 @@ bool APInt::isSplat(unsigned SplatSizeInBits) const {  /// This function returns the high "numBits" bits of this APInt.  APInt APInt::getHiBits(unsigned numBits) const { -  return APIntOps::lshr(*this, BitWidth - numBits); +  return this->lshr(BitWidth - numBits);  }  /// This function returns the low "numBits" bits of this APInt.  APInt APInt::getLoBits(unsigned numBits) const { -  return APIntOps::lshr(APIntOps::shl(*this, BitWidth - numBits), -                        BitWidth - numBits); +  APInt Result(getLowBitsSet(BitWidth, numBits)); +  Result &= *this; +  return Result;  }  unsigned APInt::countLeadingZerosSlowCase() const {    unsigned Count = 0;    for (int i = getNumWords()-1; i >= 0; --i) { -    integerPart V = pVal[i]; +    uint64_t V = pVal[i];      if (V == 0)        Count += APINT_BITS_PER_WORD;      else { @@ -729,18 +733,6 @@ unsigned APInt::countPopulationSlowCase() const {    return Count;  } -/// Perform a logical right-shift from Src to Dst, which must be equal or -/// non-overlapping, of Words words, by Shift, which must be less than 64. -static void lshrNear(uint64_t *Dst, uint64_t *Src, unsigned Words, -                     unsigned Shift) { -  uint64_t Carry = 0; -  for (int I = Words - 1; I >= 0; --I) { -    uint64_t Tmp = Src[I]; -    Dst[I] = (Tmp >> Shift) | Carry; -    Carry = Tmp << (64 - Shift); -  } -} -  APInt APInt::byteSwap() const {    assert(BitWidth >= 16 && BitWidth % 16 == 0 && "Cannot byteswap!");    if (BitWidth == 16) @@ -761,8 +753,7 @@ APInt APInt::byteSwap() const {    for (unsigned I = 0, N = getNumWords(); I != N; ++I)      Result.pVal[I] = ByteSwap_64(pVal[N - I - 1]);    if (Result.BitWidth != BitWidth) { -    lshrNear(Result.pVal, Result.pVal, getNumWords(), -             Result.BitWidth - BitWidth); +    Result.lshrInPlace(Result.BitWidth - BitWidth);      Result.BitWidth = BitWidth;    }    return Result; @@ -798,14 +789,46 @@ APInt APInt::reverseBits() const {    return Reversed;  } -APInt llvm::APIntOps::GreatestCommonDivisor(const APInt& API1, -                                            const APInt& API2) { -  APInt A = API1, B = API2; -  while (!!B) { -    APInt T = B; -    B = APIntOps::urem(A, B); -    A = T; +APInt llvm::APIntOps::GreatestCommonDivisor(APInt A, APInt B) { +  // Fast-path a common case. +  if (A == B) return A; + +  // Corner cases: if either operand is zero, the other is the gcd. +  if (!A) return B; +  if (!B) return A; + +  // Count common powers of 2 and remove all other powers of 2. +  unsigned Pow2; +  { +    unsigned Pow2_A = A.countTrailingZeros(); +    unsigned Pow2_B = B.countTrailingZeros(); +    if (Pow2_A > Pow2_B) { +      A.lshrInPlace(Pow2_A - Pow2_B); +      Pow2 = Pow2_B; +    } else if (Pow2_B > Pow2_A) { +      B.lshrInPlace(Pow2_B - Pow2_A); +      Pow2 = Pow2_A; +    } else { +      Pow2 = Pow2_A; +    } +  } + +  // Both operands are odd multiples of 2^Pow_2: +  // +  //   gcd(a, b) = gcd(|a - b| / 2^i, min(a, b)) +  // +  // This is a modified version of Stein's algorithm, taking advantage of +  // efficient countTrailingZeros(). +  while (A != B) { +    if (A.ugt(B)) { +      A -= B; +      A.lshrInPlace(A.countTrailingZeros() - Pow2); +    } else { +      B -= A; +      B.lshrInPlace(B.countTrailingZeros() - Pow2); +    }    } +    return A;  } @@ -1117,68 +1140,59 @@ APInt APInt::lshr(const APInt &shiftAmt) const {    return lshr((unsigned)shiftAmt.getLimitedValue(BitWidth));  } +/// Perform a logical right-shift from Src to Dst of Words words, by Shift, +/// which must be less than 64. If the source and destination ranges overlap, +/// we require that Src >= Dst (put another way, we require that the overall +/// operation is a right shift on the combined range). +static void lshrWords(APInt::WordType *Dst, APInt::WordType *Src, +                      unsigned Words, unsigned Shift) { +  assert(Shift < APInt::APINT_BITS_PER_WORD); + +  if (!Words) +    return; + +  if (Shift == 0) { +    std::memmove(Dst, Src, Words * APInt::APINT_WORD_SIZE); +    return; +  } + +  uint64_t Low = Src[0]; +  for (unsigned I = 1; I != Words; ++I) { +    uint64_t High = Src[I]; +    Dst[I - 1] = +        (Low >> Shift) | (High << (APInt::APINT_BITS_PER_WORD - Shift)); +    Low = High; +  } +  Dst[Words - 1] = Low >> Shift; +} +  /// Logical right-shift this APInt by shiftAmt.  /// @brief Logical right-shift function. -APInt APInt::lshr(unsigned shiftAmt) const { +void APInt::lshrInPlace(unsigned shiftAmt) {    if (isSingleWord()) {      if (shiftAmt >= BitWidth) -      return APInt(BitWidth, 0); +      VAL = 0;      else -      return APInt(BitWidth, this->VAL >> shiftAmt); -  } - -  // If all the bits were shifted out, the result is 0. This avoids issues -  // with shifting by the size of the integer type, which produces undefined -  // results. We define these "undefined results" to always be 0. -  if (shiftAmt >= BitWidth) -    return APInt(BitWidth, 0); - -  // If none of the bits are shifted out, the result is *this. This avoids -  // issues with shifting by the size of the integer type, which produces -  // undefined results in the code below. This is also an optimization. -  if (shiftAmt == 0) -    return *this; - -  // Create some space for the result. -  uint64_t * val = new uint64_t[getNumWords()]; - -  // If we are shifting less than a word, compute the shift with a simple carry -  if (shiftAmt < APINT_BITS_PER_WORD) { -    lshrNear(val, pVal, getNumWords(), shiftAmt); -    APInt Result(val, BitWidth); -    Result.clearUnusedBits(); -    return Result; +      VAL >>= shiftAmt; +    return;    } -  // Compute some values needed by the remaining shift algorithms -  unsigned wordShift = shiftAmt % APINT_BITS_PER_WORD; -  unsigned offset = shiftAmt / APINT_BITS_PER_WORD; +  // Don't bother performing a no-op shift. +  if (!shiftAmt) +    return; -  // If we are shifting whole words, just move whole words -  if (wordShift == 0) { -    for (unsigned i = 0; i < getNumWords() - offset; ++i) -      val[i] = pVal[i+offset]; -    for (unsigned i = getNumWords()-offset; i < getNumWords(); i++) -      val[i] = 0; -    APInt Result(val, BitWidth); -    Result.clearUnusedBits(); -    return Result; -  } +  // Find number of complete words being shifted out and zeroed. +  const unsigned Words = getNumWords(); +  const unsigned ShiftFullWords = +      std::min(shiftAmt / APINT_BITS_PER_WORD, Words); -  // Shift the low order words -  unsigned breakWord = getNumWords() - offset -1; -  for (unsigned i = 0; i < breakWord; ++i) -    val[i] = (pVal[i+offset] >> wordShift) | -             (pVal[i+offset+1] << (APINT_BITS_PER_WORD - wordShift)); -  // Shift the break word. -  val[breakWord] = pVal[breakWord+offset] >> wordShift; +  // Fill in first Words - ShiftFullWords by shifting. +  lshrWords(pVal, pVal + ShiftFullWords, Words - ShiftFullWords, +            shiftAmt % APINT_BITS_PER_WORD); -  // Remaining words are 0 -  for (unsigned i = breakWord+1; i < getNumWords(); ++i) -    val[i] = 0; -  APInt Result(val, BitWidth); -  Result.clearUnusedBits(); -  return Result; +  // The remaining high words are all zero. +  for (unsigned I = Words - ShiftFullWords; I != Words; ++I) +    pVal[I] = 0;  }  /// Left-shift this APInt by shiftAmt. @@ -1244,8 +1258,21 @@ APInt APInt::shlSlowCase(unsigned shiftAmt) const {    return Result;  } +// Calculate the rotate amount modulo the bit width. +static unsigned rotateModulo(unsigned BitWidth, const APInt &rotateAmt) { +  unsigned rotBitWidth = rotateAmt.getBitWidth(); +  APInt rot = rotateAmt; +  if (rotBitWidth < BitWidth) { +    // Extend the rotate APInt, so that the urem doesn't divide by 0. +    // e.g. APInt(1, 32) would give APInt(1, 0). +    rot = rotateAmt.zext(BitWidth); +  } +  rot = rot.urem(APInt(rot.getBitWidth(), BitWidth)); +  return rot.getLimitedValue(BitWidth); +} +  APInt APInt::rotl(const APInt &rotateAmt) const { -  return rotl((unsigned)rotateAmt.getLimitedValue(BitWidth)); +  return rotl(rotateModulo(BitWidth, rotateAmt));  }  APInt APInt::rotl(unsigned rotateAmt) const { @@ -1256,7 +1283,7 @@ APInt APInt::rotl(unsigned rotateAmt) const {  }  APInt APInt::rotr(const APInt &rotateAmt) const { -  return rotr((unsigned)rotateAmt.getLimitedValue(BitWidth)); +  return rotr(rotateModulo(BitWidth, rotateAmt));  }  APInt APInt::rotr(unsigned rotateAmt) const { @@ -1618,7 +1645,7 @@ static void KnuthDiv(unsigned *u, unsigned *v, unsigned *q, unsigned* r,    if (r) {      // The value d is expressed by the "shift" value above since we avoided      // multiplication by d by using a shift left. So, all we have to do is -    // shift right here. In order to mak +    // shift right here.      if (shift) {        unsigned carry = 0;        DEBUG(dbgs() << "KnuthDiv: remainder:"); @@ -2014,7 +2041,7 @@ APInt APInt::sdiv_ov(const APInt &RHS, bool &Overflow) const {  APInt APInt::smul_ov(const APInt &RHS, bool &Overflow) const {    APInt Res = *this * RHS; -   +    if (*this != 0 && RHS != 0)      Overflow = Res.sdiv(RHS) != *this || Res.sdiv(*this) != RHS;    else @@ -2041,7 +2068,7 @@ APInt APInt::sshl_ov(const APInt &ShAmt, bool &Overflow) const {      Overflow = ShAmt.uge(countLeadingZeros());    else      Overflow = ShAmt.uge(countLeadingOnes()); -   +    return *this << ShAmt;  } @@ -2061,7 +2088,7 @@ APInt APInt::ushl_ov(const APInt &ShAmt, bool &Overflow) const {  void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {    // Check our assumptions here    assert(!str.empty() && "Invalid string length"); -  assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 ||  +  assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 ||            radix == 36) &&           "Radix should be 2, 8, 10, 16, or 36!"); @@ -2086,9 +2113,8 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {    // Figure out if we can shift instead of multiply    unsigned shift = (radix == 16 ? 4 : radix == 8 ? 3 : radix == 2 ? 1 : 0); -  // Set up an APInt for the digit to add outside the loop so we don't +  // Set up an APInt for the radix multiplier outside the loop so we don't    // constantly construct/destruct it. -  APInt apdigit(getBitWidth(), 0);    APInt apradix(getBitWidth(), radix);    // Enter digit traversal loop @@ -2105,11 +2131,7 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {      }      // Add in the digit we just interpreted -    if (apdigit.isSingleWord()) -      apdigit.VAL = digit; -    else -      apdigit.pVal[0] = digit; -    *this += apdigit; +    *this += digit;    }    // If its negative, put it in two's complement form    if (isNeg) { @@ -2120,7 +2142,7 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {  void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,                       bool Signed, bool formatAsCLiteral) const { -  assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2 ||  +  assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2 ||            Radix == 36) &&           "Radix should be 2, 8, 10, 16, or 36!"); @@ -2208,7 +2230,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,    // For the 2, 8 and 16 bit cases, we can just shift instead of divide    // because the number of bits per digit (1, 3 and 4 respectively) divides -  // equaly.  We just shift until the value is zero. +  // equally.  We just shift until the value is zero.    if (Radix == 2 || Radix == 8 || Radix == 16) {      // Just shift tmp right for each digit width until it becomes zero      unsigned ShiftAmt = (Radix == 16 ? 4 : (Radix == 8 ? 3 : 1)); @@ -2245,14 +2267,15 @@ std::string APInt::toString(unsigned Radix = 10, bool Signed = true) const {    return S.str();  } - +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)  LLVM_DUMP_METHOD void APInt::dump() const {    SmallString<40> S, U;    this->toStringUnsigned(U);    this->toStringSigned(S);    dbgs() << "APInt(" << BitWidth << "b, " -         << U << "u " << S << "s)"; +         << U << "u " << S << "s)\n";  } +#endif  void APInt::print(raw_ostream &OS, bool isSigned) const {    SmallString<40> S; @@ -2265,83 +2288,60 @@ void APInt::print(raw_ostream &OS, bool isSigned) const {  // Assumed by lowHalf, highHalf, partMSB and partLSB.  A fairly safe  // and unrestricting assumption. -static_assert(integerPartWidth % 2 == 0, "Part width must be divisible by 2!"); +static_assert(APInt::APINT_BITS_PER_WORD % 2 == 0, +              "Part width must be divisible by 2!");  /* Some handy functions local to this file.  */ -namespace { -  /* Returns the integer part with the least significant BITS set. -     BITS cannot be zero.  */ -  static inline integerPart -  lowBitMask(unsigned int bits) -  { -    assert(bits != 0 && bits <= integerPartWidth); +/* Returns the integer part with the least significant BITS set. +   BITS cannot be zero.  */ +static inline APInt::WordType lowBitMask(unsigned bits) { +  assert(bits != 0 && bits <= APInt::APINT_BITS_PER_WORD); -    return ~(integerPart) 0 >> (integerPartWidth - bits); -  } +  return ~(APInt::WordType) 0 >> (APInt::APINT_BITS_PER_WORD - bits); +} -  /* Returns the value of the lower half of PART.  */ -  static inline integerPart -  lowHalf(integerPart part) -  { -    return part & lowBitMask(integerPartWidth / 2); -  } +/* Returns the value of the lower half of PART.  */ +static inline APInt::WordType lowHalf(APInt::WordType part) { +  return part & lowBitMask(APInt::APINT_BITS_PER_WORD / 2); +} -  /* Returns the value of the upper half of PART.  */ -  static inline integerPart -  highHalf(integerPart part) -  { -    return part >> (integerPartWidth / 2); -  } +/* Returns the value of the upper half of PART.  */ +static inline APInt::WordType highHalf(APInt::WordType part) { +  return part >> (APInt::APINT_BITS_PER_WORD / 2); +} -  /* Returns the bit number of the most significant set bit of a part. -     If the input number has no bits set -1U is returned.  */ -  static unsigned int -  partMSB(integerPart value) -  { -    return findLastSet(value, ZB_Max); -  } +/* Returns the bit number of the most significant set bit of a part. +   If the input number has no bits set -1U is returned.  */ +static unsigned partMSB(APInt::WordType value) { +  return findLastSet(value, ZB_Max); +} -  /* Returns the bit number of the least significant set bit of a -     part.  If the input number has no bits set -1U is returned.  */ -  static unsigned int -  partLSB(integerPart value) -  { -    return findFirstSet(value, ZB_Max); -  } +/* Returns the bit number of the least significant set bit of a +   part.  If the input number has no bits set -1U is returned.  */ +static unsigned partLSB(APInt::WordType value) { +  return findFirstSet(value, ZB_Max);  }  /* Sets the least significant part of a bignum to the input value, and     zeroes out higher parts.  */ -void -APInt::tcSet(integerPart *dst, integerPart part, unsigned int parts) -{ -  unsigned int i; - +void APInt::tcSet(WordType *dst, WordType part, unsigned parts) {    assert(parts > 0);    dst[0] = part; -  for (i = 1; i < parts; i++) +  for (unsigned i = 1; i < parts; i++)      dst[i] = 0;  }  /* Assign one bignum to another.  */ -void -APInt::tcAssign(integerPart *dst, const integerPart *src, unsigned int parts) -{ -  unsigned int i; - -  for (i = 0; i < parts; i++) +void APInt::tcAssign(WordType *dst, const WordType *src, unsigned parts) { +  for (unsigned i = 0; i < parts; i++)      dst[i] = src[i];  }  /* Returns true if a bignum is zero, false otherwise.  */ -bool -APInt::tcIsZero(const integerPart *src, unsigned int parts) -{ -  unsigned int i; - -  for (i = 0; i < parts; i++) +bool APInt::tcIsZero(const WordType *src, unsigned parts) { +  for (unsigned i = 0; i < parts; i++)      if (src[i])        return false; @@ -2349,41 +2349,29 @@ APInt::tcIsZero(const integerPart *src, unsigned int parts)  }  /* Extract the given bit of a bignum; returns 0 or 1.  */ -int -APInt::tcExtractBit(const integerPart *parts, unsigned int bit) -{ -  return (parts[bit / integerPartWidth] & -          ((integerPart) 1 << bit % integerPartWidth)) != 0; +int APInt::tcExtractBit(const WordType *parts, unsigned bit) { +  return (parts[whichWord(bit)] & maskBit(bit)) != 0;  }  /* Set the given bit of a bignum. */ -void -APInt::tcSetBit(integerPart *parts, unsigned int bit) -{ -  parts[bit / integerPartWidth] |= (integerPart) 1 << (bit % integerPartWidth); +void APInt::tcSetBit(WordType *parts, unsigned bit) { +  parts[whichWord(bit)] |= maskBit(bit);  }  /* Clears the given bit of a bignum. */ -void -APInt::tcClearBit(integerPart *parts, unsigned int bit) -{ -  parts[bit / integerPartWidth] &= -    ~((integerPart) 1 << (bit % integerPartWidth)); +void APInt::tcClearBit(WordType *parts, unsigned bit) { +  parts[whichWord(bit)] &= ~maskBit(bit);  }  /* Returns the bit number of the least significant set bit of a     number.  If the input number has no bits set -1U is returned.  */ -unsigned int -APInt::tcLSB(const integerPart *parts, unsigned int n) -{ -  unsigned int i, lsb; - -  for (i = 0; i < n; i++) { -      if (parts[i] != 0) { -          lsb = partLSB(parts[i]); +unsigned APInt::tcLSB(const WordType *parts, unsigned n) { +  for (unsigned i = 0; i < n; i++) { +    if (parts[i] != 0) { +      unsigned lsb = partLSB(parts[i]); -          return lsb + i * integerPartWidth; -      } +      return lsb + i * APINT_BITS_PER_WORD; +    }    }    return -1U; @@ -2391,18 +2379,14 @@ APInt::tcLSB(const integerPart *parts, unsigned int n)  /* Returns the bit number of the most significant set bit of a number.     If the input number has no bits set -1U is returned.  */ -unsigned int -APInt::tcMSB(const integerPart *parts, unsigned int n) -{ -  unsigned int msb; - +unsigned APInt::tcMSB(const WordType *parts, unsigned n) {    do {      --n;      if (parts[n] != 0) { -      msb = partMSB(parts[n]); +      unsigned msb = partMSB(parts[n]); -      return msb + n * integerPartWidth; +      return msb + n * APINT_BITS_PER_WORD;      }    } while (n); @@ -2414,31 +2398,28 @@ APInt::tcMSB(const integerPart *parts, unsigned int n)     the least significant bit of DST.  All high bits above srcBITS in     DST are zero-filled.  */  void -APInt::tcExtract(integerPart *dst, unsigned int dstCount,const integerPart *src, -                 unsigned int srcBits, unsigned int srcLSB) -{ -  unsigned int firstSrcPart, dstParts, shift, n; - -  dstParts = (srcBits + integerPartWidth - 1) / integerPartWidth; +APInt::tcExtract(WordType *dst, unsigned dstCount, const WordType *src, +                 unsigned srcBits, unsigned srcLSB) { +  unsigned dstParts = (srcBits + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;    assert(dstParts <= dstCount); -  firstSrcPart = srcLSB / integerPartWidth; +  unsigned firstSrcPart = srcLSB / APINT_BITS_PER_WORD;    tcAssign (dst, src + firstSrcPart, dstParts); -  shift = srcLSB % integerPartWidth; +  unsigned shift = srcLSB % APINT_BITS_PER_WORD;    tcShiftRight (dst, dstParts, shift); -  /* We now have (dstParts * integerPartWidth - shift) bits from SRC +  /* We now have (dstParts * APINT_BITS_PER_WORD - shift) bits from SRC       in DST.  If this is less that srcBits, append the rest, else       clear the high bits.  */ -  n = dstParts * integerPartWidth - shift; +  unsigned n = dstParts * APINT_BITS_PER_WORD - shift;    if (n < srcBits) { -    integerPart mask = lowBitMask (srcBits - n); +    WordType mask = lowBitMask (srcBits - n);      dst[dstParts - 1] |= ((src[firstSrcPart + dstParts] & mask) -                          << n % integerPartWidth); +                          << n % APINT_BITS_PER_WORD);    } else if (n > srcBits) { -    if (srcBits % integerPartWidth) -      dst[dstParts - 1] &= lowBitMask (srcBits % integerPartWidth); +    if (srcBits % APINT_BITS_PER_WORD) +      dst[dstParts - 1] &= lowBitMask (srcBits % APINT_BITS_PER_WORD);    }    /* Clear high parts.  */ @@ -2447,18 +2428,12 @@ APInt::tcExtract(integerPart *dst, unsigned int dstCount,const integerPart *src,  }  /* DST += RHS + C where C is zero or one.  Returns the carry flag.  */ -integerPart -APInt::tcAdd(integerPart *dst, const integerPart *rhs, -             integerPart c, unsigned int parts) -{ -  unsigned int i; - +APInt::WordType APInt::tcAdd(WordType *dst, const WordType *rhs, +                             WordType c, unsigned parts) {    assert(c <= 1); -  for (i = 0; i < parts; i++) { -    integerPart l; - -    l = dst[i]; +  for (unsigned i = 0; i < parts; i++) { +    WordType l = dst[i];      if (c) {        dst[i] += rhs[i] + 1;        c = (dst[i] <= l); @@ -2471,19 +2446,29 @@ APInt::tcAdd(integerPart *dst, const integerPart *rhs,    return c;  } -/* DST -= RHS + C where C is zero or one.  Returns the carry flag.  */ -integerPart -APInt::tcSubtract(integerPart *dst, const integerPart *rhs, -                  integerPart c, unsigned int parts) -{ -  unsigned int i; +/// This function adds a single "word" integer, src, to the multiple +/// "word" integer array, dst[]. dst[] is modified to reflect the addition and +/// 1 is returned if there is a carry out, otherwise 0 is returned. +/// @returns the carry of the addition. +APInt::WordType APInt::tcAddPart(WordType *dst, WordType src, +                                 unsigned parts) { +  for (unsigned i = 0; i < parts; ++i) { +    dst[i] += src; +    if (dst[i] >= src) +      return 0; // No need to carry so exit early. +    src = 1; // Carry one to next digit. +  } -  assert(c <= 1); +  return 1; +} -  for (i = 0; i < parts; i++) { -    integerPart l; +/* DST -= RHS + C where C is zero or one.  Returns the carry flag.  */ +APInt::WordType APInt::tcSubtract(WordType *dst, const WordType *rhs, +                                  WordType c, unsigned parts) { +  assert(c <= 1); -    l = dst[i]; +  for (unsigned i = 0; i < parts; i++) { +    WordType l = dst[i];      if (c) {        dst[i] -= rhs[i] + 1;        c = (dst[i] >= l); @@ -2496,10 +2481,28 @@ APInt::tcSubtract(integerPart *dst, const integerPart *rhs,    return c;  } +/// This function subtracts a single "word" (64-bit word), src, from +/// the multi-word integer array, dst[], propagating the borrowed 1 value until +/// no further borrowing is needed or it runs out of "words" in dst.  The result +/// is 1 if "borrowing" exhausted the digits in dst, or 0 if dst was not +/// exhausted. In other words, if src > dst then this function returns 1, +/// otherwise 0. +/// @returns the borrow out of the subtraction +APInt::WordType APInt::tcSubtractPart(WordType *dst, WordType src, +                                      unsigned parts) { +  for (unsigned i = 0; i < parts; ++i) { +    WordType Dst = dst[i]; +    dst[i] -= src; +    if (src <= Dst) +      return 0; // No need to borrow so exit early. +    src = 1; // We have to "borrow 1" from next "word" +  } + +  return 1; +} +  /* Negate a bignum in-place.  */ -void -APInt::tcNegate(integerPart *dst, unsigned int parts) -{ +void APInt::tcNegate(WordType *dst, unsigned parts) {    tcComplement(dst, parts);    tcIncrement(dst, parts);  } @@ -2515,23 +2518,20 @@ APInt::tcNegate(integerPart *dst, unsigned int parts)      DSTPARTS parts of the result, and if all of the omitted higher      parts were zero return zero, otherwise overflow occurred and      return one.  */ -int -APInt::tcMultiplyPart(integerPart *dst, const integerPart *src, -                      integerPart multiplier, integerPart carry, -                      unsigned int srcParts, unsigned int dstParts, -                      bool add) -{ -  unsigned int i, n; - +int APInt::tcMultiplyPart(WordType *dst, const WordType *src, +                          WordType multiplier, WordType carry, +                          unsigned srcParts, unsigned dstParts, +                          bool add) {    /* Otherwise our writes of DST kill our later reads of SRC.  */    assert(dst <= src || dst >= src + srcParts);    assert(dstParts <= srcParts + 1);    /* N loops; minimum of dstParts and srcParts.  */ -  n = dstParts < srcParts ? dstParts: srcParts; +  unsigned n = dstParts < srcParts ? dstParts: srcParts; +  unsigned i;    for (i = 0; i < n; i++) { -    integerPart low, mid, high, srcPart; +    WordType low, mid, high, srcPart;        /* [ LOW, HIGH ] = MULTIPLIER * SRC[i] + DST[i] + CARRY. @@ -2543,7 +2543,7 @@ APInt::tcMultiplyPart(integerPart *dst, const integerPart *src,      srcPart = src[i]; -    if (multiplier == 0 || srcPart == 0)        { +    if (multiplier == 0 || srcPart == 0) {        low = carry;        high = 0;      } else { @@ -2552,14 +2552,14 @@ APInt::tcMultiplyPart(integerPart *dst, const integerPart *src,        mid = lowHalf(srcPart) * highHalf(multiplier);        high += highHalf(mid); -      mid <<= integerPartWidth / 2; +      mid <<= APINT_BITS_PER_WORD / 2;        if (low + mid < low)          high++;        low += mid;        mid = highHalf(srcPart) * lowHalf(multiplier);        high += highHalf(mid); -      mid <<= integerPartWidth / 2; +      mid <<= APINT_BITS_PER_WORD / 2;        if (low + mid < low)          high++;        low += mid; @@ -2608,19 +2608,14 @@ APInt::tcMultiplyPart(integerPart *dst, const integerPart *src,     is filled with the least significant parts of the result.  Returns     one if overflow occurred, otherwise zero.  DST must be disjoint     from both operands.  */ -int -APInt::tcMultiply(integerPart *dst, const integerPart *lhs, -                  const integerPart *rhs, unsigned int parts) -{ -  unsigned int i; -  int overflow; - +int APInt::tcMultiply(WordType *dst, const WordType *lhs, +                      const WordType *rhs, unsigned parts) {    assert(dst != lhs && dst != rhs); -  overflow = 0; +  int overflow = 0;    tcSet(dst, 0, parts); -  for (i = 0; i < parts; i++) +  for (unsigned i = 0; i < parts; i++)      overflow |= tcMultiplyPart(&dst[i], lhs, rhs[i], 0, parts,                                 parts - i, true); @@ -2631,25 +2626,21 @@ APInt::tcMultiply(integerPart *dst, const integerPart *lhs,     operands.  No overflow occurs.  DST must be disjoint from both     operands.  Returns the number of parts required to hold the     result.  */ -unsigned int -APInt::tcFullMultiply(integerPart *dst, const integerPart *lhs, -                      const integerPart *rhs, unsigned int lhsParts, -                      unsigned int rhsParts) -{ +unsigned APInt::tcFullMultiply(WordType *dst, const WordType *lhs, +                               const WordType *rhs, unsigned lhsParts, +                               unsigned rhsParts) {    /* Put the narrower number on the LHS for less loops below.  */    if (lhsParts > rhsParts) {      return tcFullMultiply (dst, rhs, lhs, rhsParts, lhsParts);    } else { -    unsigned int n; -      assert(dst != lhs && dst != rhs);      tcSet(dst, 0, rhsParts); -    for (n = 0; n < lhsParts; n++) -      tcMultiplyPart(&dst[n], rhs, lhs[n], 0, rhsParts, rhsParts + 1, true); +    for (unsigned i = 0; i < lhsParts; i++) +      tcMultiplyPart(&dst[i], rhs, lhs[i], 0, rhsParts, rhsParts + 1, true); -    n = lhsParts + rhsParts; +    unsigned n = lhsParts + rhsParts;      return n - (dst[n - 1] == 0);    } @@ -2665,23 +2656,18 @@ APInt::tcFullMultiply(integerPart *dst, const integerPart *lhs,     use by the routine; its contents need not be initialized and are     destroyed.  LHS, REMAINDER and SCRATCH must be distinct.  */ -int -APInt::tcDivide(integerPart *lhs, const integerPart *rhs, -                integerPart *remainder, integerPart *srhs, -                unsigned int parts) -{ -  unsigned int n, shiftCount; -  integerPart mask; - +int APInt::tcDivide(WordType *lhs, const WordType *rhs, +                    WordType *remainder, WordType *srhs, +                    unsigned parts) {    assert(lhs != remainder && lhs != srhs && remainder != srhs); -  shiftCount = tcMSB(rhs, parts) + 1; +  unsigned shiftCount = tcMSB(rhs, parts) + 1;    if (shiftCount == 0)      return true; -  shiftCount = parts * integerPartWidth - shiftCount; -  n = shiftCount / integerPartWidth; -  mask = (integerPart) 1 << (shiftCount % integerPartWidth); +  shiftCount = parts * APINT_BITS_PER_WORD - shiftCount; +  unsigned n = shiftCount / APINT_BITS_PER_WORD; +  WordType mask = (WordType) 1 << (shiftCount % APINT_BITS_PER_WORD);    tcAssign(srhs, rhs, parts);    tcShiftLeft(srhs, parts, shiftCount); @@ -2704,7 +2690,7 @@ APInt::tcDivide(integerPart *lhs, const integerPart *rhs,        shiftCount--;        tcShiftRight(srhs, parts, 1);        if ((mask >>= 1) == 0) { -        mask = (integerPart) 1 << (integerPartWidth - 1); +        mask = (WordType) 1 << (APINT_BITS_PER_WORD - 1);          n--;        }    } @@ -2714,18 +2700,14 @@ APInt::tcDivide(integerPart *lhs, const integerPart *rhs,  /* Shift a bignum left COUNT bits in-place.  Shifted in bits are zero.     There are no restrictions on COUNT.  */ -void -APInt::tcShiftLeft(integerPart *dst, unsigned int parts, unsigned int count) -{ +void APInt::tcShiftLeft(WordType *dst, unsigned parts, unsigned count) {    if (count) { -    unsigned int jump, shift; -      /* Jump is the inter-part jump; shift is is intra-part shift.  */ -    jump = count / integerPartWidth; -    shift = count % integerPartWidth; +    unsigned jump = count / APINT_BITS_PER_WORD; +    unsigned shift = count % APINT_BITS_PER_WORD;      while (parts > jump) { -      integerPart part; +      WordType part;        parts--; @@ -2735,7 +2717,7 @@ APInt::tcShiftLeft(integerPart *dst, unsigned int parts, unsigned int count)        if (shift) {          part <<= shift;          if (parts >= jump + 1) -          part |= dst[parts - jump - 1] >> (integerPartWidth - shift); +          part |= dst[parts - jump - 1] >> (APINT_BITS_PER_WORD - shift);        }        dst[parts] = part; @@ -2748,20 +2730,16 @@ APInt::tcShiftLeft(integerPart *dst, unsigned int parts, unsigned int count)  /* Shift a bignum right COUNT bits in-place.  Shifted in bits are     zero.  There are no restrictions on COUNT.  */ -void -APInt::tcShiftRight(integerPart *dst, unsigned int parts, unsigned int count) -{ +void APInt::tcShiftRight(WordType *dst, unsigned parts, unsigned count) {    if (count) { -    unsigned int i, jump, shift; -      /* Jump is the inter-part jump; shift is is intra-part shift.  */ -    jump = count / integerPartWidth; -    shift = count % integerPartWidth; +    unsigned jump = count / APINT_BITS_PER_WORD; +    unsigned shift = count % APINT_BITS_PER_WORD;      /* Perform the shift.  This leaves the most significant COUNT bits         of the result at zero.  */ -    for (i = 0; i < parts; i++) { -      integerPart part; +    for (unsigned i = 0; i < parts; i++) { +      WordType part;        if (i + jump >= parts) {          part = 0; @@ -2770,7 +2748,7 @@ APInt::tcShiftRight(integerPart *dst, unsigned int parts, unsigned int count)          if (shift) {            part >>= shift;            if (i + jump + 1 < parts) -            part |= dst[i + jump + 1] << (integerPartWidth - shift); +            part |= dst[i + jump + 1] << (APINT_BITS_PER_WORD - shift);          }        } @@ -2780,107 +2758,55 @@ APInt::tcShiftRight(integerPart *dst, unsigned int parts, unsigned int count)  }  /* Bitwise and of two bignums.  */ -void -APInt::tcAnd(integerPart *dst, const integerPart *rhs, unsigned int parts) -{ -  unsigned int i; - -  for (i = 0; i < parts; i++) +void APInt::tcAnd(WordType *dst, const WordType *rhs, unsigned parts) { +  for (unsigned i = 0; i < parts; i++)      dst[i] &= rhs[i];  }  /* Bitwise inclusive or of two bignums.  */ -void -APInt::tcOr(integerPart *dst, const integerPart *rhs, unsigned int parts) -{ -  unsigned int i; - -  for (i = 0; i < parts; i++) +void APInt::tcOr(WordType *dst, const WordType *rhs, unsigned parts) { +  for (unsigned i = 0; i < parts; i++)      dst[i] |= rhs[i];  }  /* Bitwise exclusive or of two bignums.  */ -void -APInt::tcXor(integerPart *dst, const integerPart *rhs, unsigned int parts) -{ -  unsigned int i; - -  for (i = 0; i < parts; i++) +void APInt::tcXor(WordType *dst, const WordType *rhs, unsigned parts) { +  for (unsigned i = 0; i < parts; i++)      dst[i] ^= rhs[i];  }  /* Complement a bignum in-place.  */ -void -APInt::tcComplement(integerPart *dst, unsigned int parts) -{ -  unsigned int i; - -  for (i = 0; i < parts; i++) +void APInt::tcComplement(WordType *dst, unsigned parts) { +  for (unsigned i = 0; i < parts; i++)      dst[i] = ~dst[i];  }  /* Comparison (unsigned) of two bignums.  */ -int -APInt::tcCompare(const integerPart *lhs, const integerPart *rhs, -                 unsigned int parts) -{ +int APInt::tcCompare(const WordType *lhs, const WordType *rhs, +                     unsigned parts) {    while (parts) { -      parts--; -      if (lhs[parts] == rhs[parts]) -        continue; +    parts--; +    if (lhs[parts] == rhs[parts]) +      continue; -      if (lhs[parts] > rhs[parts]) -        return 1; -      else -        return -1; -    } +    return (lhs[parts] > rhs[parts]) ? 1 : -1; +  }    return 0;  } -/* Increment a bignum in-place, return the carry flag.  */ -integerPart -APInt::tcIncrement(integerPart *dst, unsigned int parts) -{ -  unsigned int i; - -  for (i = 0; i < parts; i++) -    if (++dst[i] != 0) -      break; - -  return i == parts; -} - -/* Decrement a bignum in-place, return the borrow flag.  */ -integerPart -APInt::tcDecrement(integerPart *dst, unsigned int parts) { -  for (unsigned int i = 0; i < parts; i++) { -    // If the current word is non-zero, then the decrement has no effect on the -    // higher-order words of the integer and no borrow can occur. Exit early. -    if (dst[i]--) -      return 0; -  } -  // If every word was zero, then there is a borrow. -  return 1; -} - -  /* Set the least significant BITS bits of a bignum, clear the     rest.  */ -void -APInt::tcSetLeastSignificantBits(integerPart *dst, unsigned int parts, -                                 unsigned int bits) -{ -  unsigned int i; - -  i = 0; -  while (bits > integerPartWidth) { -    dst[i++] = ~(integerPart) 0; -    bits -= integerPartWidth; +void APInt::tcSetLeastSignificantBits(WordType *dst, unsigned parts, +                                      unsigned bits) { +  unsigned i = 0; +  while (bits > APINT_BITS_PER_WORD) { +    dst[i++] = ~(WordType) 0; +    bits -= APINT_BITS_PER_WORD;    }    if (bits) -    dst[i++] = ~(integerPart) 0 >> (integerPartWidth - bits); +    dst[i++] = ~(WordType) 0 >> (APINT_BITS_PER_WORD - bits);    while (i < parts)      dst[i++] = 0;  | 
