add a few operations for signed operations that also
authorChris Lattner <sabre@nondot.org>
Wed, 13 Oct 2010 23:46:33 +0000 (23:46 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 13 Oct 2010 23:46:33 +0000 (23:46 +0000)
return an overflow flag.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116452 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/APInt.h
lib/Support/APInt.cpp

index 8004cb4b123bcf5a7d80b108d2d550dccf50857d..525b3ddc06969f98b2beefcc8e21b19685d94dca 100644 (file)
@@ -741,11 +741,11 @@ public:
   /// RHS are treated as unsigned quantities for purposes of this division.
   /// @returns a new APInt value containing the division result
   /// @brief Unsigned division operation.
   /// 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 APIntRHS) const;
+  APInt udiv(const APInt &RHS) const;
 
   /// Signed divide this APInt by APInt RHS.
   /// @brief Signed division function for APInt.
 
   /// Signed divide this APInt by APInt RHS.
   /// @brief Signed division function for APInt.
-  APInt sdiv(const APIntRHS) const {
+  APInt sdiv(const APInt &RHS) const {
     if (isNegative())
       if (RHS.isNegative())
         return (-(*this)).udiv(-RHS);
     if (isNegative())
       if (RHS.isNegative())
         return (-(*this)).udiv(-RHS);
@@ -763,11 +763,11 @@ public:
   /// which is *this.
   /// @returns a new APInt value containing the remainder result
   /// @brief Unsigned remainder operation.
   /// which is *this.
   /// @returns a new APInt value containing the remainder result
   /// @brief Unsigned remainder operation.
-  APInt urem(const APIntRHS) const;
+  APInt urem(const APInt &RHS) const;
 
   /// Signed remainder operation on APInt.
   /// @brief Function for signed remainder operation.
 
   /// Signed remainder operation on APInt.
   /// @brief Function for signed remainder operation.
-  APInt srem(const APIntRHS) const {
+  APInt srem(const APInt &RHS) const {
     if (isNegative())
       if (RHS.isNegative())
         return -((-(*this)).urem(-RHS));
     if (isNegative())
       if (RHS.isNegative())
         return -((-(*this)).urem(-RHS));
@@ -788,8 +788,7 @@ public:
                       APInt &Quotient, APInt &Remainder);
 
   static void sdivrem(const APInt &LHS, const APInt &RHS,
                       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);
     if (LHS.isNegative()) {
       if (RHS.isNegative())
         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
   /// @brief Array-indexing support.
 
   /// @returns the bit value at bitPosition
   /// @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
   /// between this APInt and RHS that are both set.
   bool intersects(const APInt &RHS) const {
   /// 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 @@ public:
   /// @name Bit Manipulation Operators
   /// @{
   /// @brief Set every bit to 1.
   /// @name Bit Manipulation Operators
   /// @{
   /// @brief Set every bit to 1.
-  APIntset() {
+  APInt &set() {
     if (isSingleWord()) {
       VAL = -1ULL;
       return clearUnusedBits();
     if (isSingleWord()) {
       VAL = -1ULL;
       return clearUnusedBits();
@@ -1044,10 +1056,10 @@ public:
 
   /// Set the given bit to 1 whose position is given as "bitPosition".
   /// @brief Set a given bit to 1.
 
   /// Set the given bit to 1 whose position is given as "bitPosition".
   /// @brief Set a given bit to 1.
-  APIntset(unsigned bitPosition);
+  APInt &set(unsigned bitPosition);
 
   /// @brief Set every bit to 0.
 
   /// @brief Set every bit to 0.
-  APIntclear() {
+  APInt &clear() {
     if (isSingleWord())
       VAL = 0;
     else
     if (isSingleWord())
       VAL = 0;
     else
@@ -1057,10 +1069,10 @@ public:
 
   /// Set the given bit to 0 whose position is given as "bitPosition".
   /// @brief Set a given bit to 0.
 
   /// Set the given bit to 0 whose position is given as "bitPosition".
   /// @brief Set a given bit to 0.
-  APIntclear(unsigned bitPosition);
+  APInt &clear(unsigned bitPosition);
 
   /// @brief Toggle every bit to its opposite value.
 
   /// @brief Toggle every bit to its opposite value.
-  APIntflip() {
+  APInt &flip() {
     if (isSingleWord()) {
       VAL ^= -1ULL;
       return clearUnusedBits();
     if (isSingleWord()) {
       VAL ^= -1ULL;
       return clearUnusedBits();
index 8a212a291f24d777750ed39eb1e46e3692829cff..51203f6091dc012b244cd9e8ae1b8f1bae540b2b 100644 (file)
@@ -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) {
   // Check our assumptions here
   assert(!str.empty() && "Invalid string length");
 void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
   // Check our assumptions here
   assert(!str.empty() && "Invalid string length");