X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FAPSInt.h;h=807ca5e1927a14adcf592a49dca09455375ddcf8;hb=5449a1db40b75586c1daf70a14396295e7b3fe24;hp=be419272fec8746316949abd4a680e51cfc589ac;hpb=d25c9cd3ff5786655201c550ae76f1b89815e1c7;p=oota-llvm.git diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index be419272fec..807ca5e1927 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -18,34 +18,36 @@ #include "llvm/ADT/APInt.h" namespace llvm { - - + class APSInt : public APInt { bool IsUnsigned; public: + /// Default constructor that creates an uninitialized APInt. + explicit APSInt() {} + /// 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; } @@ -54,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) @@ -101,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); } @@ -109,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); @@ -126,24 +135,24 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return IsUnsigned ? uge(RHS) : sge(RHS); } - + // The remaining operators just wrap the logic of APInt, but retain the // signedness information. - - APSInt operator<<(unsigned Bits) { - return APSInt(static_cast(*this) << Bits, IsUnsigned); - } + + 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) { @@ -151,20 +160,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; @@ -186,36 +195,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); } @@ -223,15 +232,62 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast(*this) - RHS, IsUnsigned); } - APSInt operator~() { + 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 raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) { + I.print(OS, I.isSigned()); + return OS; +} + + } // end namespace llvm #endif