mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-02 07:32:52 +00:00
add a few operations for signed operations that also
return an overflow flag. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116452 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
95369599c6
commit
f2ddc64c87
@ -741,11 +741,11 @@ public:
|
|||||||
/// RHS are treated as unsigned quantities for purposes of this division.
|
/// RHS are treated as unsigned quantities for purposes of this division.
|
||||||
/// @returns a new APInt value containing the division result
|
/// @returns a new APInt value containing the division result
|
||||||
/// @brief Unsigned division operation.
|
/// @brief Unsigned division operation.
|
||||||
APInt udiv(const APInt& RHS) const;
|
APInt udiv(const APInt &RHS) const;
|
||||||
|
|
||||||
/// Signed divide this APInt by APInt RHS.
|
/// Signed divide this APInt by APInt RHS.
|
||||||
/// @brief Signed division function for APInt.
|
/// @brief Signed division function for APInt.
|
||||||
APInt sdiv(const APInt& RHS) const {
|
APInt sdiv(const APInt &RHS) const {
|
||||||
if (isNegative())
|
if (isNegative())
|
||||||
if (RHS.isNegative())
|
if (RHS.isNegative())
|
||||||
return (-(*this)).udiv(-RHS);
|
return (-(*this)).udiv(-RHS);
|
||||||
@ -763,11 +763,11 @@ public:
|
|||||||
/// which is *this.
|
/// which is *this.
|
||||||
/// @returns a new APInt value containing the remainder result
|
/// @returns a new APInt value containing the remainder result
|
||||||
/// @brief Unsigned remainder operation.
|
/// @brief Unsigned remainder operation.
|
||||||
APInt urem(const APInt& RHS) const;
|
APInt urem(const APInt &RHS) const;
|
||||||
|
|
||||||
/// Signed remainder operation on APInt.
|
/// Signed remainder operation on APInt.
|
||||||
/// @brief Function for signed remainder operation.
|
/// @brief Function for signed remainder operation.
|
||||||
APInt srem(const APInt& RHS) const {
|
APInt srem(const APInt &RHS) const {
|
||||||
if (isNegative())
|
if (isNegative())
|
||||||
if (RHS.isNegative())
|
if (RHS.isNegative())
|
||||||
return -((-(*this)).urem(-RHS));
|
return -((-(*this)).urem(-RHS));
|
||||||
@ -788,8 +788,7 @@ public:
|
|||||||
APInt &Quotient, APInt &Remainder);
|
APInt &Quotient, APInt &Remainder);
|
||||||
|
|
||||||
static void sdivrem(const APInt &LHS, const APInt &RHS,
|
static void sdivrem(const APInt &LHS, const APInt &RHS,
|
||||||
APInt &Quotient, APInt &Remainder)
|
APInt &Quotient, APInt &Remainder) {
|
||||||
{
|
|
||||||
if (LHS.isNegative()) {
|
if (LHS.isNegative()) {
|
||||||
if (RHS.isNegative())
|
if (RHS.isNegative())
|
||||||
APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
|
APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
|
||||||
@ -804,6 +803,16 @@ public:
|
|||||||
APInt::udivrem(LHS, RHS, Quotient, Remainder);
|
APInt::udivrem(LHS, RHS, Quotient, Remainder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Operations that return overflow indicators.
|
||||||
|
|
||||||
|
// ssub_ov - Signed subtraction. Unsigned subtraction never overflows.
|
||||||
|
APInt sadd_ov(const APInt &RHS, bool &Overflow);
|
||||||
|
APInt ssub_ov(const APInt &RHS, bool &Overflow);
|
||||||
|
APInt sdiv_ov(const APInt &RHS, bool &Overflow);
|
||||||
|
APInt smul_ov(const APInt &RHS, bool &Overflow);
|
||||||
|
APInt sshl_ov(unsigned Amt, bool &Overflow);
|
||||||
|
|
||||||
/// @returns the bit value at bitPosition
|
/// @returns the bit value at bitPosition
|
||||||
/// @brief Array-indexing support.
|
/// @brief Array-indexing support.
|
||||||
@ -988,6 +997,9 @@ public:
|
|||||||
return sge(APInt(getBitWidth(), RHS));
|
return sge(APInt(getBitWidth(), RHS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// This operation tests if there are any pairs of corresponding bits
|
/// This operation tests if there are any pairs of corresponding bits
|
||||||
/// between this APInt and RHS that are both set.
|
/// between this APInt and RHS that are both set.
|
||||||
bool intersects(const APInt &RHS) const {
|
bool intersects(const APInt &RHS) const {
|
||||||
@ -1029,7 +1041,7 @@ public:
|
|||||||
/// @name Bit Manipulation Operators
|
/// @name Bit Manipulation Operators
|
||||||
/// @{
|
/// @{
|
||||||
/// @brief Set every bit to 1.
|
/// @brief Set every bit to 1.
|
||||||
APInt& set() {
|
APInt &set() {
|
||||||
if (isSingleWord()) {
|
if (isSingleWord()) {
|
||||||
VAL = -1ULL;
|
VAL = -1ULL;
|
||||||
return clearUnusedBits();
|
return clearUnusedBits();
|
||||||
@ -1044,10 +1056,10 @@ public:
|
|||||||
|
|
||||||
/// Set the given bit to 1 whose position is given as "bitPosition".
|
/// Set the given bit to 1 whose position is given as "bitPosition".
|
||||||
/// @brief Set a given bit to 1.
|
/// @brief Set a given bit to 1.
|
||||||
APInt& set(unsigned bitPosition);
|
APInt &set(unsigned bitPosition);
|
||||||
|
|
||||||
/// @brief Set every bit to 0.
|
/// @brief Set every bit to 0.
|
||||||
APInt& clear() {
|
APInt &clear() {
|
||||||
if (isSingleWord())
|
if (isSingleWord())
|
||||||
VAL = 0;
|
VAL = 0;
|
||||||
else
|
else
|
||||||
@ -1057,10 +1069,10 @@ public:
|
|||||||
|
|
||||||
/// Set the given bit to 0 whose position is given as "bitPosition".
|
/// Set the given bit to 0 whose position is given as "bitPosition".
|
||||||
/// @brief Set a given bit to 0.
|
/// @brief Set a given bit to 0.
|
||||||
APInt& clear(unsigned bitPosition);
|
APInt &clear(unsigned bitPosition);
|
||||||
|
|
||||||
/// @brief Toggle every bit to its opposite value.
|
/// @brief Toggle every bit to its opposite value.
|
||||||
APInt& flip() {
|
APInt &flip() {
|
||||||
if (isSingleWord()) {
|
if (isSingleWord()) {
|
||||||
VAL ^= -1ULL;
|
VAL ^= -1ULL;
|
||||||
return clearUnusedBits();
|
return clearUnusedBits();
|
||||||
|
@ -2046,6 +2046,52 @@ void APInt::udivrem(const APInt &LHS, const APInt &RHS,
|
|||||||
divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder);
|
divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
APInt APInt::sadd_ov(const APInt &RHS, bool &Overflow) {
|
||||||
|
APInt Res = *this+RHS;
|
||||||
|
Overflow = isNonNegative() == RHS.isNonNegative() &&
|
||||||
|
Res.isNonNegative() != isNonNegative();
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
APInt APInt::ssub_ov(const APInt &RHS, bool &Overflow) {
|
||||||
|
APInt Res = *this - RHS;
|
||||||
|
Overflow = isNonNegative() != RHS.isNonNegative() &&
|
||||||
|
Res.isNonNegative() != isNonNegative();
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
APInt APInt::sdiv_ov(const APInt &RHS, bool &Overflow) {
|
||||||
|
// MININT/-1 --> overflow.
|
||||||
|
Overflow = isMinSignedValue() && RHS.isAllOnesValue();
|
||||||
|
return sdiv(RHS);
|
||||||
|
}
|
||||||
|
|
||||||
|
APInt APInt::smul_ov(const APInt &RHS, bool &Overflow) {
|
||||||
|
APInt Res = *this * RHS;
|
||||||
|
|
||||||
|
if (*this != 0 && RHS != 0)
|
||||||
|
Overflow = Res.sdiv(RHS) != *this || Res.sdiv(*this) != RHS;
|
||||||
|
else
|
||||||
|
Overflow = false;
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
APInt APInt::sshl_ov(unsigned ShAmt, bool &Overflow) {
|
||||||
|
Overflow = ShAmt >= getBitWidth();
|
||||||
|
if (Overflow)
|
||||||
|
ShAmt = getBitWidth()-1;
|
||||||
|
|
||||||
|
if (isNonNegative()) // Don't allow sign change.
|
||||||
|
Overflow = ShAmt >= countLeadingZeros();
|
||||||
|
else
|
||||||
|
Overflow = ShAmt >= countLeadingOnes();
|
||||||
|
|
||||||
|
return *this << ShAmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
|
void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
|
||||||
// Check our assumptions here
|
// Check our assumptions here
|
||||||
assert(!str.empty() && "Invalid string length");
|
assert(!str.empty() && "Invalid string length");
|
||||||
|
Loading…
Reference in New Issue
Block a user