X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FAPSInt.h;h=048c65ce2c773f00654f0f2a47db54b52ec40689;hb=b4c28fc93f5149a0bd7967af44c429412e751c56;hp=edb36bafe4a4c7331bb2778ca2320a6956d186b2;hpb=7fb842420a87d984196454b3e43fc54267f79edc;p=oota-llvm.git diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index edb36bafe4a..048c65ce2c7 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -18,8 +18,7 @@ #include "llvm/ADT/APInt.h" namespace llvm { - - + class APSInt : public APInt { bool IsUnsigned; public: @@ -28,27 +27,27 @@ public: /// APSInt ctor - Create an APSInt with the specified width, default to /// unsigned. - explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) + explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {} - explicit APSInt(const APInt &I, bool isUnsigned = true) + explicit APSInt(const APInt &I, bool isUnsigned = true) : APInt(I), IsUnsigned(isUnsigned) {} APSInt &operator=(const APSInt &RHS) { - APInt::operator=(RHS); + APInt::operator=(RHS); IsUnsigned = RHS.IsUnsigned; return *this; } APSInt &operator=(const APInt &RHS) { // Retain our current sign. - APInt::operator=(RHS); + APInt::operator=(RHS); return *this; } APSInt &operator=(uint64_t RHS) { // Retain our current sign. - APInt::operator=(RHS); + APInt::operator=(RHS); return *this; } @@ -57,29 +56,36 @@ public: bool isUnsigned() const { return IsUnsigned; } void setIsUnsigned(bool Val) { IsUnsigned = Val; } void setIsSigned(bool Val) { IsUnsigned = !Val; } - - /// This is used internally to convert an APInt to a string. - /// @brief Converts an APInt to a std::string - std::string toString(uint8_t Radix = 10) const { + + /// toString - Append this APSInt to the specified SmallString. + void toString(SmallVectorImpl &Str, unsigned Radix = 10) const { + APInt::toString(Str, Radix, isSigned()); + } + /// toString - Converts an APInt to a std::string. This is an inefficient + /// method, your should prefer passing in a SmallString instead. + std::string toString(unsigned Radix) const { return APInt::toString(Radix, isSigned()); } - - APSInt& extend(uint32_t width) { + using APInt::toString; + + APSInt trunc(uint32_t width) const { + return APSInt(APInt::trunc(width), IsUnsigned); + } + + APSInt extend(uint32_t width) const { if (IsUnsigned) - zext(width); + return APSInt(zext(width), IsUnsigned); else - sext(width); - return *this; + return APSInt(sext(width), IsUnsigned); } - - APSInt& extOrTrunc(uint32_t width) { + + APSInt extOrTrunc(uint32_t width) const { if (IsUnsigned) - zextOrTrunc(width); + return APSInt(zextOrTrunc(width), IsUnsigned); else - sextOrTrunc(width); - return *this; + return APSInt(sextOrTrunc(width), IsUnsigned); } - + const APSInt &operator%=(const APSInt &RHS) { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); if (IsUnsigned) @@ -104,7 +110,7 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false); } - + APSInt operator>>(unsigned Amt) const { return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false); } @@ -112,7 +118,7 @@ public: *this = *this >> Amt; return *this; } - + inline bool operator<(const APSInt& RHS) const { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return IsUnsigned ? ult(RHS) : slt(RHS); @@ -129,24 +135,37 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return IsUnsigned ? uge(RHS) : sge(RHS); } - + inline bool operator==(const APSInt& RHS) const { + assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); + return eq(RHS); + } + inline bool operator==(int64_t RHS) const { + return isSameValue(*this, APSInt(APInt(64, RHS), true)); + } + inline bool operator!=(const APSInt& RHS) const { + return !((*this) == RHS); + } + inline bool operator!=(int64_t RHS) const { + return !((*this) == RHS); + } + // The remaining operators just wrap the logic of APInt, but retain the // signedness information. - + APSInt operator<<(unsigned Bits) const { return APSInt(static_cast(*this) << Bits, IsUnsigned); - } + } APSInt& operator<<=(unsigned Amt) { *this = *this << Amt; return *this; } - + APSInt& operator++() { static_cast(*this)++; return *this; } APSInt& operator--() { - static_cast(*this)++; + static_cast(*this)--; return *this; } APSInt operator++(int) { @@ -154,20 +173,20 @@ public: } APSInt operator--(int) { return APSInt(--static_cast(*this), IsUnsigned); - } + } APSInt operator-() const { return APSInt(-static_cast(*this), IsUnsigned); - } + } APSInt& operator+=(const APSInt& RHS) { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); static_cast(*this) += RHS; return *this; - } + } APSInt& operator-=(const APSInt& RHS) { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); static_cast(*this) -= RHS; return *this; - } + } APSInt& operator*=(const APSInt& RHS) { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); static_cast(*this) *= RHS; @@ -189,36 +208,36 @@ public: return *this; } - APSInt operator&(const APSInt& RHS) const { + APSInt operator&(const APSInt& RHS) const { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast(*this) & RHS, IsUnsigned); } APSInt And(const APSInt& RHS) const { return this->operator&(RHS); } - - APSInt operator|(const APSInt& RHS) const { + + APSInt operator|(const APSInt& RHS) const { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast(*this) | RHS, IsUnsigned); } APSInt Or(const APSInt& RHS) const { return this->operator|(RHS); } - - - APSInt operator^(const APSInt& RHS) const { + + + APSInt operator^(const APSInt& RHS) const { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast(*this) ^ RHS, IsUnsigned); } APSInt Xor(const APSInt& RHS) const { return this->operator^(RHS); - } - + } + APSInt operator*(const APSInt& RHS) const { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast(*this) * RHS, IsUnsigned); } - APSInt operator+(const APSInt& RHS) const { + APSInt operator+(const APSInt& RHS) const { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast(*this) + RHS, IsUnsigned); } @@ -226,15 +245,68 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast(*this) - RHS, IsUnsigned); } - APSInt operator~() const { + APSInt operator~() const { return APSInt(~static_cast(*this), IsUnsigned); } - + + /// getMaxValue - Return the APSInt representing the maximum integer value + /// with the given bit width and signedness. + static APSInt getMaxValue(uint32_t numBits, bool Unsigned) { + return APSInt(Unsigned ? APInt::getMaxValue(numBits) + : APInt::getSignedMaxValue(numBits), Unsigned); + } + + /// getMinValue - Return the APSInt representing the minimum integer value + /// with the given bit width and signedness. + static APSInt getMinValue(uint32_t numBits, bool Unsigned) { + return APSInt(Unsigned ? APInt::getMinValue(numBits) + : APInt::getSignedMinValue(numBits), Unsigned); + } + + /// \brief Determine if two APSInts have the same value, zero- or + /// sign-extending as needed. + static bool isSameValue(const APSInt &I1, const APSInt &I2) { + if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned()) + return I1 == I2; + + // Check for a bit-width mismatch. + if (I1.getBitWidth() > I2.getBitWidth()) + return isSameValue(I1, I2.extend(I1.getBitWidth())); + else if (I2.getBitWidth() > I1.getBitWidth()) + return isSameValue(I1.extend(I2.getBitWidth()), I2); + + // We have a signedness mismatch. Turn the signed value into an unsigned + // value. + if (I1.isSigned()) { + if (I1.isNegative()) + return false; + + return APSInt(I1, true) == I2; + } + + if (I2.isNegative()) + return false; + + return I1 == APSInt(I2, true); + } + /// Profile - Used to insert APSInt objects, or objects that contain APSInt /// objects, into FoldingSets. void Profile(FoldingSetNodeID& ID) const; }; - + +inline bool operator==(int64_t V1, const APSInt& V2) { + return V2 == V1; +} +inline bool operator!=(int64_t V1, const APSInt& V2) { + return V2 != V1; +} + +inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) { + I.print(OS, I.isSigned()); + return OS; +} + } // end namespace llvm #endif