Changes in directory llvm/lib/Support:
APInt.cpp updated: 1.2 -> 1.3 --- Log message: As Reid suggested, fixed some problems. --- Diffs of the changes: (+143 -150) APInt.cpp | 293 ++++++++++++++++++++++++++++++-------------------------------- 1 files changed, 143 insertions(+), 150 deletions(-) Index: llvm/lib/Support/APInt.cpp diff -u llvm/lib/Support/APInt.cpp:1.2 llvm/lib/Support/APInt.cpp:1.3 --- llvm/lib/Support/APInt.cpp:1.2 Mon Feb 5 23:38:37 2007 +++ llvm/lib/Support/APInt.cpp Tue Feb 6 00:04:53 2007 @@ -24,147 +24,10 @@ #include <cstdlib> using namespace llvm; -APInt::APInt(uint64_t val, unsigned numBits, bool sign) - : bitsnum(numBits), isSigned(sign) { - assert(bitsnum >= IntegerType::MIN_INT_BITS && "bitwidth too small"); - assert(bitsnum <= IntegerType::MAX_INT_BITS && "bitwidth too large"); - if (isSingleWord()) - VAL = val & (~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - bitsnum)); - else { - // Memory allocation and check if successful. - assert((pVal = new uint64_t[numWords()]) && - "APInt memory allocation fails!"); - bzero(pVal, numWords() * 8); - pVal[0] = val; - } -} - -APInt::APInt(unsigned numBits, uint64_t bigVal[], bool sign) - : bitsnum(numBits), isSigned(sign) { - assert(bitsnum >= IntegerType::MIN_INT_BITS && "bitwidth too small"); - assert(bitsnum <= 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)); - else { - // Memory allocation and check if successful. - assert((pVal = new uint64_t[numWords()]) && - "APInt memory allocation fails!"); - // Calculate the actual length of bigVal[]. - unsigned n = sizeof(*bigVal) / sizeof(bigVal[0]); - unsigned maxN = std::max<unsigned>(n, numWords()); - unsigned minN = std::min<unsigned>(n, numWords()); - memcpy(pVal, bigVal, (minN - 1) * 8); - pVal[minN-1] = bigVal[minN-1] & (~uint64_t(0ULL) >> (64 - bitsnum % 64)); - if (maxN == numWords()) - bzero(pVal+n, (numWords() - n) * 8); - } -} - -APInt::APInt(std::string& Val, uint8_t radix, bool sign) - : isSigned(sign) { - assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && - "Radix should be 2, 8, 10, or 16!"); - assert(!Val.empty() && "String empty?"); - unsigned slen = Val.size(); - 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; - if (numWords() > 1) - assert((pVal = new uint64_t[numWords()]) && - "APInt memory allocation fails!"); - for (int i = slen - 1; i >= 0; --i) { - uint64_t digit = Val[i] - 48; // '0' == 48. - resDigit |= digit << nextBitPos; - nextBitPos += bits_per_digit; - if (nextBitPos >= 64) { - if (isSingleWord()) { - VAL = resDigit; - break; - } - pVal[size++] = resDigit; - nextBitPos -= 64; - resDigit = digit >> (bits_per_digit - nextBitPos); - } - } - if (!isSingleWord() && size <= numWords()) - pVal[size] = resDigit; - } else { // General case. The radix is not a power of 2. - // For 10-radix, the max value of 64-bit integer is 18446744073709551615, - // and its digits number is 14. - const unsigned chars_per_word = 20; - if (slen < chars_per_word || - (Val <= "18446744073709551615" && - slen == chars_per_word)) { // In case Val <= 2^64 - 1 - bitsnum = 64; - VAL = strtoull(Val.c_str(), 0, 10); - } else { // In case Val > 2^64 - 1 - bitsnum = (slen / chars_per_word + 1) * 64; - assert((pVal = new uint64_t[numWords()]) && - "APInt memory allocation fails!"); - bzero(pVal, numWords() * 8); - unsigned str_pos = 0; - while (str_pos < slen) { - unsigned chunk = slen - str_pos; - if (chunk > chars_per_word - 1) - chunk = chars_per_word - 1; - uint64_t resDigit = Val[str_pos++] - 48; // 48 == '0'. - uint64_t big_base = radix; - while (--chunk > 0) { - resDigit = resDigit * radix + Val[str_pos++] - 48; - big_base *= radix; - } - - uint64_t carry; - if (!size) - carry = resDigit; - else { - carry = mul_1(pVal, pVal, size, big_base); - carry += add_1(pVal, pVal, size, resDigit); - } - - if (carry) pVal[size++] = carry; - } - } - } -} - -APInt::APInt(const APInt& APIVal) - : bitsnum(APIVal.bitsnum), isSigned(APIVal.isSigned) { - if (isSingleWord()) VAL = APIVal.VAL; - else { - // Memory allocation and check if successful. - assert((pVal = new uint64_t[numWords()]) && - "APInt memory allocation fails!"); - memcpy(pVal, APIVal.pVal, numWords() * 8); - } -} - -APInt::~APInt() { - if (!isSingleWord() && pVal) delete[] pVal; -} - -/// whichByte - This function returns the word position -/// for the specified bit position. -inline unsigned APInt::whichByte(unsigned bitPosition) -{ return (bitPosition % APINT_BITS_PER_WORD) / 8; } - -/// getWord - returns the corresponding word for the specified bit position. -inline uint64_t& APInt::getWord(unsigned bitPosition) -{ return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; } - -/// getWord - returns the corresponding word for the specified bit position. -/// This is a constant version. -inline uint64_t APInt::getWord(unsigned bitPosition) const -{ return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; } - -/// mul_1 - This function multiplies the integer array x[] by a integer y and -/// returns the carry. -uint64_t APInt::mul_1(uint64_t dest[], uint64_t x[], +/// mul_1 - This function performs the multiplication operation on a +/// large integer (represented as an integer array) and a uint64_t integer. +/// @returns the carry of the multiplication. +static uint64_t mul_1(uint64_t dest[], uint64_t x[], unsigned len, uint64_t y) { // Split y into high 32-bit part and low 32-bit part. uint64_t ly = y & 0xffffffffULL, hy = y >> 32; @@ -197,7 +60,7 @@ /// mul - This function multiplies integer array x[] by integer array y[] and /// stores the result into integer array dest[]. /// Note the array dest[]'s size should no less than xlen + ylen. -void APInt::mul(uint64_t dest[], uint64_t x[], unsigned xlen, +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]); @@ -230,7 +93,8 @@ /// add_1 - This function adds the integer array x[] by integer y and /// returns the carry. -uint64_t APInt::add_1(uint64_t dest[], uint64_t x[], +/// @returns the carry of the addition. +static uint64_t add_1(uint64_t dest[], uint64_t x[], unsigned len, uint64_t y) { uint64_t carry = y; @@ -243,7 +107,7 @@ /// add - This function adds the integer array x[] by integer array /// y[] and returns the carry. -uint64_t APInt::add(uint64_t dest[], uint64_t x[], +static uint64_t add(uint64_t dest[], uint64_t x[], uint64_t y[], unsigned len) { unsigned carry = 0; @@ -257,7 +121,7 @@ /// sub_1 - This function subtracts the integer array x[] by /// integer y and returns the borrow-out carry. -uint64_t APInt::sub_1(uint64_t x[], unsigned len, uint64_t y) { +static uint64_t sub_1(uint64_t x[], unsigned len, uint64_t y) { uint64_t cy = y; for (unsigned i = 0; i < len; ++i) { @@ -276,7 +140,7 @@ /// sub - This function subtracts the integer array x[] by /// integer array y[], and returns the borrow-out carry. -uint64_t APInt::sub(uint64_t dest[], uint64_t x[], +static uint64_t sub(uint64_t dest[], uint64_t x[], uint64_t y[], unsigned len) { // Carry indicator. uint64_t cy = 0; @@ -296,7 +160,7 @@ /// UnitDiv - This function divides N by D, /// and returns (remainder << 32) | quotient. /// Assumes (N >> 32) < D. -uint64_t APInt::unitDiv(uint64_t N, unsigned D) { +static uint64_t unitDiv(uint64_t N, unsigned D) { uint64_t q, r; // q: quotient, r: remainder. uint64_t a1 = N >> 32; // a1: high 32-bit part of N. uint64_t a0 = N & 0xffffffffL; // a0: low 32-bit part of N @@ -320,7 +184,7 @@ /// subMul - This function substracts x[len-1:0] * y from /// dest[offset+len-1:offset], and returns the most significant /// word of the product, minus the borrow-out from the subtraction. -unsigned APInt::subMul(unsigned dest[], unsigned offset, +static unsigned subMul(unsigned dest[], unsigned offset, unsigned x[], unsigned len, unsigned y) { uint64_t yl = (uint64_t) y & 0xffffffffL; unsigned carry = 0; @@ -348,7 +212,7 @@ /// Our nx == Knuth's m+n. /// Could be re-implemented using gmp's mpn_divrem: /// zds[nx] = mpn_divrem (&zds[ny], 0, zds, nx, y, ny). -void APInt::div(unsigned zds[], unsigned nx, unsigned y[], unsigned ny) { +static void div(unsigned zds[], unsigned nx, unsigned y[], unsigned ny) { unsigned j = nx; do { // loop over digits of quotient // Knuth's j == our nx-j. @@ -386,7 +250,7 @@ /// store the len least significant words of the result in /// dest[d_offset:d_offset+len-1]. It returns the bits shifted out from /// the most significant digit. -uint64_t APInt::lshift(uint64_t dest[], unsigned d_offset, +static uint64_t lshift(uint64_t dest[], unsigned d_offset, uint64_t x[], unsigned len, unsigned shiftAmt) { unsigned count = 64 - shiftAmt; int i = len - 1; @@ -401,6 +265,135 @@ return retVal; } +APInt::APInt(uint64_t val, unsigned numBits, bool sign) + : bitsnum(numBits), isSigned(sign) { + assert(bitsnum >= IntegerType::MIN_INT_BITS && "bitwidth too small"); + assert(bitsnum <= IntegerType::MAX_INT_BITS && "bitwidth too large"); + if (isSingleWord()) + VAL = val & (~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - bitsnum)); + else { + // Memory allocation and check if successful. + assert((pVal = new uint64_t[numWords()]) && + "APInt memory allocation fails!"); + bzero(pVal, numWords() * 8); + pVal[0] = val; + } +} + +APInt::APInt(unsigned numBits, uint64_t bigVal[], bool sign) + : bitsnum(numBits), isSigned(sign) { + assert(bitsnum >= IntegerType::MIN_INT_BITS && "bitwidth too small"); + assert(bitsnum <= 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)); + else { + // Memory allocation and check if successful. + assert((pVal = new uint64_t[numWords()]) && + "APInt memory allocation fails!"); + // Calculate the actual length of bigVal[]. + unsigned n = sizeof(*bigVal) / sizeof(bigVal[0]); + unsigned maxN = std::max<unsigned>(n, numWords()); + unsigned minN = std::min<unsigned>(n, numWords()); + memcpy(pVal, bigVal, (minN - 1) * 8); + pVal[minN-1] = bigVal[minN-1] & (~uint64_t(0ULL) >> (64 - bitsnum % 64)); + if (maxN == numWords()) + bzero(pVal+n, (numWords() - n) * 8); + } +} + +APInt::APInt(std::string& Val, uint8_t radix, bool sign) + : isSigned(sign) { + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + assert(!Val.empty() && "String empty?"); + unsigned slen = Val.size(); + 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; + if (numWords() > 1) + assert((pVal = new uint64_t[numWords()]) && + "APInt memory allocation fails!"); + for (int i = slen - 1; i >= 0; --i) { + uint64_t digit = Val[i] - 48; // '0' == 48. + resDigit |= digit << nextBitPos; + nextBitPos += bits_per_digit; + if (nextBitPos >= 64) { + if (isSingleWord()) { + VAL = resDigit; + break; + } + pVal[size++] = resDigit; + nextBitPos -= 64; + resDigit = digit >> (bits_per_digit - nextBitPos); + } + } + if (!isSingleWord() && size <= numWords()) + pVal[size] = resDigit; + } else { // General case. The radix is not a power of 2. + // For 10-radix, the max value of 64-bit integer is 18446744073709551615, + // and its digits number is 14. + const unsigned chars_per_word = 20; + if (slen < chars_per_word || + (Val <= "18446744073709551615" && + slen == chars_per_word)) { // In case Val <= 2^64 - 1 + bitsnum = 64; + VAL = strtoull(Val.c_str(), 0, 10); + } else { // In case Val > 2^64 - 1 + bitsnum = (slen / chars_per_word + 1) * 64; + assert((pVal = new uint64_t[numWords()]) && + "APInt memory allocation fails!"); + bzero(pVal, numWords() * 8); + unsigned str_pos = 0; + while (str_pos < slen) { + unsigned chunk = slen - str_pos; + if (chunk > chars_per_word - 1) + chunk = chars_per_word - 1; + uint64_t resDigit = Val[str_pos++] - 48; // 48 == '0'. + uint64_t big_base = radix; + while (--chunk > 0) { + resDigit = resDigit * radix + Val[str_pos++] - 48; + big_base *= radix; + } + + uint64_t carry; + if (!size) + carry = resDigit; + else { + carry = mul_1(pVal, pVal, size, big_base); + carry += add_1(pVal, pVal, size, resDigit); + } + + if (carry) pVal[size++] = carry; + } + } + } +} + +APInt::APInt(const APInt& APIVal) + : bitsnum(APIVal.bitsnum), isSigned(APIVal.isSigned) { + if (isSingleWord()) VAL = APIVal.VAL; + else { + // Memory allocation and check if successful. + assert((pVal = new uint64_t[numWords()]) && + "APInt memory allocation fails!"); + memcpy(pVal, APIVal.pVal, numWords() * 8); + } +} + +APInt::~APInt() { + if (!isSingleWord() && pVal) delete[] pVal; +} + +/// whichByte - This function returns the word position +/// for the specified bit position. +inline unsigned APInt::whichByte(unsigned bitPosition) +{ return (bitPosition % APINT_BITS_PER_WORD) / 8; } + /// @brief Copy assignment operator. Create a new object from the given /// APInt one by initialization. APInt& APInt::operator=(const APInt& RHS) { _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits