[llvm-commits] CVS: llvm/lib/Support/APInt.cpp
Reid Spencer
reid at x10sys.com
Sun Feb 18 12:09:58 PST 2007
Changes in directory llvm/lib/Support:
APInt.cpp updated: 1.19 -> 1.20
---
Log message:
1. Use APINT_WORD_SIZE instead of sizeof(uint64_t)
2. Teach slt about signedness.
3. Teach roundToDouble to properly sign extend.
---
Diffs of the changes: (+59 -42)
APInt.cpp | 101 ++++++++++++++++++++++++++++++++++++--------------------------
1 files changed, 59 insertions(+), 42 deletions(-)
Index: llvm/lib/Support/APInt.cpp
diff -u llvm/lib/Support/APInt.cpp:1.19 llvm/lib/Support/APInt.cpp:1.20
--- llvm/lib/Support/APInt.cpp:1.19 Sun Feb 18 12:38:44 2007
+++ llvm/lib/Support/APInt.cpp Sun Feb 18 14:09:41 2007
@@ -59,12 +59,12 @@
// Calculate the actual length of bigVal[].
uint32_t maxN = std::max<uint32_t>(numWords, getNumWords());
uint32_t minN = std::min<uint32_t>(numWords, getNumWords());
- memcpy(pVal, bigVal, (minN - 1) * sizeof(uint64_t));
+ memcpy(pVal, bigVal, (minN - 1) * APINT_WORD_SIZE);
pVal[minN-1] = bigVal[minN-1] &
(~uint64_t(0ULL) >>
(APINT_BITS_PER_WORD - BitWidth % APINT_BITS_PER_WORD));
if (maxN == getNumWords())
- memset(pVal+numWords, 0, (getNumWords() - numWords) * sizeof(uint64_t));
+ memset(pVal+numWords, 0, (getNumWords() - numWords) * APINT_WORD_SIZE);
}
}
@@ -82,13 +82,14 @@
fromString(numbits, Val.c_str(), Val.size(), radix);
}
+/// @brief Copy constructor
APInt::APInt(const APInt& APIVal)
: BitWidth(APIVal.BitWidth) {
if (isSingleWord())
VAL = APIVal.VAL;
else {
pVal = getMemory(getNumWords());
- memcpy(pVal, APIVal.pVal, getNumWords() * sizeof(uint64_t));
+ memcpy(pVal, APIVal.pVal, getNumWords() * APINT_WORD_SIZE);
}
}
@@ -103,7 +104,7 @@
if (isSingleWord())
VAL = RHS.VAL;
else
- memcpy(pVal, RHS.pVal, getNumWords() * sizeof(uint64_t));
+ memcpy(pVal, RHS.pVal, getNumWords() * APINT_WORD_SIZE);
return *this;
}
@@ -114,7 +115,7 @@
VAL = RHS;
else {
pVal[0] = RHS;
- memset(pVal+1, 0, (getNumWords() - 1) * sizeof(uint64_t));
+ memset(pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
}
return *this;
}
@@ -339,13 +340,13 @@
first = RHS.getActiveBits();
uint32_t ylen = !first ? 0 : whichWord(first - 1) + 1;
if (!ylen) {
- memset(pVal, 0, getNumWords() * sizeof(uint64_t));
+ memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
return *this;
}
uint64_t *dest = getMemory(xlen+ylen);
mul(dest, pVal, xlen, RHS.pVal, ylen);
memcpy(pVal, dest, ((xlen + ylen >= getNumWords()) ?
- getNumWords() : xlen + ylen) * sizeof(uint64_t));
+ getNumWords() : xlen + ylen) * APINT_WORD_SIZE);
delete[] dest;
}
}
@@ -536,23 +537,35 @@
/// @brief Signed less than comparison
bool APInt::slt(const APInt& RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be same for comparison");
- if (isSingleWord())
- return VAL < RHS.VAL;
- else {
- uint32_t n1 = getActiveBits();
- uint32_t n2 = RHS.getActiveBits();
- if (n1 < n2)
+ if (isSingleWord()) {
+ int64_t lhsSext = (int64_t(VAL) << (64-BitWidth)) >> (64-BitWidth);
+ int64_t rhsSext = (int64_t(RHS.VAL) << (64-BitWidth)) >> (64-BitWidth);
+ return lhsSext < rhsSext;
+ }
+
+ APInt lhs(*this);
+ APInt rhs(*this);
+ bool lhsNegative = false;
+ bool rhsNegative = false;
+ if (lhs[BitWidth-1]) {
+ lhsNegative = true;
+ lhs.flip();
+ lhs++;
+ }
+ if (rhs[BitWidth-1]) {
+ rhsNegative = true;
+ rhs.flip();
+ rhs++;
+ }
+ if (lhsNegative)
+ if (rhsNegative)
+ return !lhs.ult(rhs);
+ else
return true;
- else if (n2 < n1)
- return false;
- else if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD)
- return pVal[0] < RHS.pVal[0];
- for (int i = whichWord(n1 - 1); i >= 0; --i) {
- if (pVal[i] > RHS.pVal[i]) return false;
- else if (pVal[i] < RHS.pVal[i]) return true;
- }
- }
- return false;
+ else if (rhsNegative)
+ return false;
+ else
+ return lhs.ult(rhs);
}
/// Set the given bit to 1 whose poition is given as "bitPosition".
@@ -591,7 +604,7 @@
if (isSingleWord())
VAL = 0;
else
- memset(pVal, 0, getNumWords() * sizeof(uint64_t));
+ memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
return *this;
}
@@ -801,10 +814,10 @@
else {
APInt Result(BitWidth, 0);
char *pByte = (char*)Result.pVal;
- for (uint32_t i = 0; i < BitWidth / sizeof(uint64_t) / 2; ++i) {
+ for (uint32_t i = 0; i < BitWidth / APINT_WORD_SIZE / 2; ++i) {
char Tmp = pByte[i];
- pByte[i] = pByte[BitWidth / sizeof(uint64_t) - 1 - i];
- pByte[BitWidth / sizeof(uint64_t) - i - 1] = Tmp;
+ pByte[i] = pByte[BitWidth / APINT_WORD_SIZE - 1 - i];
+ pByte[BitWidth / APINT_WORD_SIZE - i - 1] = Tmp;
}
return Result;
}
@@ -852,13 +865,17 @@
/// | 1[63] 11[62-52] 52[51-00] 1023 |
/// --------------------------------------
double APInt::roundToDouble(bool isSigned) const {
+ if (isSingleWord() || getActiveBits() <= APINT_BITS_PER_WORD) {
+ if (isSigned) {
+ int64_t sext = (int64_t(VAL) << (64-BitWidth)) >> (64-BitWidth);
+ return double(sext);
+ } else
+ return double(VAL);
+ }
+
bool isNeg = isSigned ? (*this)[BitWidth-1] : false;
APInt Tmp(isNeg ? -(*this) : (*this));
- if (Tmp.isSingleWord())
- return isSigned ? double(int64_t(Tmp.VAL)) : double(Tmp.VAL);
uint32_t n = Tmp.getActiveBits();
- if (n <= APINT_BITS_PER_WORD)
- return isSigned ? double(int64_t(Tmp.pVal[0])) : double(Tmp.pVal[0]);
// Exponent when normalized to have decimal point directly after
// leading one. This is stored excess 1023 in the exponent bit field.
uint64_t exp = n - 1;
@@ -914,7 +931,7 @@
else {
if (shiftAmt >= API.BitWidth) {
memset(API.pVal, API[API.BitWidth-1] ? 1 : 0,
- (API.getNumWords()-1) * sizeof(uint64_t));
+ (API.getNumWords()-1) * APINT_WORD_SIZE);
API.pVal[API.getNumWords() - 1] =
~uint64_t(0UL) >>
(APINT_BITS_PER_WORD - API.BitWidth % APINT_BITS_PER_WORD);
@@ -942,7 +959,7 @@
API.VAL >>= shiftAmt;
else {
if (shiftAmt >= API.BitWidth)
- memset(API.pVal, 0, API.getNumWords() * sizeof(uint64_t));
+ memset(API.pVal, 0, API.getNumWords() * APINT_WORD_SIZE);
uint32_t i = 0;
for (i = 0; i < API.BitWidth - shiftAmt; ++i)
if (API[i+shiftAmt]) API.set(i);
@@ -960,12 +977,12 @@
if (API.isSingleWord())
API.VAL <<= shiftAmt;
else if (shiftAmt >= API.BitWidth)
- memset(API.pVal, 0, API.getNumWords() * sizeof(uint64_t));
+ memset(API.pVal, 0, API.getNumWords() * APINT_WORD_SIZE);
else {
if (uint32_t offset = shiftAmt / APINT_BITS_PER_WORD) {
for (uint32_t i = API.getNumWords() - 1; i > offset - 1; --i)
API.pVal[i] = API.pVal[i-offset];
- memset(API.pVal, 0, offset * sizeof(uint64_t));
+ memset(API.pVal, 0, offset * APINT_WORD_SIZE);
}
shiftAmt %= APINT_BITS_PER_WORD;
uint32_t i;
@@ -1094,10 +1111,10 @@
return Result; // 0 / X == 0
else if (lhsWords < rhsWords || Result.ult(RHS))
// X / Y with X < Y == 0
- memset(Result.pVal, 0, Result.getNumWords() * sizeof(uint64_t));
+ memset(Result.pVal, 0, Result.getNumWords() * APINT_WORD_SIZE);
else if (Result == RHS) {
// X / X == 1
- memset(Result.pVal, 0, Result.getNumWords() * sizeof(uint64_t));
+ memset(Result.pVal, 0, Result.getNumWords() * APINT_WORD_SIZE);
Result.pVal[0] = 1;
} else if (lhsWords == 1)
// All high words are zero, just use native divide
@@ -1115,9 +1132,9 @@
}
div((uint32_t*)X.pVal, lhsWords * 2 - 1,
(uint32_t*)(Y.isSingleWord()? &Y.VAL : Y.pVal), rhsWords*2);
- memset(Result.pVal, 0, Result.getNumWords() * sizeof(uint64_t));
+ memset(Result.pVal, 0, Result.getNumWords() * APINT_WORD_SIZE);
memcpy(Result.pVal, X.pVal + rhsWords,
- (lhsWords - rhsWords) * sizeof(uint64_t));
+ (lhsWords - rhsWords) * APINT_WORD_SIZE);
}
return Result;
}
@@ -1146,13 +1163,13 @@
// Check the degenerate cases
if (lhsWords == 0)
// 0 % Y == 0
- memset(Result.pVal, 0, Result.getNumWords() * sizeof(uint64_t));
+ memset(Result.pVal, 0, Result.getNumWords() * APINT_WORD_SIZE);
else if (lhsWords < rhsWords || Result.ult(RHS))
// X % Y == X iff X < Y
return Result;
else if (Result == RHS)
// X % X == 0;
- memset(Result.pVal, 0, Result.getNumWords() * sizeof(uint64_t));
+ memset(Result.pVal, 0, Result.getNumWords() * APINT_WORD_SIZE);
else if (lhsWords == 1)
// All high words are zero, just use native remainder
Result.pVal[0] %= RHS.pVal[0];
@@ -1168,7 +1185,7 @@
}
div((uint32_t*)X.pVal, rhsWords*2-1,
(uint32_t*)(Y.isSingleWord()? &Y.VAL : Y.pVal), rhsWords*2);
- memset(Result.pVal, 0, Result.getNumWords() * sizeof(uint64_t));
+ memset(Result.pVal, 0, Result.getNumWords() * APINT_WORD_SIZE);
for (uint32_t i = 0; i < rhsWords-1; ++i)
Result.pVal[i] = (X.pVal[i] >> nshift) |
(X.pVal[i+1] << (APINT_BITS_PER_WORD - nshift));
More information about the llvm-commits
mailing list