Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

312 lines
9.7 KiB

  1. //===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the APSInt class, which is a simple class that
  11. // represents an arbitrary sized integer that knows its signedness.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_ADT_APSINT_H
  15. #define LLVM_ADT_APSINT_H
  16. #include "llvm/ADT/APInt.h"
  17. namespace llvm {
  18. class APSInt : public APInt {
  19. bool IsUnsigned;
  20. public:
  21. /// Default constructor that creates an uninitialized APInt.
  22. explicit APSInt() : IsUnsigned(false) {}
  23. /// APSInt ctor - Create an APSInt with the specified width, default to
  24. /// unsigned.
  25. explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
  26. : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
  27. explicit APSInt(const APInt &I, bool isUnsigned = true)
  28. : APInt(I), IsUnsigned(isUnsigned) {}
  29. APSInt &operator=(const APSInt &RHS) {
  30. APInt::operator=(RHS);
  31. IsUnsigned = RHS.IsUnsigned;
  32. return *this;
  33. }
  34. APSInt &operator=(const APInt &RHS) {
  35. // Retain our current sign.
  36. APInt::operator=(RHS);
  37. return *this;
  38. }
  39. APSInt &operator=(uint64_t RHS) {
  40. // Retain our current sign.
  41. APInt::operator=(RHS);
  42. return *this;
  43. }
  44. // Query sign information.
  45. bool isSigned() const { return !IsUnsigned; }
  46. bool isUnsigned() const { return IsUnsigned; }
  47. void setIsUnsigned(bool Val) { IsUnsigned = Val; }
  48. void setIsSigned(bool Val) { IsUnsigned = !Val; }
  49. /// toString - Append this APSInt to the specified SmallString.
  50. void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
  51. APInt::toString(Str, Radix, isSigned());
  52. }
  53. /// toString - Converts an APInt to a std::string. This is an inefficient
  54. /// method, your should prefer passing in a SmallString instead.
  55. std::string toString(unsigned Radix) const {
  56. return APInt::toString(Radix, isSigned());
  57. }
  58. using APInt::toString;
  59. APSInt trunc(uint32_t width) const {
  60. return APSInt(APInt::trunc(width), IsUnsigned);
  61. }
  62. APSInt extend(uint32_t width) const {
  63. if (IsUnsigned)
  64. return APSInt(zext(width), IsUnsigned);
  65. else
  66. return APSInt(sext(width), IsUnsigned);
  67. }
  68. APSInt extOrTrunc(uint32_t width) const {
  69. if (IsUnsigned)
  70. return APSInt(zextOrTrunc(width), IsUnsigned);
  71. else
  72. return APSInt(sextOrTrunc(width), IsUnsigned);
  73. }
  74. const APSInt &operator%=(const APSInt &RHS) {
  75. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  76. if (IsUnsigned)
  77. *this = urem(RHS);
  78. else
  79. *this = srem(RHS);
  80. return *this;
  81. }
  82. const APSInt &operator/=(const APSInt &RHS) {
  83. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  84. if (IsUnsigned)
  85. *this = udiv(RHS);
  86. else
  87. *this = sdiv(RHS);
  88. return *this;
  89. }
  90. APSInt operator%(const APSInt &RHS) const {
  91. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  92. return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
  93. }
  94. APSInt operator/(const APSInt &RHS) const {
  95. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  96. return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
  97. }
  98. APSInt operator>>(unsigned Amt) const {
  99. return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
  100. }
  101. APSInt& operator>>=(unsigned Amt) {
  102. *this = *this >> Amt;
  103. return *this;
  104. }
  105. inline bool operator<(const APSInt& RHS) const {
  106. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  107. return IsUnsigned ? ult(RHS) : slt(RHS);
  108. }
  109. inline bool operator>(const APSInt& RHS) const {
  110. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  111. return IsUnsigned ? ugt(RHS) : sgt(RHS);
  112. }
  113. inline bool operator<=(const APSInt& RHS) const {
  114. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  115. return IsUnsigned ? ule(RHS) : sle(RHS);
  116. }
  117. inline bool operator>=(const APSInt& RHS) const {
  118. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  119. return IsUnsigned ? uge(RHS) : sge(RHS);
  120. }
  121. inline bool operator==(const APSInt& RHS) const {
  122. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  123. return eq(RHS);
  124. }
  125. inline bool operator==(int64_t RHS) const {
  126. return isSameValue(*this, APSInt(APInt(64, RHS), true));
  127. }
  128. inline bool operator!=(const APSInt& RHS) const {
  129. return !((*this) == RHS);
  130. }
  131. inline bool operator!=(int64_t RHS) const {
  132. return !((*this) == RHS);
  133. }
  134. // The remaining operators just wrap the logic of APInt, but retain the
  135. // signedness information.
  136. APSInt operator<<(unsigned Bits) const {
  137. return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
  138. }
  139. APSInt& operator<<=(unsigned Amt) {
  140. *this = *this << Amt;
  141. return *this;
  142. }
  143. APSInt& operator++() {
  144. ++(static_cast<APInt&>(*this));
  145. return *this;
  146. }
  147. APSInt& operator--() {
  148. --(static_cast<APInt&>(*this));
  149. return *this;
  150. }
  151. APSInt operator++(int) {
  152. return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
  153. }
  154. APSInt operator--(int) {
  155. return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
  156. }
  157. APSInt operator-() const {
  158. return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
  159. }
  160. APSInt& operator+=(const APSInt& RHS) {
  161. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  162. static_cast<APInt&>(*this) += RHS;
  163. return *this;
  164. }
  165. APSInt& operator-=(const APSInt& RHS) {
  166. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  167. static_cast<APInt&>(*this) -= RHS;
  168. return *this;
  169. }
  170. APSInt& operator*=(const APSInt& RHS) {
  171. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  172. static_cast<APInt&>(*this) *= RHS;
  173. return *this;
  174. }
  175. APSInt& operator&=(const APSInt& RHS) {
  176. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  177. static_cast<APInt&>(*this) &= RHS;
  178. return *this;
  179. }
  180. APSInt& operator|=(const APSInt& RHS) {
  181. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  182. static_cast<APInt&>(*this) |= RHS;
  183. return *this;
  184. }
  185. APSInt& operator^=(const APSInt& RHS) {
  186. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  187. static_cast<APInt&>(*this) ^= RHS;
  188. return *this;
  189. }
  190. APSInt operator&(const APSInt& RHS) const {
  191. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  192. return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
  193. }
  194. APSInt And(const APSInt& RHS) const {
  195. return this->operator&(RHS);
  196. }
  197. APSInt operator|(const APSInt& RHS) const {
  198. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  199. return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
  200. }
  201. APSInt Or(const APSInt& RHS) const {
  202. return this->operator|(RHS);
  203. }
  204. APSInt operator^(const APSInt& RHS) const {
  205. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  206. return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
  207. }
  208. APSInt Xor(const APSInt& RHS) const {
  209. return this->operator^(RHS);
  210. }
  211. APSInt operator*(const APSInt& RHS) const {
  212. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  213. return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
  214. }
  215. APSInt operator+(const APSInt& RHS) const {
  216. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  217. return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
  218. }
  219. APSInt operator-(const APSInt& RHS) const {
  220. assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
  221. return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
  222. }
  223. APSInt operator~() const {
  224. return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
  225. }
  226. /// getMaxValue - Return the APSInt representing the maximum integer value
  227. /// with the given bit width and signedness.
  228. static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
  229. return APSInt(Unsigned ? APInt::getMaxValue(numBits)
  230. : APInt::getSignedMaxValue(numBits), Unsigned);
  231. }
  232. /// getMinValue - Return the APSInt representing the minimum integer value
  233. /// with the given bit width and signedness.
  234. static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
  235. return APSInt(Unsigned ? APInt::getMinValue(numBits)
  236. : APInt::getSignedMinValue(numBits), Unsigned);
  237. }
  238. /// \brief Determine if two APSInts have the same value, zero- or
  239. /// sign-extending as needed.
  240. static bool isSameValue(const APSInt &I1, const APSInt &I2) {
  241. if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
  242. return I1 == I2;
  243. // Check for a bit-width mismatch.
  244. if (I1.getBitWidth() > I2.getBitWidth())
  245. return isSameValue(I1, I2.extend(I1.getBitWidth()));
  246. else if (I2.getBitWidth() > I1.getBitWidth())
  247. return isSameValue(I1.extend(I2.getBitWidth()), I2);
  248. // We have a signedness mismatch. Turn the signed value into an unsigned
  249. // value.
  250. if (I1.isSigned()) {
  251. if (I1.isNegative())
  252. return false;
  253. return APSInt(I1, true) == I2;
  254. }
  255. if (I2.isNegative())
  256. return false;
  257. return I1 == APSInt(I2, true);
  258. }
  259. /// Profile - Used to insert APSInt objects, or objects that contain APSInt
  260. /// objects, into FoldingSets.
  261. void Profile(FoldingSetNodeID& ID) const;
  262. };
  263. inline bool operator==(int64_t V1, const APSInt& V2) {
  264. return V2 == V1;
  265. }
  266. inline bool operator!=(int64_t V1, const APSInt& V2) {
  267. return V2 != V1;
  268. }
  269. inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
  270. I.print(OS, I.isSigned());
  271. return OS;
  272. }
  273. } // end namespace llvm
  274. #endif