17f46734b66306bb81720fbe617c15b1184b13807Ted Kremenek//===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===// 2db8918a98ff001d0c37abf41bc62364595340035Chris Lattner// 3db8918a98ff001d0c37abf41bc62364595340035Chris Lattner// The LLVM Compiler Infrastructure 4db8918a98ff001d0c37abf41bc62364595340035Chris Lattner// 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details. 7db8918a98ff001d0c37abf41bc62364595340035Chris Lattner// 8db8918a98ff001d0c37abf41bc62364595340035Chris Lattner//===----------------------------------------------------------------------===// 9db8918a98ff001d0c37abf41bc62364595340035Chris Lattner// 10db8918a98ff001d0c37abf41bc62364595340035Chris Lattner// This file implements the APSInt class, which is a simple class that 11db8918a98ff001d0c37abf41bc62364595340035Chris Lattner// represents an arbitrary sized integer that knows its signedness. 12db8918a98ff001d0c37abf41bc62364595340035Chris Lattner// 13db8918a98ff001d0c37abf41bc62364595340035Chris Lattner//===----------------------------------------------------------------------===// 14db8918a98ff001d0c37abf41bc62364595340035Chris Lattner 15674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#ifndef LLVM_ADT_APSINT_H 16674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#define LLVM_ADT_APSINT_H 17db8918a98ff001d0c37abf41bc62364595340035Chris Lattner 18db8918a98ff001d0c37abf41bc62364595340035Chris Lattner#include "llvm/ADT/APInt.h" 19db8918a98ff001d0c37abf41bc62364595340035Chris Lattner 20db8918a98ff001d0c37abf41bc62364595340035Chris Lattnernamespace llvm { 213a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 22db8918a98ff001d0c37abf41bc62364595340035Chris Lattnerclass APSInt : public APInt { 23db8918a98ff001d0c37abf41bc62364595340035Chris Lattner bool IsUnsigned; 24db8918a98ff001d0c37abf41bc62364595340035Chris Lattnerpublic: 257fb842420a87d984196454b3e43fc54267f79edcDaniel Dunbar /// Default constructor that creates an uninitialized APInt. 26e8ce626308eb047d226847660e7dceed1169038fRichard Smith explicit APSInt() : IsUnsigned(false) {} 277fb842420a87d984196454b3e43fc54267f79edcDaniel Dunbar 28db8918a98ff001d0c37abf41bc62364595340035Chris Lattner /// APSInt ctor - Create an APSInt with the specified width, default to 29db8918a98ff001d0c37abf41bc62364595340035Chris Lattner /// unsigned. 303a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) 31d25c9cd3ff5786655201c550ae76f1b89815e1c7Ted Kremenek : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {} 32cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek 3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines explicit APSInt(APInt I, bool isUnsigned = true) 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : APInt(std::move(I)), IsUnsigned(isUnsigned) {} 35db8918a98ff001d0c37abf41bc62364595340035Chris Lattner 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines APSInt &operator=(APInt RHS) { 37db8918a98ff001d0c37abf41bc62364595340035Chris Lattner // Retain our current sign. 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines APInt::operator=(std::move(RHS)); 39db8918a98ff001d0c37abf41bc62364595340035Chris Lattner return *this; 40db8918a98ff001d0c37abf41bc62364595340035Chris Lattner } 41db8918a98ff001d0c37abf41bc62364595340035Chris Lattner 42db8918a98ff001d0c37abf41bc62364595340035Chris Lattner APSInt &operator=(uint64_t RHS) { 43db8918a98ff001d0c37abf41bc62364595340035Chris Lattner // Retain our current sign. 443a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman APInt::operator=(RHS); 45db8918a98ff001d0c37abf41bc62364595340035Chris Lattner return *this; 46db8918a98ff001d0c37abf41bc62364595340035Chris Lattner } 47db8918a98ff001d0c37abf41bc62364595340035Chris Lattner 48db8918a98ff001d0c37abf41bc62364595340035Chris Lattner // Query sign information. 49db8918a98ff001d0c37abf41bc62364595340035Chris Lattner bool isSigned() const { return !IsUnsigned; } 50db8918a98ff001d0c37abf41bc62364595340035Chris Lattner bool isUnsigned() const { return IsUnsigned; } 51db8918a98ff001d0c37abf41bc62364595340035Chris Lattner void setIsUnsigned(bool Val) { IsUnsigned = Val; } 52f7b71c64cfe805d0a48d18d55a739ce8a7e6851aChris Lattner void setIsSigned(bool Val) { IsUnsigned = !Val; } 533a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 54fad86b003a839cef40ec8ce8408322f4913368caChris Lattner /// toString - Append this APSInt to the specified SmallString. 55fad86b003a839cef40ec8ce8408322f4913368caChris Lattner void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const { 56af9b6b264f2bf4315c25b286a1c24331038545e0Bill Wendling APInt::toString(Str, Radix, isSigned()); 57fad86b003a839cef40ec8ce8408322f4913368caChris Lattner } 58fad86b003a839cef40ec8ce8408322f4913368caChris Lattner /// toString - Converts an APInt to a std::string. This is an inefficient 59c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines /// method; you should prefer passing in a SmallString instead. 60fad86b003a839cef40ec8ce8408322f4913368caChris Lattner std::string toString(unsigned Radix) const { 61028760fd88081964ace51e4205e28ff52fc1f47aChris Lattner return APInt::toString(Radix, isSigned()); 629132a2b81842b0e2b77703fab3e6fe7467f859bbChris Lattner } 63fad86b003a839cef40ec8ce8408322f4913368caChris Lattner using APInt::toString; 643a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief Get the correctly-extended \c int64_t value. 66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int64_t getExtValue() const { 67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(getMinSignedBits() <= 64 && "Too many bits for int64_t"); 68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return isSigned() ? getSExtValue() : getZExtValue(); 69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 70ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 71b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer APSInt LLVM_ATTRIBUTE_UNUSED_RESULT trunc(uint32_t width) const { 7240f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad return APSInt(APInt::trunc(width), IsUnsigned); 7340f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad } 7440f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad 75b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer APSInt LLVM_ATTRIBUTE_UNUSED_RESULT extend(uint32_t width) const { 76cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek if (IsUnsigned) 7740f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad return APSInt(zext(width), IsUnsigned); 78cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek else 7940f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad return APSInt(sext(width), IsUnsigned); 80cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 813a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 82b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer APSInt LLVM_ATTRIBUTE_UNUSED_RESULT extOrTrunc(uint32_t width) const { 83cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek if (IsUnsigned) 8440f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad return APSInt(zextOrTrunc(width), IsUnsigned); 85cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek else 8640f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad return APSInt(sextOrTrunc(width), IsUnsigned); 87cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 883a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 89db8918a98ff001d0c37abf41bc62364595340035Chris Lattner const APSInt &operator%=(const APSInt &RHS) { 90db8918a98ff001d0c37abf41bc62364595340035Chris Lattner assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 91db8918a98ff001d0c37abf41bc62364595340035Chris Lattner if (IsUnsigned) 92db8918a98ff001d0c37abf41bc62364595340035Chris Lattner *this = urem(RHS); 93db8918a98ff001d0c37abf41bc62364595340035Chris Lattner else 94db8918a98ff001d0c37abf41bc62364595340035Chris Lattner *this = srem(RHS); 95db8918a98ff001d0c37abf41bc62364595340035Chris Lattner return *this; 96db8918a98ff001d0c37abf41bc62364595340035Chris Lattner } 97db8918a98ff001d0c37abf41bc62364595340035Chris Lattner const APSInt &operator/=(const APSInt &RHS) { 98db8918a98ff001d0c37abf41bc62364595340035Chris Lattner assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 99db8918a98ff001d0c37abf41bc62364595340035Chris Lattner if (IsUnsigned) 100db8918a98ff001d0c37abf41bc62364595340035Chris Lattner *this = udiv(RHS); 101db8918a98ff001d0c37abf41bc62364595340035Chris Lattner else 102db8918a98ff001d0c37abf41bc62364595340035Chris Lattner *this = sdiv(RHS); 103db8918a98ff001d0c37abf41bc62364595340035Chris Lattner return *this; 104db8918a98ff001d0c37abf41bc62364595340035Chris Lattner } 105403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner APSInt operator%(const APSInt &RHS) const { 106403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 107cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false); 108403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner } 109403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner APSInt operator/(const APSInt &RHS) const { 110403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 111cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false); 112403949ea93d78796fcd803e75c97b68e53e331a9Chris Lattner } 1133a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 114cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt operator>>(unsigned Amt) const { 115cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false); 116db8918a98ff001d0c37abf41bc62364595340035Chris Lattner } 117cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt& operator>>=(unsigned Amt) { 118cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek *this = *this >> Amt; 1197ccd9ec4f40d1cdf740c98dab8e212943a4b4863Anders Carlsson return *this; 1207ccd9ec4f40d1cdf740c98dab8e212943a4b4863Anders Carlsson } 1213a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 122db8918a98ff001d0c37abf41bc62364595340035Chris Lattner inline bool operator<(const APSInt& RHS) const { 123db8918a98ff001d0c37abf41bc62364595340035Chris Lattner assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 124db8918a98ff001d0c37abf41bc62364595340035Chris Lattner return IsUnsigned ? ult(RHS) : slt(RHS); 125db8918a98ff001d0c37abf41bc62364595340035Chris Lattner } 126db8918a98ff001d0c37abf41bc62364595340035Chris Lattner inline bool operator>(const APSInt& RHS) const { 127db8918a98ff001d0c37abf41bc62364595340035Chris Lattner assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 128db8918a98ff001d0c37abf41bc62364595340035Chris Lattner return IsUnsigned ? ugt(RHS) : sgt(RHS); 129db8918a98ff001d0c37abf41bc62364595340035Chris Lattner } 130db8918a98ff001d0c37abf41bc62364595340035Chris Lattner inline bool operator<=(const APSInt& RHS) const { 131db8918a98ff001d0c37abf41bc62364595340035Chris Lattner assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 132db8918a98ff001d0c37abf41bc62364595340035Chris Lattner return IsUnsigned ? ule(RHS) : sle(RHS); 133db8918a98ff001d0c37abf41bc62364595340035Chris Lattner } 134db8918a98ff001d0c37abf41bc62364595340035Chris Lattner inline bool operator>=(const APSInt& RHS) const { 135db8918a98ff001d0c37abf41bc62364595340035Chris Lattner assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 136db8918a98ff001d0c37abf41bc62364595340035Chris Lattner return IsUnsigned ? uge(RHS) : sge(RHS); 137db8918a98ff001d0c37abf41bc62364595340035Chris Lattner } 1385e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu inline bool operator==(const APSInt& RHS) const { 1395e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 1405e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu return eq(RHS); 1415e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu } 1425e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu inline bool operator!=(const APSInt& RHS) const { 1435e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu return !((*this) == RHS); 1445e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu } 145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool operator==(int64_t RHS) const { 147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return compareValues(*this, get(RHS)) == 0; 148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool operator!=(int64_t RHS) const { 150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return compareValues(*this, get(RHS)) != 0; 151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool operator<=(int64_t RHS) const { 153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return compareValues(*this, get(RHS)) <= 0; 154ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 155ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool operator>=(int64_t RHS) const { 156ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return compareValues(*this, get(RHS)) >= 0; 157ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool operator<(int64_t RHS) const { 159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return compareValues(*this, get(RHS)) < 0; 160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool operator>(int64_t RHS) const { 162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return compareValues(*this, get(RHS)) > 0; 1635e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu } 1643a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 165cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek // The remaining operators just wrap the logic of APInt, but retain the 166cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek // signedness information. 1673a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 16886383e1f7cc8c31eafc6e3d8a67ce6f23d1bce63Ted Kremenek APSInt operator<<(unsigned Bits) const { 16986383e1f7cc8c31eafc6e3d8a67ce6f23d1bce63Ted Kremenek return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned); 1703a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman } 171cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt& operator<<=(unsigned Amt) { 172cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek *this = *this << Amt; 173cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return *this; 174cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 1753a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 176cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt& operator++() { 1772adf8ccbf0611df6393c30737d87faaf38cdcd0cJakub Staszak ++(static_cast<APInt&>(*this)); 178cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return *this; 179cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 180cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt& operator--() { 1812adf8ccbf0611df6393c30737d87faaf38cdcd0cJakub Staszak --(static_cast<APInt&>(*this)); 182cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return *this; 183cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 184cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt operator++(int) { 185cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return APSInt(++static_cast<APInt&>(*this), IsUnsigned); 186cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 187cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt operator--(int) { 188cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return APSInt(--static_cast<APInt&>(*this), IsUnsigned); 1893a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman } 190cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt operator-() const { 191cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return APSInt(-static_cast<const APInt&>(*this), IsUnsigned); 1923a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman } 193cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt& operator+=(const APSInt& RHS) { 194cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 195cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek static_cast<APInt&>(*this) += RHS; 196cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return *this; 1973a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman } 198cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt& operator-=(const APSInt& RHS) { 199cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 200cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek static_cast<APInt&>(*this) -= RHS; 201cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return *this; 2023a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman } 203cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt& operator*=(const APSInt& RHS) { 204cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 205cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek static_cast<APInt&>(*this) *= RHS; 206cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return *this; 207cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 208cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt& operator&=(const APSInt& RHS) { 209cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 210cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek static_cast<APInt&>(*this) &= RHS; 211cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return *this; 212cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 213cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt& operator|=(const APSInt& RHS) { 214cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 215cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek static_cast<APInt&>(*this) |= RHS; 216cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return *this; 217cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 218cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt& operator^=(const APSInt& RHS) { 219cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 220cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek static_cast<APInt&>(*this) ^= RHS; 221cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return *this; 222cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 223cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek 2243a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman APSInt operator&(const APSInt& RHS) const { 225cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 226cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned); 227cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 228b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer APSInt LLVM_ATTRIBUTE_UNUSED_RESULT And(const APSInt& RHS) const { 229cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return this->operator&(RHS); 230cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 2313a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 2323a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman APSInt operator|(const APSInt& RHS) const { 233cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 234cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned); 235cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 236b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer APSInt LLVM_ATTRIBUTE_UNUSED_RESULT Or(const APSInt& RHS) const { 237cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return this->operator|(RHS); 238cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 2393a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 2403a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 2413a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman APSInt operator^(const APSInt& RHS) const { 242cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 243cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned); 244cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 245b69143c6a9bfc969e7c95bbd48b83bb962086070Benjamin Kramer APSInt LLVM_ATTRIBUTE_UNUSED_RESULT Xor(const APSInt& RHS) const { 246cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return this->operator^(RHS); 2473a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman } 2483a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 249cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt operator*(const APSInt& RHS) const { 250cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 251cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned); 252cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 2533a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman APSInt operator+(const APSInt& RHS) const { 254cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 255cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned); 256cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 257cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek APSInt operator-(const APSInt& RHS) const { 258cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); 259cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned); 260cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 2613a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman APSInt operator~() const { 262cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek return APSInt(~static_cast<const APInt&>(*this), IsUnsigned); 263cadf873c83ad7ea7c638e6d98fc5f20752702b03Ted Kremenek } 2643a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 265ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek /// getMaxValue - Return the APSInt representing the maximum integer value 266ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek /// with the given bit width and signedness. 267072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner static APSInt getMaxValue(uint32_t numBits, bool Unsigned) { 268072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner return APSInt(Unsigned ? APInt::getMaxValue(numBits) 269072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner : APInt::getSignedMaxValue(numBits), Unsigned); 270ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek } 2713a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 272ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek /// getMinValue - Return the APSInt representing the minimum integer value 273ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek /// with the given bit width and signedness. 274072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner static APSInt getMinValue(uint32_t numBits, bool Unsigned) { 275072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner return APSInt(Unsigned ? APInt::getMinValue(numBits) 276072e99ef9bd7e731c06716d8a21f630e429ddd82Chris Lattner : APInt::getSignedMinValue(numBits), Unsigned); 277ed871805f718f6bd0f9f32888b82c66545fc1157Ted Kremenek } 2783a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 2795449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher /// \brief Determine if two APSInts have the same value, zero- or 2805449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher /// sign-extending as needed. 2815449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher static bool isSameValue(const APSInt &I1, const APSInt &I2) { 282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return !compareValues(I1, I2); 283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// \brief Compare underlying values of two numbers. 286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static int compareValues(const APSInt &I1, const APSInt &I2) { 2875449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned()) 288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return I1 == I2 ? 0 : I1 > I2 ? 1 : -1; 2895449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher 2905449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher // Check for a bit-width mismatch. 2915449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher if (I1.getBitWidth() > I2.getBitWidth()) 292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return compareValues(I1, I2.extend(I1.getBitWidth())); 2935449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher else if (I2.getBitWidth() > I1.getBitWidth()) 294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return compareValues(I1.extend(I2.getBitWidth()), I2); 2955449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher 29637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We have a signedness mismatch. Check for negative values and do an 297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // unsigned compare if both are positive. 298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (I1.isSigned()) { 299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(!I2.isSigned() && "Expected signed mismatch"); 300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (I1.isNegative()) 301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return -1; 302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(I2.isSigned() && "Expected signed mismatch"); 304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (I2.isNegative()) 305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 1; 306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 3075449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher 308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return I1.eq(I2) ? 0 : I1.ugt(I2) ? 1 : -1; 3095449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher } 3105449a1db40b75586c1daf70a14396295e7b3fe24Eric Christopher 311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static APSInt get(int64_t X) { return APSInt(APInt(64, X), false); } 312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static APSInt getUnsigned(uint64_t X) { return APSInt(APInt(64, X), true); } 313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 3144048a082847cea72431aa8235f54941ed064913bTed Kremenek /// Profile - Used to insert APSInt objects, or objects that contain APSInt 3154048a082847cea72431aa8235f54941ed064913bTed Kremenek /// objects, into FoldingSets. 3164048a082847cea72431aa8235f54941ed064913bTed Kremenek void Profile(FoldingSetNodeID& ID) const; 317db8918a98ff001d0c37abf41bc62364595340035Chris Lattner}; 3183a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator==(int64_t V1, const APSInt &V2) { return V2 == V1; } 320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator!=(int64_t V1, const APSInt &V2) { return V2 != V1; } 321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator<=(int64_t V1, const APSInt &V2) { return V2 >= V1; } 322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator>=(int64_t V1, const APSInt &V2) { return V2 <= V1; } 323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator<(int64_t V1, const APSInt &V2) { return V2 > V1; } 324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline bool operator>(int64_t V1, const APSInt &V2) { return V2 < V1; } 3255e31044e119c75899b91ca97eb4d8ba786afc01cRichard Trieu 326944fac71e082cc2664cc71b4d3f6c72bab7143fbChris Lattnerinline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) { 327fad86b003a839cef40ec8ce8408322f4913368caChris Lattner I.print(OS, I.isSigned()); 328fad86b003a839cef40ec8ce8408322f4913368caChris Lattner return OS; 329fad86b003a839cef40ec8ce8408322f4913368caChris Lattner} 3303a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman 331db8918a98ff001d0c37abf41bc62364595340035Chris Lattner} // end namespace llvm 332db8918a98ff001d0c37abf41bc62364595340035Chris Lattner 333db8918a98ff001d0c37abf41bc62364595340035Chris Lattner#endif 334