As Chris and Reid suggested, remove "isSigned" field from APInt, instead,
authorZhou Sheng <zhousheng00@gmail.com>
Thu, 8 Feb 2007 14:35:19 +0000 (14:35 +0000)
committerZhou Sheng <zhousheng00@gmail.com>
Thu, 8 Feb 2007 14:35:19 +0000 (14:35 +0000)
add some signed/unsigned arithmetic operation functions into APInt.h to
handle the signed/unsigned issue. These functions will be defined inside a
namespace "APIntOps" which is inside llvm namespace.

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

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

index 62a33d5320a860dfffc2d1b5606977b89ad0d5e3..8709fb80e0822aec99d8aa4a69af18941d3d03d2 100644 (file)
 
 namespace llvm {
 
+/// Forward declaration.
+class APInt;
+namespace APIntOps {
+  bool isIntN(unsigned N, const APInt& APIVal);
+  APInt ByteSwap(const APInt& APIVal);
+  APInt LogBase2(const APInt& APIVal);
+  APInt ashr(const APInt& LHS, unsigned shiftAmt);
+  APInt lshr(const APInt& LHS, unsigned shiftAmt);
+  APInt shl(const APInt& LHS, unsigned shiftAmt);
+  APInt sdiv(const APInt& LHS, const APInt& RHS);
+  APInt udiv(const APInt& LHS, const APInt& RHS);
+  APInt srem(const APInt& LHS, const APInt& RHS);
+  APInt urem(const APInt& LHS, const APInt& RHS);
+}
+
 //===----------------------------------------------------------------------===//
 //                              APInt Class
 //===----------------------------------------------------------------------===//
@@ -40,14 +55,18 @@ namespace llvm {
 class APInt {
   /// Friend Functions of APInt declared here. For detailed comments,
   /// see bottom of this file.
-  friend bool isIntN(unsigned N, const APInt& APIVal);
-  friend APInt ByteSwap(const APInt& APIVal);
-  friend APInt LogBase2(const APInt& APIVal);
-  friend double APIntToDouble(const APInt& APIVal);
-  friend float APIntToFloat(const APInt& APIVal);
+  friend bool APIntOps::isIntN(unsigned N, const APInt& APIVal);
+  friend APInt APIntOps::ByteSwap(const APInt& APIVal);
+  friend APInt APIntOps::LogBase2(const APInt& APIVal);
+  friend APInt APIntOps::ashr(const APInt& LHS, unsigned shiftAmt);
+  friend APInt APIntOps::lshr(const APInt& LHS, unsigned shiftAmt);
+  friend APInt APIntOps::shl(const APInt& LHS, unsigned shiftAmt);
+  friend APInt APIntOps::sdiv(const APInt& LHS, const APInt& RHS);
+  friend APInt APIntOps::udiv(const APInt& LHS, const APInt& RHS);
+  friend APInt APIntOps::srem(const APInt& LHS, const APInt& RHS);
+  friend APInt APIntOps::urem(const APInt& LHS, const APInt& RHS);
 
   unsigned BitsNum;      ///< The number of bits.
-  bool isSigned;         ///< The sign flag for this APInt.
 
   /// This union is used to store the integer value. When the
   /// integer bit-width <= 64, it uses VAL; 
@@ -114,20 +133,19 @@ class APInt {
 
 public:
   /// @brief Create a new APInt of numBits bit-width, and initialized as val.
-  APInt(uint64_t val = 0, unsigned numBits = APINT_BITS_PER_WORD, 
-        bool sign = false);
+  APInt(uint64_t val = 0, unsigned numBits = APINT_BITS_PER_WORD);
 
   /// @brief Create a new APInt of numBits bit-width, and initialized as 
   /// bigVal[].
-  APInt(unsigned numBits, uint64_t bigVal[], bool sign = false);
+  APInt(unsigned numBits, uint64_t bigVal[]);
 
   /// @brief Create a new APInt by translating the string represented 
   /// integer value.
-  APInt(const std::string& Val, uint8_t radix = 10, bool sign = false);
+  APInt(const std::string& Val, uint8_t radix = 10);
 
   /// @brief Create a new APInt by translating the char array represented
   /// integer value.
-  APInt(const char StrStart[], unsigned slen, uint8_t radix, bool sign = false);
+  APInt(const char StrStart[], unsigned slen, uint8_t radix);
 
   /// @brief Copy Constructor.
   APInt(const APInt& API);
@@ -179,14 +197,6 @@ public:
   /// @brief Bitwise XOR assignment operator. 
   APInt& operator^=(const APInt& RHS);
 
-  /// Left-shift the APInt by shiftAmt and assigns the result to this APInt.
-  /// @brief Left-shift assignment operator. 
-  APInt& operator<<=(unsigned shiftAmt);
-
-  /// Right-shift the APInt by shiftAmt and assigns the result to this APInt.
-  /// @brief Right-shift assignment operator. 
-  APInt& operator>>=(unsigned shiftAmt);
-
   /// Performs a bitwise complement operation on this APInt.
   /// @brief Bitwise complement operator. 
   APInt operator~() const;
@@ -196,11 +206,6 @@ public:
   /// @brief Multiplication assignment operator. 
   APInt& operator*=(const APInt& RHS);
 
-  /// Divides this APInt by the given APInt &RHS and 
-  /// assigns the result to this APInt.
-  /// @brief Division assignment operator. 
-  APInt& operator/=(const APInt& RHS);
-
   /// Adds this APInt by the given APInt& RHS and 
   /// assigns the result to this APInt.
   /// @brief Addition assignment operator. 
@@ -211,11 +216,6 @@ public:
   /// @brief Subtraction assignment operator. 
   APInt& operator-=(const APInt& RHS);
 
-  /// Yields the remainder from the division of this APInt by 
-  /// the given APInt& RHS and assigns the remainder to this APInt.
-  /// @brief Remainder assignment operator. 
-  APInt& operator%=(const APInt& RHS);
-
   /// Performs bitwise AND operation on this APInt and 
   /// the given APInt& RHS.
   /// @brief Bitwise AND operator. 
@@ -245,15 +245,6 @@ public:
   /// @brief Multiplication operator. 
   APInt operator*(const APInt& RHS) const;
 
-  /// Divides this APInt by the given APInt& RHS.
-  /// @brief Division operator. 
-  APInt operator/(const APInt& RHS) const;
-
-  /// Yields the remainder from the division of 
-  /// this APInt and the given APInt& RHS.
-  /// @brief Remainder operator. 
-  APInt operator%(const APInt& RHS) const;
-
   /// Adds this APInt by the given APInt& RHS.
   /// @brief Addition operator. 
   APInt operator+(const APInt& RHS) const;
@@ -262,13 +253,10 @@ public:
   /// @brief Subtraction operator. 
   APInt operator-(const APInt& RHS) const;
 
-  /// Left-shift the APInt by shiftAmt.
-  /// @brief Left-shift operator. 
-  APInt operator<<(unsigned shiftAmt) const;
-
-  /// Right-shift the APInt by shiftAmt.
-  /// @brief Right-shift operator. 
-  APInt operator>>(unsigned shiftAmt) const;
+  ///
+  inline APInt operator-() const {
+    return APInt(0, BitsNum) - (*this);
+  }
 
   /// @brief Array-indexing support.
   bool operator[](unsigned bitPosition) const;
@@ -321,9 +309,7 @@ public:
   /// word, just returns VAL, otherwise pVal[0].
   inline uint64_t getValue() {
     if (isSingleWord())
-      return isSigned ? ((int64_t(VAL) << (APINT_BITS_PER_WORD - BitsNum)) >> 
-                         (APINT_BITS_PER_WORD - BitsNum)) :
-                        VAL;
+      return VAL;
     assert(0 && "This APInt's bitwidth > 64");
   }
 
@@ -403,6 +389,8 @@ public:
 
 };
 
+namespace APIntOps {
+
 /// @brief Check if the specified APInt has a N-bits integer value.
 inline bool isIntN(unsigned N, const APInt& APIVal) {
   if (APIVal.isSingleWord()) {
@@ -439,6 +427,62 @@ inline APInt LogBase2(const APInt& APIVal) {
 /// using Euclid's algorithm.
 APInt GreatestCommonDivisor(const APInt& API1, const APInt& API2);
 
+/// Arithmetic right-shift the APInt by shiftAmt.
+/// @brief Arithmetic right-shift function.
+APInt ashr(const APInt& LHS, unsigned shiftAmt);
+
+/// Logical right-shift the APInt by shiftAmt.
+/// @brief Logical right-shift function.
+APInt lshr(const APInt& LHS, unsigned shiftAmt);
+
+/// Left-shift the APInt by shiftAmt.
+/// @brief Left-shift function.
+APInt shl(const APInt& LHS, unsigned shiftAmt);
+
+/// Signed divide APInt LHS by APInt RHS.
+/// @brief Signed division function for APInt.
+inline APInt sdiv(const APInt& LHS, const APInt& RHS) {
+  bool isSignedLHS = LHS[LHS.BitsNum - 1], isSignedRHS = RHS[RHS.BitsNum - 1];
+  APInt API = udiv(isSignedLHS ? -LHS : LHS, isSignedRHS ? -RHS : RHS);
+  return isSignedLHS != isSignedRHS ? -API : API;;
+}
+
+/// Unsigned divide APInt LHS by APInt RHS.
+/// @brief Unsigned division function for APInt.
+APInt udiv(const APInt& LHS, const APInt& RHS);
+
+/// Signed remainder operation on APInt.
+/// @brief Function for signed remainder operation.
+inline APInt srem(const APInt& LHS, const APInt& RHS) {
+  bool isSignedLHS = LHS[LHS.BitsNum - 1], isSignedRHS = RHS[RHS.BitsNum - 1];
+  APInt API = urem(isSignedLHS ? -LHS : LHS, isSignedRHS ? -RHS : RHS);
+  return isSignedLHS ? -API : API;
+}
+
+/// Unsigned remainder operation on APInt.
+/// @brief Function for unsigned remainder operation.
+APInt urem(const APInt& LHS, const APInt& RHS);
+
+/// Performs multiplication on APInt values.
+/// @brief Function for multiplication operation.
+inline APInt mul(const APInt& LHS, const APInt& RHS) {
+  return LHS * RHS;
+}
+
+/// Performs addition on APInt values.
+/// @brief Function for addition operation.
+inline APInt add(const APInt& LHS, const APInt& RHS) {
+  return LHS + RHS;
+}
+
+/// Performs subtraction on APInt values.
+/// @brief Function for subtraction operation.
+inline APInt sub(const APInt& LHS, const APInt& RHS) {
+  return LHS - RHS;
+}
+
+} // End of APIntOps namespace
+
 } // End of llvm namespace
 
 #endif
index c288f98ff9a275afa1b3b892fb7b4e17f2168a10..21fb8cffc7ff966769f4388ec821d2604f04de5d 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "llvm/ADT/APInt.h"
 
-#if 0
+#if 1
 #include "llvm/DerivedTypes.h"
 #include "llvm/Support/MathExtras.h"
 #include <cstring>
@@ -262,8 +262,8 @@ static uint64_t lshift(uint64_t dest[], unsigned d_offset,
   return retVal;
 }
 
-APInt::APInt(uint64_t val, unsigned numBits, bool sign)
-  : BitsNum(numBits), isSigned(sign) {
+APInt::APInt(uint64_t val, unsigned numBits)
+  : BitsNum(numBits) {
   assert(BitsNum >= IntegerType::MIN_INT_BITS && "bitwidth too small");
   assert(BitsNum <= IntegerType::MAX_INT_BITS && "bitwidth too large");
   if (isSingleWord()) 
@@ -277,8 +277,8 @@ APInt::APInt(uint64_t val, unsigned numBits, bool sign)
   }
 }
 
-APInt::APInt(unsigned numBits, uint64_t bigVal[], bool sign)
-  : BitsNum(numBits), isSigned(sign) {
+APInt::APInt(unsigned numBits, uint64_t bigVal[])
+  : BitsNum(numBits) {
   assert(BitsNum >= IntegerType::MIN_INT_BITS && "bitwidth too small");
   assert(BitsNum <= IntegerType::MAX_INT_BITS && "bitwidth too large");
   assert(bigVal && "Null pointer detected!");
@@ -301,15 +301,13 @@ APInt::APInt(unsigned numBits, uint64_t bigVal[], bool sign)
 
 /// @brief Create a new APInt by translating the char array represented
 /// integer value.
-APInt::APInt(const char StrStart[], unsigned slen, uint8_t radix, bool sign)
-  : isSigned(sign) {
+APInt::APInt(const char StrStart[], unsigned slen, uint8_t radix) {
   StrToAPInt(StrStart, slen, radix);
 }
 
 /// @brief Create a new APInt by translating the string represented
 /// integer value.
-APInt::APInt(const std::string& Val, uint8_t radix, bool sign)
-  : isSigned(sign) {
+APInt::APInt(const std::string& Val, uint8_t radix) {
   assert(!Val.empty() && "String empty?");
   StrToAPInt(Val.c_str(), Val.size(), radix);
 }
@@ -386,7 +384,7 @@ void APInt::StrToAPInt(const char *StrStart, unsigned slen, uint8_t radix) {
 }
 
 APInt::APInt(const APInt& APIVal)
-  : BitsNum(APIVal.BitsNum), isSigned(APIVal.isSigned) {
+  : BitsNum(APIVal.BitsNum) {
   if (isSingleWord()) VAL = APIVal.VAL;
   else {
     // Memory allocation and check if successful.
@@ -421,6 +419,7 @@ APInt& APInt::operator=(uint64_t RHS) {
     pVal[0] = RHS;
     memset(pVal, 0, (getNumWords() - 1) * 8);
   }
+  TruncToBits();
   return *this;
 }
 
@@ -514,101 +513,6 @@ APInt& APInt::operator*=(const APInt& RHS) {
   return *this;
 }
 
-/// @brief Division assignment operator. Divides this APInt by the given APInt
-/// &RHS and assigns the result to this APInt.
-APInt& APInt::operator/=(const APInt& RHS) {
-  unsigned first = RHS.getNumWords() * APINT_BITS_PER_WORD - 
-                   RHS.CountLeadingZeros();
-  unsigned ylen = !first ? 0 : whichWord(first - 1) + 1;
-  assert(ylen && "Divided by zero???");
-  if (isSingleWord()) {
-    if (isSigned && RHS.isSigned)
-      VAL = RHS.isSingleWord() ? (int64_t(VAL) / int64_t(RHS.VAL)) :
-            (ylen > 1 ? 0 : int64_t(VAL) / int64_t(RHS.pVal[0]));
-    else
-      VAL = RHS.isSingleWord() ? (VAL / RHS.VAL) : 
-          (ylen > 1 ? 0 : VAL / RHS.pVal[0]);
-  } else {
-    unsigned first2 = getNumWords() * APINT_BITS_PER_WORD - CountLeadingZeros();
-    unsigned xlen = !first2 ? 0 : whichWord(first2 - 1) + 1;
-    if (!xlen)
-      return *this;
-    else if ((*this) < RHS)
-      memset(pVal, 0, getNumWords() * 8);
-    else if ((*this) == RHS) {
-      memset(pVal, 0, getNumWords() * 8);
-      pVal[0] = 1;
-    } else if (xlen == 1)
-      pVal[0] /= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
-    else {
-      uint64_t *xwords = new uint64_t[xlen+1], *ywords = new uint64_t[ylen];
-      assert(xwords && ywords && "Memory Allocation Failed!");
-      memcpy(xwords, pVal, xlen * 8);
-      xwords[xlen] = 0;
-      memcpy(ywords, RHS.isSingleWord() ? &RHS.VAL : RHS.pVal, ylen * 8);
-      if (unsigned nshift = 63 - (first - 1) % 64) {
-        lshift(ywords, 0, ywords, ylen, nshift);
-        unsigned xlentmp = xlen;
-        xwords[xlen++] = lshift(xwords, 0, xwords, xlentmp, nshift);
-      }
-      div((unsigned*)xwords, xlen*2-1, (unsigned*)ywords, ylen*2);
-      memset(pVal, 0, getNumWords() * 8);
-      memcpy(pVal, xwords + ylen, (xlen - ylen) * 8);
-      delete[] xwords;
-      delete[] ywords;
-    }
-  }
-  return *this;
-}
-
-/// @brief Remainder assignment operator. Yields the remainder from the 
-/// division of this APInt by the given APInt& RHS and assigns the remainder 
-/// to this APInt.
-APInt& APInt::operator%=(const APInt& RHS) {
-  unsigned first = RHS.getNumWords() * APINT_BITS_PER_WORD -
-                   RHS.CountLeadingZeros();
-  unsigned ylen = !first ? 0 : whichWord(first - 1) + 1;
-  assert(ylen && "Performing remainder operation by zero ???");
-  if (isSingleWord()) {
-    if (isSigned && RHS.isSigned)
-      VAL = RHS.isSingleWord() ? (int64_t(VAL) % int64_t(RHS.VAL)) :
-            (ylen > 1 ? VAL : int64_t(VAL) % int64_t(RHS.pVal[0]));
-    else
-      VAL = RHS.isSingleWord() ? (VAL % RHS.VAL) : 
-          (ylen > 1 ? VAL : VAL % RHS.pVal[0]);
-  } else {
-    unsigned first2 = getNumWords() * APINT_BITS_PER_WORD - CountLeadingZeros();
-    unsigned xlen = !first2 ? 0 : whichWord(first2 - 1) + 1;
-    if (!xlen || (*this) < RHS)
-      return *this;
-    else if ((*this) == RHS) 
-      memset(pVal, 0, getNumWords() * 8);
-    else if (xlen == 1) 
-      pVal[0] %= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
-    else {
-      uint64_t *xwords = new uint64_t[xlen+1], *ywords = new uint64_t[ylen];
-      assert(xwords && ywords && "Memory Allocation Failed!");
-      memcpy(xwords, pVal, xlen * 8);
-      xwords[xlen] = 0;
-      memcpy(ywords, RHS.isSingleWord() ? &RHS.VAL : RHS.pVal, ylen * 8);
-      unsigned nshift = 63 - (first - 1) % 64;
-      if (nshift) {
-        lshift(ywords, 0, ywords, ylen, nshift);
-        unsigned xlentmp = xlen;
-        xwords[xlen++] = lshift(xwords, 0, xwords, xlentmp, nshift);
-      }
-      div((unsigned*)xwords, xlen*2-1, (unsigned*)ywords, ylen*2);
-      memset(pVal, 0, getNumWords() * 8);
-      for (unsigned i = 0; i < ylen-1; ++i)
-        pVal[i] = (xwords[i] >> nshift) | (xwords[i+1] << (64 - nshift));
-      pVal[ylen-1] = xwords[ylen-1] >> nshift;
-      delete[] xwords;
-      delete[] ywords;
-    }
-  }
-  return *this;
-}
-
 /// @brief Bitwise AND assignment operator. Performs bitwise AND operation on
 /// this APInt and the given APInt& RHS, assigns the result to this APInt.
 APInt& APInt::operator&=(const APInt& RHS) {
@@ -753,19 +657,6 @@ APInt APInt::operator*(const APInt& RHS) const {
   return API;
 }
 
-/// @brief Division operator. Divides this APInt by the given APInt& RHS.
-APInt APInt::operator/(const APInt& RHS) const {
-  APInt API(*this);
-  return API /= RHS;
-}
-
-/// @brief Remainder operator. Yields the remainder from the division of this
-/// APInt and the given APInt& RHS.
-APInt APInt::operator%(const APInt& RHS) const {
-  APInt API(*this);
-  return API %= RHS;
-}
-
 /// @brief Addition operator. Adds this APInt by the given APInt& RHS.
 APInt APInt::operator+(const APInt& RHS) const {
   APInt API(*this);
@@ -778,7 +669,6 @@ APInt APInt::operator+(const APInt& RHS) const {
 APInt APInt::operator-(const APInt& RHS) const {
   APInt API(*this);
   API -= RHS;
-  API.TruncToBits();
   return API;
 }
 
@@ -822,12 +712,6 @@ bool APInt::operator==(uint64_t Val) const {
 /// @brief Less-than operator. Compare this APInt with the given APInt& RHS
 /// for the validity of the less-than relationship.
 bool APInt::operator <(const APInt& RHS) const {
-  if (isSigned && RHS.isSigned) {
-    if ((*this)[BitsNum-1] > RHS[RHS.BitsNum-1])
-      return false;
-    else if ((*this)[BitsNum-1] < RHS[RHS.BitsNum-1])
-      return true;
-  }
   unsigned n1 = getNumWords() * 64 - CountLeadingZeros(), 
            n2 = RHS.getNumWords() * 64 - RHS.CountLeadingZeros();
   if (n1 < n2) return true;
@@ -896,54 +780,6 @@ APInt& APInt::clear() {
   return *this;
 }
 
-/// @brief Left-shift assignment operator. Left-shift the APInt by shiftAmt
-/// and assigns the result to this APInt.
-APInt& APInt::operator<<=(unsigned shiftAmt) {
-  if (shiftAmt >= BitsNum) {
-    if (isSingleWord()) VAL = 0;
-    else 
-      memset(pVal, 0, getNumWords() * 8);
-  } else {
-    for (unsigned i = 0; i < shiftAmt; ++i) clear(i);
-    for (unsigned i = shiftAmt; i < BitsNum; ++i) {
-      if ((*this)[i-shiftAmt]) set(i);
-      else clear(i);
-    }
-  }
-  return *this;
-}
-
-/// @brief Left-shift operator. Left-shift the APInt by shiftAmt.
-APInt APInt::operator<<(unsigned shiftAmt) const {
-  APInt API(*this);
-  API <<= shiftAmt;
-  return API;
-}
-
-/// @brief Right-shift assignment operator. Right-shift the APInt by shiftAmt
-/// and assigns the result to this APInt.
-APInt& APInt::operator>>=(unsigned shiftAmt) {
-  bool isAShr = isSigned && (*this)[BitsNum-1];
-  if (isSingleWord())
-    VAL = isAShr ? (int64_t(VAL) >> shiftAmt) : (VAL >> shiftAmt);
-  else {
-    unsigned i = 0;
-    for (i = 0; i < BitsNum - shiftAmt; ++i)
-      if ((*this)[i+shiftAmt]) set(i);
-      else clear(i);
-    for (; i < BitsNum; ++i)
-      isAShr ? set(i) : clear(i);
-  }
-  return *this;
-}
-
-/// @brief Right-shift operator. Right-shift the APInt by shiftAmt.
-APInt APInt::operator>>(unsigned shiftAmt) const {
-  APInt API(*this);
-  API >>= shiftAmt;
-  return API;
-}
-
 /// @brief Bitwise NOT operator. Performs a bitwise logical NOT operation on
 /// this APInt.
 APInt APInt::operator~() const {
@@ -1042,12 +878,13 @@ APInt APInt::getNullValue(unsigned numBits) {
 
 /// HiBits - This function returns the high "numBits" bits of this APInt.
 APInt APInt::HiBits(unsigned numBits) const {
-  return (*this) >> (BitsNum - numBits); 
+  return APIntOps::lshr(*this, BitsNum - numBits);
 }
 
 /// LoBits - This function returns the low "numBits" bits of this APInt.
 APInt APInt::LoBits(unsigned numBits) const {
-  return ((*this) << (BitsNum - numBits)) >> (BitsNum - numBits);
+  return APIntOps::lshr(APIntOps::shl(*this, BitsNum - numBits), 
+                        BitsNum - numBits);
 }
 
 /// CountLeadingZeros - This function is a APInt version corresponding to 
@@ -1096,7 +933,7 @@ unsigned APInt::CountPopulation() const {
 
 /// ByteSwap - This function returns a byte-swapped representation of the
 /// APInt argument, APIVal.
-APInt llvm::ByteSwap(const APInt& APIVal) {
+APInt llvm::APIntOps::ByteSwap(const APInt& APIVal) {
   if (APIVal.BitsNum <= 32)
     return APInt(APIVal.BitsNum, ByteSwap_32(unsigned(APIVal.VAL)));
   else if (APIVal.BitsNum <= 64)
@@ -1107,15 +944,170 @@ APInt llvm::ByteSwap(const APInt& APIVal) {
 
 /// GreatestCommonDivisor - This function returns the greatest common
 /// divisor of the two APInt values using Enclid's algorithm.
-APInt llvm::GreatestCommonDivisor(const APInt& API1, const APInt& API2) {
+APInt llvm::APIntOps::GreatestCommonDivisor(const APInt& API1, 
+                                            const APInt& API2) {
   APInt A = API1, B = API2;
   while (!!B) {
     APInt T = B;
-    B = A % B;
+    B = APIntOps::urem(A, B);
     A = T;
   }
   return A;
 }
 
+/// Arithmetic right-shift the APInt by shiftAmt.
+/// @brief Arithmetic right-shift function.
+APInt llvm::APIntOps::ashr(const APInt& LHS, unsigned shiftAmt) {
+  APInt API(LHS);
+  if (API.isSingleWord())
+    API.VAL = (((int64_t(API.VAL) << (64 - API.BitsNum)) >> (64 - API.BitsNum))
+               >> shiftAmt) & (~uint64_t(0UL) >> (64 - API.BitsNum));
+  else {
+    if (shiftAmt >= API.BitsNum) {
+      memset(API.pVal, API[API.BitsNum-1] ? 1 : 0, (API.getNumWords()-1) * 8);
+      API.pVal[API.getNumWords() - 1] = ~uint64_t(0UL) >> 
+                                        (64 - API.BitsNum % 64);
+    } else {
+      unsigned i = 0;
+      for (; i < API.BitsNum - shiftAmt; ++i)
+        if (API[i+shiftAmt]) 
+          API.set(i);
+        else
+          API.clear(i);
+      for (; i < API.BitsNum; ++i)
+        API[API.BitsNum-1] ? API.set(i) : API.clear(i);
+    }
+  }
+  return API;
+}
+
+/// Logical right-shift the APInt by shiftAmt.
+/// @brief Logical right-shift function.
+APInt llvm::APIntOps::lshr(const APInt& RHS, unsigned shiftAmt) {
+  APInt API(RHS);
+  if (API.isSingleWord())
+    API.VAL >>= shiftAmt;
+  else {
+    if (shiftAmt >= API.BitsNum)
+      memset(API.pVal, 0, API.getNumWords() * 8);
+    unsigned i = 0;
+    for (i = 0; i < API.BitsNum - shiftAmt; ++i)
+      if (API[i+shiftAmt]) API.set(i);
+      else API.clear(i);
+    for (; i < API.BitsNum; ++i)
+      API.clear(i);
+  }
+  return API;
+}
+
+/// Left-shift the APInt by shiftAmt.
+/// @brief Left-shift function.
+APInt llvm::APIntOps::shl(const APInt& RHS, unsigned shiftAmt) {
+  APInt API(RHS);
+  if (shiftAmt >= API.BitsNum) {
+    if (API.isSingleWord()) 
+      API.VAL = 0;
+    else 
+      memset(API.pVal, 0, API.getNumWords() * 8);
+  } else {
+    for (unsigned i = 0; i < shiftAmt; ++i) API.clear(i);
+    for (unsigned i = shiftAmt; i < API.BitsNum; ++i) {
+      if (API[i-shiftAmt]) API.set(i);
+      else API.clear(i);
+    }
+  }
+  return API;
+}
+
+/// Unsigned divide APInt LHS by APInt RHS.
+/// @brief Unsigned division function for APInt.
+APInt llvm::APIntOps::udiv(const APInt& LHS, const APInt& RHS) {
+  APInt API(LHS);
+  unsigned first = RHS.getNumWords() * APInt::APINT_BITS_PER_WORD - 
+                   RHS.CountLeadingZeros();
+  unsigned ylen = !first ? 0 : APInt::whichWord(first - 1) + 1;
+  assert(ylen && "Divided by zero???");
+  if (API.isSingleWord()) {
+    API.VAL = RHS.isSingleWord() ? (API.VAL / RHS.VAL) : 
+              (ylen > 1 ? 0 : API.VAL / RHS.pVal[0]);
+  } else {
+    unsigned first2 = API.getNumWords() * APInt::APINT_BITS_PER_WORD - 
+                      API.CountLeadingZeros();
+    unsigned xlen = !first2 ? 0 : APInt::whichWord(first2 - 1) + 1;
+    if (!xlen)
+      return API;
+    else if (API < RHS)
+      memset(API.pVal, 0, API.getNumWords() * 8);
+    else if (API == RHS) {
+      memset(API.pVal, 0, API.getNumWords() * 8);
+      API.pVal[0] = 1;
+    } else if (xlen == 1)
+      API.pVal[0] /= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
+    else {
+      uint64_t *xwords = new uint64_t[xlen+1], *ywords = new uint64_t[ylen];
+      assert(xwords && ywords && "Memory Allocation Failed!");
+      memcpy(xwords, API.pVal, xlen * 8);
+      xwords[xlen] = 0;
+      memcpy(ywords, RHS.isSingleWord() ? &RHS.VAL : RHS.pVal, ylen * 8);
+      if (unsigned nshift = 63 - (first - 1) % 64) {
+        lshift(ywords, 0, ywords, ylen, nshift);
+        unsigned xlentmp = xlen;
+        xwords[xlen++] = lshift(xwords, 0, xwords, xlentmp, nshift);
+      }
+      div((unsigned*)xwords, xlen*2-1, (unsigned*)ywords, ylen*2);
+      memset(API.pVal, 0, API.getNumWords() * 8);
+      memcpy(API.pVal, xwords + ylen, (xlen - ylen) * 8);
+      delete[] xwords;
+      delete[] ywords;
+    }
+  }
+  return API;
+}
+
+/// Unsigned remainder operation on APInt.
+/// @brief Function for unsigned remainder operation.
+APInt llvm::APIntOps::urem(const APInt& LHS, const APInt& RHS) {
+  APInt API(LHS);
+  unsigned first = RHS.getNumWords() * APInt::APINT_BITS_PER_WORD -
+                   RHS.CountLeadingZeros();
+  unsigned ylen = !first ? 0 : APInt::whichWord(first - 1) + 1;
+  assert(ylen && "Performing remainder operation by zero ???");
+  if (API.isSingleWord()) {
+    API.VAL = RHS.isSingleWord() ? (API.VAL % RHS.VAL) : 
+              (ylen > 1 ? API.VAL : API.VAL % RHS.pVal[0]);
+  } else {
+    unsigned first2 = API.getNumWords() * APInt::APINT_BITS_PER_WORD - 
+                      API.CountLeadingZeros();
+    unsigned xlen = !first2 ? 0 : API.whichWord(first2 - 1) + 1;
+    if (!xlen || API < RHS)
+      return API;
+    else if (API == RHS) 
+      memset(API.pVal, 0, API.getNumWords() * 8);
+    else if (xlen == 1) 
+      API.pVal[0] %= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
+    else {
+      uint64_t *xwords = new uint64_t[xlen+1], *ywords = new uint64_t[ylen];
+      assert(xwords && ywords && "Memory Allocation Failed!");
+      memcpy(xwords, API.pVal, xlen * 8);
+      xwords[xlen] = 0;
+      memcpy(ywords, RHS.isSingleWord() ? &RHS.VAL : RHS.pVal, ylen * 8);
+      unsigned nshift = 63 - (first - 1) % 64;
+      if (nshift) {
+        lshift(ywords, 0, ywords, ylen, nshift);
+        unsigned xlentmp = xlen;
+        xwords[xlen++] = lshift(xwords, 0, xwords, xlentmp, nshift);
+      }
+      div((unsigned*)xwords, xlen*2-1, (unsigned*)ywords, ylen*2);
+      memset(API.pVal, 0, API.getNumWords() * 8);
+      for (unsigned i = 0; i < ylen-1; ++i)
+        API.pVal[i] = (xwords[i] >> nshift) | (xwords[i+1] << (64 - nshift));
+      API.pVal[ylen-1] = xwords[ylen-1] >> nshift;
+      delete[] xwords;
+      delete[] ywords;
+    }
+  }
+  return API;
+}
+
 #endif