mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-17 06:33:21 +00:00
Fix the > 64 bits case for left shift.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34564 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
99c49a4b94
commit
8755380fff
@ -946,34 +946,59 @@ APInt APInt::lshr(uint32_t shiftAmt) const {
|
|||||||
/// @brief Left-shift function.
|
/// @brief Left-shift function.
|
||||||
APInt APInt::shl(uint32_t shiftAmt) const {
|
APInt APInt::shl(uint32_t shiftAmt) const {
|
||||||
assert(shiftAmt <= BitWidth && "Invalid shift amount");
|
assert(shiftAmt <= BitWidth && "Invalid shift amount");
|
||||||
APInt API(*this);
|
if (isSingleWord()) {
|
||||||
if (API.isSingleWord()) {
|
|
||||||
if (shiftAmt == BitWidth)
|
if (shiftAmt == BitWidth)
|
||||||
API.VAL = 0;
|
return APInt(BitWidth, 0); // avoid undefined shift results
|
||||||
else
|
return APInt(BitWidth, (VAL << shiftAmt) &
|
||||||
API.VAL <<= shiftAmt;
|
(~uint64_t(0ULL) >>
|
||||||
API.clearUnusedBits();
|
(APINT_BITS_PER_WORD - BitWidth)));
|
||||||
return API;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shiftAmt == BitWidth) {
|
// If all the bits were shifted out, the result is 0. This avoids issues
|
||||||
memset(API.pVal, 0, getNumWords() * APINT_WORD_SIZE);
|
// with shifting by the size of the integer type, which produces undefined
|
||||||
return API;
|
// results. We define these "undefined results" to always be 0.
|
||||||
|
if (shiftAmt == BitWidth)
|
||||||
|
return APInt(BitWidth, 0);
|
||||||
|
|
||||||
|
// Create some space for the result.
|
||||||
|
uint64_t * val = new uint64_t[getNumWords()];
|
||||||
|
|
||||||
|
// If we are shifting less than a word, do it the easy way
|
||||||
|
if (shiftAmt < APINT_BITS_PER_WORD) {
|
||||||
|
uint64_t carry = 0;
|
||||||
|
shiftAmt %= APINT_BITS_PER_WORD;
|
||||||
|
for (uint32_t i = 0; i < getNumWords(); i++) {
|
||||||
|
val[i] = pVal[i] << shiftAmt | carry;
|
||||||
|
carry = pVal[i] >> (APINT_BITS_PER_WORD - shiftAmt);
|
||||||
|
}
|
||||||
|
val[getNumWords()-1] &= ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitWidth);
|
||||||
|
return APInt(val, BitWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uint32_t offset = shiftAmt / APINT_BITS_PER_WORD) {
|
// Compute some values needed by the remaining shift algorithms
|
||||||
for (uint32_t i = API.getNumWords() - 1; i > offset - 1; --i)
|
uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD;
|
||||||
API.pVal[i] = API.pVal[i-offset];
|
uint32_t offset = shiftAmt / APINT_BITS_PER_WORD;
|
||||||
memset(API.pVal, 0, offset * APINT_WORD_SIZE);
|
|
||||||
|
// If we are shifting whole words, just move whole words
|
||||||
|
if (wordShift == 0) {
|
||||||
|
for (uint32_t i = 0; i < offset; i++)
|
||||||
|
val[i] = 0;
|
||||||
|
for (uint32_t i = offset; i < getNumWords(); i++)
|
||||||
|
val[i] = pVal[i-offset];
|
||||||
|
val[getNumWords()-1] &= ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitWidth);
|
||||||
|
return APInt(val,BitWidth);
|
||||||
}
|
}
|
||||||
shiftAmt %= APINT_BITS_PER_WORD;
|
|
||||||
uint32_t i;
|
// Copy whole words from this to Result.
|
||||||
for (i = API.getNumWords() - 1; i > 0; --i)
|
uint32_t i = getNumWords() - 1;
|
||||||
API.pVal[i] = (API.pVal[i] << shiftAmt) |
|
for (; i > offset; --i)
|
||||||
(API.pVal[i-1] >> (APINT_BITS_PER_WORD - shiftAmt));
|
val[i] = pVal[i-offset] << wordShift |
|
||||||
API.pVal[i] <<= shiftAmt;
|
pVal[i-offset-1] >> (APINT_BITS_PER_WORD - wordShift);
|
||||||
API.clearUnusedBits();
|
val[offset] = pVal[offset-1] << wordShift;
|
||||||
return API;
|
for (i = 0; i < offset; ++i)
|
||||||
|
val[i] = 0;
|
||||||
|
val[getNumWords()-1] &= ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitWidth);
|
||||||
|
return APInt(val, BitWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of Knuth's Algorithm D (Division of nonnegative integers)
|
/// Implementation of Knuth's Algorithm D (Division of nonnegative integers)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user