[llvm-commits] [llvm] r116452 - in /llvm/trunk: include/llvm/ADT/APInt.h lib/Support/APInt.cpp
Chris Lattner
sabre at nondot.org
Wed Oct 13 16:46:33 PDT 2010
Author: lattner
Date: Wed Oct 13 18:46:33 2010
New Revision: 116452
URL: http://llvm.org/viewvc/llvm-project?rev=116452&view=rev
Log:
add a few operations for signed operations that also
return an overflow flag.
Modified:
llvm/trunk/include/llvm/ADT/APInt.h
llvm/trunk/lib/Support/APInt.cpp
Modified: llvm/trunk/include/llvm/ADT/APInt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=116452&r1=116451&r2=116452&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APInt.h (original)
+++ llvm/trunk/include/llvm/ADT/APInt.h Wed Oct 13 18:46:33 2010
@@ -741,11 +741,11 @@
/// RHS are treated as unsigned quantities for purposes of this division.
/// @returns a new APInt value containing the division result
/// @brief Unsigned division operation.
- APInt udiv(const APInt& RHS) const;
+ APInt udiv(const APInt &RHS) const;
/// Signed divide this APInt by APInt RHS.
/// @brief Signed division function for APInt.
- APInt sdiv(const APInt& RHS) const {
+ APInt sdiv(const APInt &RHS) const {
if (isNegative())
if (RHS.isNegative())
return (-(*this)).udiv(-RHS);
@@ -763,11 +763,11 @@
/// which is *this.
/// @returns a new APInt value containing the remainder result
/// @brief Unsigned remainder operation.
- APInt urem(const APInt& RHS) const;
+ APInt urem(const APInt &RHS) const;
/// Signed remainder operation on APInt.
/// @brief Function for signed remainder operation.
- APInt srem(const APInt& RHS) const {
+ APInt srem(const APInt &RHS) const {
if (isNegative())
if (RHS.isNegative())
return -((-(*this)).urem(-RHS));
@@ -788,8 +788,7 @@
APInt &Quotient, APInt &Remainder);
static void sdivrem(const APInt &LHS, const APInt &RHS,
- APInt &Quotient, APInt &Remainder)
- {
+ APInt &Quotient, APInt &Remainder) {
if (LHS.isNegative()) {
if (RHS.isNegative())
APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
@@ -804,6 +803,16 @@
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
/// @brief Array-indexing support.
@@ -988,6 +997,9 @@
return sge(APInt(getBitWidth(), RHS));
}
+
+
+
/// This operation tests if there are any pairs of corresponding bits
/// between this APInt and RHS that are both set.
bool intersects(const APInt &RHS) const {
@@ -1029,7 +1041,7 @@
/// @name Bit Manipulation Operators
/// @{
/// @brief Set every bit to 1.
- APInt& set() {
+ APInt &set() {
if (isSingleWord()) {
VAL = -1ULL;
return clearUnusedBits();
@@ -1044,10 +1056,10 @@
/// Set the given bit to 1 whose position is given as "bitPosition".
/// @brief Set a given bit to 1.
- APInt& set(unsigned bitPosition);
+ APInt &set(unsigned bitPosition);
/// @brief Set every bit to 0.
- APInt& clear() {
+ APInt &clear() {
if (isSingleWord())
VAL = 0;
else
@@ -1057,10 +1069,10 @@
/// Set the given bit to 0 whose position is given as "bitPosition".
/// @brief Set a given bit to 0.
- APInt& clear(unsigned bitPosition);
+ APInt &clear(unsigned bitPosition);
/// @brief Toggle every bit to its opposite value.
- APInt& flip() {
+ APInt &flip() {
if (isSingleWord()) {
VAL ^= -1ULL;
return clearUnusedBits();
Modified: llvm/trunk/lib/Support/APInt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=116452&r1=116451&r2=116452&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APInt.cpp (original)
+++ llvm/trunk/lib/Support/APInt.cpp Wed Oct 13 18:46:33 2010
@@ -2046,6 +2046,52 @@
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) {
// Check our assumptions here
assert(!str.empty() && "Invalid string length");
More information about the llvm-commits
mailing list