[llvm-commits] CVS: llvm/lib/Support/APInt.cpp
Zhou Sheng
zhousheng00 at gmail.com
Mon Feb 5 22:05:09 PST 2007
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) {
More information about the llvm-commits
mailing list