diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 8709fb80e08..14eee40f78f 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -24,15 +24,7 @@ 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); } @@ -53,19 +45,6 @@ namespace APIntOps { /// Note: In this class, all bit/byte/word positions are zero-based. /// class APInt { - /// Friend Functions of APInt declared here. For detailed comments, - /// see bottom of this file. - 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. /// This union is used to store the integer value. When the @@ -387,19 +366,68 @@ public: inline unsigned getNumBits() const { return BitsNum; } + /// @brief Check if this APInt has a N-bits integer value. + inline bool isIntN(unsigned N) const { + if (isSingleWord()) { + return VAL == VAL & (~uint64_t(0ULL) >> (64 - N)); + } else { + APInt Tmp(N, pVal); + return Tmp == (*this); + } + } + + /// @returns a byte-swapped representation of this APInt Value. + APInt ByteSwap() const; + + /// @returns the floor log base 2 of this APInt. + inline unsigned LogBase2() const { + return getNumWords() * APINT_BITS_PER_WORD - + CountLeadingZeros(); + } + + /// Arithmetic right-shift this APInt by shiftAmt. + /// @brief Arithmetic right-shift function. + APInt ashr(unsigned shiftAmt) const; + + /// Logical right-shift this APInt by shiftAmt. + /// @brief Logical right-shift function. + APInt lshr(unsigned shiftAmt) const; + + /// Left-shift this APInt by shiftAmt. + /// @brief Left-shift function. + APInt shl(unsigned shiftAmt) const; + + /// Signed divide this APInt by APInt RHS. + /// @brief Signed division function for APInt. + inline APInt sdiv(const APInt& RHS) const { + bool isSignedLHS = (*this)[BitsNum - 1], isSignedRHS = RHS[RHS.BitsNum - 1]; + APInt API = APIntOps::udiv(isSignedLHS ? -(*this) : (*this), isSignedRHS ? -RHS : RHS); + return isSignedLHS != isSignedRHS ? -API : API;; + } + + /// Unsigned divide this APInt by APInt RHS. + /// @brief Unsigned division function for APInt. + APInt udiv(const APInt& RHS) const; + + /// Signed remainder operation on APInt. + /// @brief Function for signed remainder operation. + inline APInt srem(const APInt& RHS) const { + bool isSignedLHS = (*this)[BitsNum - 1], isSignedRHS = RHS[RHS.BitsNum - 1]; + APInt API = APIntOps::urem(isSignedLHS ? -(*this) : (*this), isSignedRHS ? -RHS : RHS); + return isSignedLHS ? -API : API; + } + + /// Unsigned remainder operation on APInt. + /// @brief Function for unsigned remainder operation. + APInt urem(const APInt& RHS) const; + }; 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()) { - APInt Tmp(N, APIVal.VAL); - return Tmp == APIVal; - } else { - APInt Tmp(N, APIVal.pVal); - return Tmp == APIVal; - } + return APIVal.isIntN(N); } /// @returns true if the argument APInt value is a sequence of ones @@ -415,12 +443,13 @@ inline const bool isShiftedMask(unsigned numBits, const APInt& APIVal) { } /// @returns a byte-swapped representation of the specified APInt Value. -APInt ByteSwap(const APInt& APIVal); +inline APInt ByteSwap(const APInt& APIVal) { + return APIVal.ByteSwap(); +} /// @returns the floor log base 2 of the specified APInt value. -inline APInt LogBase2(const APInt& APIVal) { - return APIVal.getNumWords() * APInt::APINT_BITS_PER_WORD - - APIVal.CountLeadingZeros(); +inline unsigned LogBase2(const APInt& APIVal) { + return APIVal.LogBase2(); } /// @returns the greatest common divisor of the two values @@ -429,39 +458,45 @@ 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); +inline APInt ashr(const APInt& LHS, unsigned shiftAmt) { + return LHS.ashr(shiftAmt); +} /// Logical right-shift the APInt by shiftAmt. /// @brief Logical right-shift function. -APInt lshr(const APInt& LHS, unsigned shiftAmt); +inline APInt lshr(const APInt& LHS, unsigned shiftAmt) { + return LHS.lshr(shiftAmt); +} /// Left-shift the APInt by shiftAmt. /// @brief Left-shift function. -APInt shl(const APInt& LHS, unsigned shiftAmt); +inline APInt shl(const APInt& LHS, unsigned shiftAmt) { + return LHS.shl(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;; + return LHS.sdiv(RHS); } /// Unsigned divide APInt LHS by APInt RHS. /// @brief Unsigned division function for APInt. -APInt udiv(const APInt& LHS, const APInt& RHS); +inline APInt udiv(const APInt& LHS, const APInt& RHS) { + return LHS.udiv(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; + return LHS.srem(RHS); } /// Unsigned remainder operation on APInt. /// @brief Function for unsigned remainder operation. -APInt urem(const APInt& LHS, const APInt& RHS); +inline APInt urem(const APInt& LHS, const APInt& RHS) { + return LHS.urem(RHS); +} /// Performs multiplication on APInt values. /// @brief Function for multiplication operation. @@ -481,6 +516,31 @@ inline APInt sub(const APInt& LHS, const APInt& RHS) { return LHS - RHS; } +/// Performs bitwise AND operation on APInt LHS and +/// APInt RHS. +/// @brief Bitwise AND function for APInt. +inline APInt And(const APInt& LHS, const APInt& RHS) { + return LHS & RHS; +} + +/// Performs bitwise OR operation on APInt LHS and APInt RHS. +/// @brief Bitwise OR function for APInt. +inline APInt Or(const APInt& LHS, const APInt& RHS) { + return LHS | RHS; +} + +/// Performs bitwise XOR operation on APInt. +/// @brief Bitwise XOR function for APInt. +inline APInt Xor(const APInt& LHS, const APInt& RHS) { + return LHS ^ RHS; +} + +/// Performs a bitwise complement operation on APInt. +/// @brief Bitwise complement function. +inline APInt Not(const APInt& APIVal) { + return ~APIVal; +} + } // End of APIntOps namespace } // End of llvm namespace diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index dccabda1b57..80ea80489cc 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -674,8 +674,8 @@ APInt APInt::operator-(const APInt& RHS) const { /// @brief Array-indexing support. bool APInt::operator[](unsigned bitPosition) const { - return maskBit(bitPosition) & (isSingleWord() ? - VAL : pVal[whichWord(bitPosition)]) != 0; + return (maskBit(bitPosition) & (isSingleWord() ? + VAL : pVal[whichWord(bitPosition)])) != 0; } /// @brief Equality operator. Compare this APInt with the given APInt& RHS @@ -932,14 +932,14 @@ unsigned APInt::CountPopulation() const { /// ByteSwap - This function returns a byte-swapped representation of the -/// APInt argument, 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) - return APInt(APIVal.BitsNum, ByteSwap_64(APIVal.VAL)); +/// this APInt. +APInt APInt::ByteSwap() const { + if (BitsNum <= 32) + return APInt(BitsNum, ByteSwap_32(unsigned(VAL))); + else if (BitsNum <= 64) + return APInt(BitsNum, ByteSwap_64(VAL)); else - return APIVal; + return *this; } /// GreatestCommonDivisor - This function returns the greatest common @@ -955,10 +955,10 @@ APInt llvm::APIntOps::GreatestCommonDivisor(const APInt& API1, return A; } -/// Arithmetic right-shift the APInt by shiftAmt. +/// Arithmetic right-shift this APInt by shiftAmt. /// @brief Arithmetic right-shift function. -APInt llvm::APIntOps::ashr(const APInt& LHS, unsigned shiftAmt) { - APInt API(LHS); +APInt APInt::ashr(unsigned shiftAmt) const { + APInt API(*this); if (API.isSingleWord()) API.VAL = (((int64_t(API.VAL) << (64 - API.BitsNum)) >> (64 - API.BitsNum)) >> shiftAmt) & (~uint64_t(0UL) >> (64 - API.BitsNum)); @@ -981,10 +981,10 @@ APInt llvm::APIntOps::ashr(const APInt& LHS, unsigned shiftAmt) { return API; } -/// Logical right-shift the APInt by shiftAmt. +/// Logical right-shift this APInt by shiftAmt. /// @brief Logical right-shift function. -APInt llvm::APIntOps::lshr(const APInt& RHS, unsigned shiftAmt) { - APInt API(RHS); +APInt APInt::lshr(unsigned shiftAmt) const { + APInt API(*this); if (API.isSingleWord()) API.VAL >>= shiftAmt; else { @@ -1000,10 +1000,10 @@ APInt llvm::APIntOps::lshr(const APInt& RHS, unsigned shiftAmt) { return API; } -/// Left-shift the APInt by shiftAmt. +/// Left-shift this APInt by shiftAmt. /// @brief Left-shift function. -APInt llvm::APIntOps::shl(const APInt& RHS, unsigned shiftAmt) { - APInt API(RHS); +APInt APInt::shl(unsigned shiftAmt) const { + APInt API(*this); if (shiftAmt >= API.BitsNum) { if (API.isSingleWord()) API.VAL = 0; @@ -1019,10 +1019,10 @@ APInt llvm::APIntOps::shl(const APInt& RHS, unsigned shiftAmt) { return API; } -/// Unsigned divide APInt LHS by APInt RHS. +/// Unsigned divide this APInt by APInt RHS. /// @brief Unsigned division function for APInt. -APInt llvm::APIntOps::udiv(const APInt& LHS, const APInt& RHS) { - APInt API(LHS); +APInt APInt::udiv(const APInt& RHS) const { + APInt API(*this); unsigned first = RHS.getNumWords() * APInt::APINT_BITS_PER_WORD - RHS.CountLeadingZeros(); unsigned ylen = !first ? 0 : APInt::whichWord(first - 1) + 1; @@ -1066,8 +1066,8 @@ APInt llvm::APIntOps::udiv(const APInt& LHS, const APInt& RHS) { /// Unsigned remainder operation on APInt. /// @brief Function for unsigned remainder operation. -APInt llvm::APIntOps::urem(const APInt& LHS, const APInt& RHS) { - APInt API(LHS); +APInt APInt::urem(const APInt& RHS) const { + APInt API(*this); unsigned first = RHS.getNumWords() * APInt::APINT_BITS_PER_WORD - RHS.CountLeadingZeros(); unsigned ylen = !first ? 0 : APInt::whichWord(first - 1) + 1;