mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
Make long addition and subtraction work. Speed things up by using internal
functions more. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34458 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e811636f33
commit
54362ca095
@ -85,13 +85,13 @@ APInt::APInt(uint32_t numbits, const std::string& Val, uint8_t radix)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Copy constructor
|
/// @brief Copy constructor
|
||||||
APInt::APInt(const APInt& APIVal)
|
APInt::APInt(const APInt& that)
|
||||||
: BitWidth(APIVal.BitWidth), pVal(0) {
|
: BitWidth(that.BitWidth), pVal(0) {
|
||||||
if (isSingleWord())
|
if (isSingleWord())
|
||||||
VAL = APIVal.VAL;
|
VAL = that.VAL;
|
||||||
else {
|
else {
|
||||||
pVal = getMemory(getNumWords());
|
pVal = getMemory(getNumWords());
|
||||||
memcpy(pVal, APIVal.pVal, getNumWords() * APINT_WORD_SIZE);
|
memcpy(pVal, that.pVal, getNumWords() * APINT_WORD_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,11 +186,11 @@ APInt& APInt::operator--() {
|
|||||||
/// y[] and returns the carry.
|
/// y[] and returns the carry.
|
||||||
static uint64_t add(uint64_t dest[], uint64_t x[],
|
static uint64_t add(uint64_t dest[], uint64_t x[],
|
||||||
uint64_t y[], uint32_t len) {
|
uint64_t y[], uint32_t len) {
|
||||||
uint32_t carry = 0;
|
uint64_t carry = 0;
|
||||||
for (uint32_t i = 0; i< len; ++i) {
|
for (uint32_t i = 0; i< len; ++i) {
|
||||||
carry += x[i];
|
uint64_t save = x[i];
|
||||||
dest[i] = carry + y[i];
|
dest[i] = x[i] + y[i] + carry;
|
||||||
carry = carry < x[i] ? 1 : (dest[i] < carry ? 1 : 0);
|
carry = dest[i] < save ? 1 : 0;
|
||||||
}
|
}
|
||||||
return carry;
|
return carry;
|
||||||
}
|
}
|
||||||
@ -199,18 +199,10 @@ static uint64_t add(uint64_t dest[], uint64_t x[],
|
|||||||
/// RHS and assigns the result to this APInt.
|
/// RHS and assigns the result to this APInt.
|
||||||
APInt& APInt::operator+=(const APInt& RHS) {
|
APInt& APInt::operator+=(const APInt& RHS) {
|
||||||
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
||||||
if (isSingleWord()) VAL += RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
|
if (isSingleWord())
|
||||||
|
VAL += RHS.VAL;
|
||||||
else {
|
else {
|
||||||
if (RHS.isSingleWord()) add_1(pVal, pVal, getNumWords(), RHS.VAL);
|
add(pVal, pVal, RHS.pVal, getNumWords());
|
||||||
else {
|
|
||||||
if (getNumWords() <= RHS.getNumWords())
|
|
||||||
add(pVal, pVal, RHS.pVal, getNumWords());
|
|
||||||
else {
|
|
||||||
uint64_t carry = add(pVal, pVal, RHS.pVal, RHS.getNumWords());
|
|
||||||
add_1(pVal + RHS.getNumWords(), pVal + RHS.getNumWords(),
|
|
||||||
getNumWords() - RHS.getNumWords(), carry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
clearUnusedBits();
|
clearUnusedBits();
|
||||||
return *this;
|
return *this;
|
||||||
@ -220,19 +212,13 @@ APInt& APInt::operator+=(const APInt& RHS) {
|
|||||||
/// integer array y[], and returns the borrow-out carry.
|
/// integer array y[], and returns the borrow-out carry.
|
||||||
static uint64_t sub(uint64_t dest[], uint64_t x[],
|
static uint64_t sub(uint64_t dest[], uint64_t x[],
|
||||||
uint64_t y[], uint32_t len) {
|
uint64_t y[], uint32_t len) {
|
||||||
// Carry indicator.
|
uint64_t borrow = 0;
|
||||||
uint64_t cy = 0;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < len; ++i) {
|
for (uint32_t i = 0; i < len; ++i) {
|
||||||
uint64_t Y = y[i], X = x[i];
|
uint64_t save = x[i];
|
||||||
Y += cy;
|
dest[i] = x[i] - borrow - y[i];
|
||||||
|
borrow = save < dest[i] ? 1 : 0;
|
||||||
cy = Y < cy ? 1 : 0;
|
|
||||||
Y = X - Y;
|
|
||||||
cy += Y > X ? 1 : 0;
|
|
||||||
dest[i] = Y;
|
|
||||||
}
|
}
|
||||||
return cy;
|
return borrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Subtraction assignment operator. Subtracts this APInt by the given
|
/// @brief Subtraction assignment operator. Subtracts this APInt by the given
|
||||||
@ -240,20 +226,9 @@ static uint64_t sub(uint64_t dest[], uint64_t x[],
|
|||||||
APInt& APInt::operator-=(const APInt& RHS) {
|
APInt& APInt::operator-=(const APInt& RHS) {
|
||||||
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
||||||
if (isSingleWord())
|
if (isSingleWord())
|
||||||
VAL -= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
|
VAL -= RHS.VAL;
|
||||||
else {
|
else
|
||||||
if (RHS.isSingleWord())
|
sub(pVal, pVal, RHS.pVal, getNumWords());
|
||||||
sub_1(pVal, getNumWords(), RHS.VAL);
|
|
||||||
else {
|
|
||||||
if (RHS.getNumWords() < getNumWords()) {
|
|
||||||
uint64_t carry = sub(pVal, pVal, RHS.pVal, RHS.getNumWords());
|
|
||||||
sub_1(pVal + RHS.getNumWords(), getNumWords() - RHS.getNumWords(),
|
|
||||||
carry);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sub(pVal, pVal, RHS.pVal, getNumWords());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clearUnusedBits();
|
clearUnusedBits();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -330,7 +305,7 @@ static void mul(uint64_t dest[], uint64_t x[], uint32_t xlen,
|
|||||||
/// given APInt& RHS and assigns the result to this APInt.
|
/// given APInt& RHS and assigns the result to this APInt.
|
||||||
APInt& APInt::operator*=(const APInt& RHS) {
|
APInt& APInt::operator*=(const APInt& RHS) {
|
||||||
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
||||||
if (isSingleWord())
|
if (isSingleWord())
|
||||||
VAL *= RHS.VAL;
|
VAL *= RHS.VAL;
|
||||||
else {
|
else {
|
||||||
// one-based first non-zero bit position.
|
// one-based first non-zero bit position.
|
||||||
@ -338,8 +313,6 @@ APInt& APInt::operator*=(const APInt& RHS) {
|
|||||||
uint32_t xlen = !first ? 0 : whichWord(first - 1) + 1;
|
uint32_t xlen = !first ? 0 : whichWord(first - 1) + 1;
|
||||||
if (!xlen)
|
if (!xlen)
|
||||||
return *this;
|
return *this;
|
||||||
else if (RHS.isSingleWord())
|
|
||||||
mul_1(pVal, pVal, xlen, RHS.VAL);
|
|
||||||
else {
|
else {
|
||||||
first = RHS.getActiveBits();
|
first = RHS.getActiveBits();
|
||||||
uint32_t ylen = !first ? 0 : whichWord(first - 1) + 1;
|
uint32_t ylen = !first ? 0 : whichWord(first - 1) + 1;
|
||||||
@ -392,11 +365,13 @@ APInt& APInt::operator^=(const APInt& RHS) {
|
|||||||
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
||||||
if (isSingleWord()) {
|
if (isSingleWord()) {
|
||||||
VAL ^= RHS.VAL;
|
VAL ^= RHS.VAL;
|
||||||
|
this->clearUnusedBits();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
uint32_t numWords = getNumWords();
|
uint32_t numWords = getNumWords();
|
||||||
for (uint32_t i = 0; i < numWords; ++i)
|
for (uint32_t i = 0; i < numWords; ++i)
|
||||||
pVal[i] ^= RHS.pVal[i];
|
pVal[i] ^= RHS.pVal[i];
|
||||||
|
this->clearUnusedBits();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,6 +395,7 @@ APInt APInt::operator|(const APInt& RHS) const {
|
|||||||
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
||||||
if (isSingleWord())
|
if (isSingleWord())
|
||||||
return APInt(getBitWidth(), VAL | RHS.VAL);
|
return APInt(getBitWidth(), VAL | RHS.VAL);
|
||||||
|
|
||||||
APInt Result(*this);
|
APInt Result(*this);
|
||||||
uint32_t numWords = getNumWords();
|
uint32_t numWords = getNumWords();
|
||||||
for (uint32_t i = 0; i < numWords; ++i)
|
for (uint32_t i = 0; i < numWords; ++i)
|
||||||
@ -431,8 +407,11 @@ APInt APInt::operator|(const APInt& RHS) const {
|
|||||||
/// and the given APInt& RHS.
|
/// and the given APInt& RHS.
|
||||||
APInt APInt::operator^(const APInt& RHS) const {
|
APInt APInt::operator^(const APInt& RHS) const {
|
||||||
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
||||||
if (isSingleWord())
|
if (isSingleWord()) {
|
||||||
return APInt(getBitWidth(), VAL ^ RHS.VAL);
|
APInt Result(BitWidth, VAL ^ RHS.VAL);
|
||||||
|
Result.clearUnusedBits();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
APInt Result(*this);
|
APInt Result(*this);
|
||||||
uint32_t numWords = getNumWords();
|
uint32_t numWords = getNumWords();
|
||||||
for (uint32_t i = 0; i < numWords; ++i)
|
for (uint32_t i = 0; i < numWords; ++i)
|
||||||
@ -456,6 +435,11 @@ bool APInt::operator !() const {
|
|||||||
/// RHS.
|
/// RHS.
|
||||||
APInt APInt::operator*(const APInt& RHS) const {
|
APInt APInt::operator*(const APInt& RHS) const {
|
||||||
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
||||||
|
if (isSingleWord()) {
|
||||||
|
APInt Result(BitWidth, VAL * RHS.VAL);
|
||||||
|
Result.clearUnusedBits();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
APInt Result(*this);
|
APInt Result(*this);
|
||||||
Result *= RHS;
|
Result *= RHS;
|
||||||
Result.clearUnusedBits();
|
Result.clearUnusedBits();
|
||||||
@ -465,18 +449,29 @@ APInt APInt::operator*(const APInt& RHS) const {
|
|||||||
/// @brief Addition operator. Adds this APInt by the given APInt& RHS.
|
/// @brief Addition operator. Adds this APInt by the given APInt& RHS.
|
||||||
APInt APInt::operator+(const APInt& RHS) const {
|
APInt APInt::operator+(const APInt& RHS) const {
|
||||||
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
||||||
APInt API(*this);
|
if (isSingleWord()) {
|
||||||
API += RHS;
|
APInt Result(BitWidth, VAL + RHS.VAL);
|
||||||
API.clearUnusedBits();
|
Result.clearUnusedBits();
|
||||||
return API;
|
return Result;
|
||||||
|
}
|
||||||
|
APInt Result(BitWidth, 0);
|
||||||
|
add(Result.pVal, this->pVal, RHS.pVal, getNumWords());
|
||||||
|
Result.clearUnusedBits();
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Subtraction operator. Subtracts this APInt by the given APInt& RHS
|
/// @brief Subtraction operator. Subtracts this APInt by the given APInt& RHS
|
||||||
APInt APInt::operator-(const APInt& RHS) const {
|
APInt APInt::operator-(const APInt& RHS) const {
|
||||||
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
|
||||||
APInt API(*this);
|
if (isSingleWord()) {
|
||||||
API -= RHS;
|
APInt Result(BitWidth, VAL - RHS.VAL);
|
||||||
return API;
|
Result.clearUnusedBits();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
APInt Result(BitWidth, 0);
|
||||||
|
sub(Result.pVal, this->pVal, RHS.pVal, getNumWords());
|
||||||
|
Result.clearUnusedBits();
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Array-indexing support.
|
/// @brief Array-indexing support.
|
||||||
@ -488,17 +483,20 @@ bool APInt::operator[](uint32_t bitPosition) const {
|
|||||||
/// @brief Equality operator. Compare this APInt with the given APInt& RHS
|
/// @brief Equality operator. Compare this APInt with the given APInt& RHS
|
||||||
/// for the validity of the equality relationship.
|
/// for the validity of the equality relationship.
|
||||||
bool APInt::operator==(const APInt& RHS) const {
|
bool APInt::operator==(const APInt& RHS) const {
|
||||||
|
if (isSingleWord())
|
||||||
|
return VAL == RHS.VAL;
|
||||||
|
|
||||||
uint32_t n1 = getActiveBits();
|
uint32_t n1 = getActiveBits();
|
||||||
uint32_t n2 = RHS.getActiveBits();
|
uint32_t n2 = RHS.getActiveBits();
|
||||||
if (n1 != n2) return false;
|
if (n1 != n2)
|
||||||
else if (isSingleWord())
|
return false;
|
||||||
return VAL == (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]);
|
|
||||||
else {
|
if (n1 <= APINT_BITS_PER_WORD)
|
||||||
if (n1 <= APINT_BITS_PER_WORD)
|
return pVal[0] == RHS.pVal[0];
|
||||||
return pVal[0] == (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]);
|
|
||||||
for (int i = whichWord(n1 - 1); i >= 0; --i)
|
for (int i = whichWord(n1 - 1); i >= 0; --i)
|
||||||
if (pVal[i] != RHS.pVal[i]) return false;
|
if (pVal[i] != RHS.pVal[i])
|
||||||
}
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,13 +505,12 @@ bool APInt::operator==(const APInt& RHS) const {
|
|||||||
bool APInt::operator==(uint64_t Val) const {
|
bool APInt::operator==(uint64_t Val) const {
|
||||||
if (isSingleWord())
|
if (isSingleWord())
|
||||||
return VAL == Val;
|
return VAL == Val;
|
||||||
else {
|
|
||||||
uint32_t n = getActiveBits();
|
uint32_t n = getActiveBits();
|
||||||
if (n <= APINT_BITS_PER_WORD)
|
if (n <= APINT_BITS_PER_WORD)
|
||||||
return pVal[0] == Val;
|
return pVal[0] == Val;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Unsigned less than comparison
|
/// @brief Unsigned less than comparison
|
||||||
|
Loading…
Reference in New Issue
Block a user