X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FAPSInt.h;h=048c65ce2c773f00654f0f2a47db54b52ec40689;hb=b4c28fc93f5149a0bd7967af44c429412e751c56;hp=ef689f87b2dddd4c9b1f7221c3ff55eab3275595;hpb=ed871805f718f6bd0f9f32888b82c66545fc1157;p=oota-llvm.git diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index ef689f87b2d..048c65ce2c7 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -18,7 +18,7 @@ #include "llvm/ADT/APInt.h" namespace llvm { - + class APSInt : public APInt { bool IsUnsigned; public: @@ -27,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; } @@ -56,10 +56,10 @@ public: bool isUnsigned() const { return IsUnsigned; } void setIsUnsigned(bool Val) { IsUnsigned = Val; } void setIsSigned(bool Val) { IsUnsigned = !Val; } - + /// toString - Append this APSInt to the specified SmallString. void toString(SmallVectorImpl &Str, unsigned Radix = 10) const { - return APInt::toString(Str, Radix, isSigned()); + 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. @@ -67,23 +67,25 @@ public: return APInt::toString(Radix, isSigned()); } using APInt::toString; - - APSInt& extend(uint32_t width) { + + 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) @@ -108,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); } @@ -116,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); @@ -133,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) { @@ -158,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; @@ -193,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); } @@ -230,35 +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 Signed) { - return APSInt(Signed ? APInt::getSignedMaxValue(numBits) - : APInt::getMaxValue(numBits), Signed); + 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 Signed) { - return APSInt(Signed ? APInt::getSignedMinValue(numBits) - : APInt::getMinValue(numBits), Signed); + 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