1 //===-- Scalar.h ------------------------------------------------*- 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 #ifndef LLDB_UTILITY_SCALAR_H 11 #define LLDB_UTILITY_SCALAR_H 12 13 #include "lldb/Utility/Status.h" 14 #include "lldb/lldb-enumerations.h" 15 #include "lldb/lldb-private-types.h" 16 #include "llvm/ADT/APFloat.h" 17 #include "llvm/ADT/APInt.h" 18 #include <cstddef> 19 #include <cstdint> 20 21 namespace lldb_private { 22 class DataExtractor; 23 class Stream; 24 } // namespace lldb_private 25 26 #define NUM_OF_WORDS_INT128 2 27 #define BITWIDTH_INT128 128 28 #define NUM_OF_WORDS_INT256 4 29 #define BITWIDTH_INT256 256 30 31 namespace lldb_private { 32 33 //---------------------------------------------------------------------- 34 // A class designed to hold onto values and their corresponding types. 35 // Operators are defined and Scalar objects will correctly promote their types 36 // and values before performing these operations. Type promotion currently 37 // follows the ANSI C type promotion rules. 38 //---------------------------------------------------------------------- 39 class Scalar { 40 public: 41 enum Type { 42 e_void = 0, 43 e_sint, 44 e_uint, 45 e_slong, 46 e_ulong, 47 e_slonglong, 48 e_ulonglong, 49 e_sint128, 50 e_uint128, 51 e_sint256, 52 e_uint256, 53 e_float, 54 e_double, 55 e_long_double 56 }; 57 58 //------------------------------------------------------------------ 59 // Constructors and Destructors 60 //------------------------------------------------------------------ 61 Scalar(); Scalar(int v)62 Scalar(int v) : m_type(e_sint), m_float((float)0) { 63 m_integer = llvm::APInt(sizeof(int) * 8, v, true); 64 } Scalar(unsigned int v)65 Scalar(unsigned int v) : m_type(e_uint), m_float((float)0) { 66 m_integer = llvm::APInt(sizeof(int) * 8, v); 67 } Scalar(long v)68 Scalar(long v) : m_type(e_slong), m_float((float)0) { 69 m_integer = llvm::APInt(sizeof(long) * 8, v, true); 70 } Scalar(unsigned long v)71 Scalar(unsigned long v) : m_type(e_ulong), m_float((float)0) { 72 m_integer = llvm::APInt(sizeof(long) * 8, v); 73 } Scalar(long long v)74 Scalar(long long v) : m_type(e_slonglong), m_float((float)0) { 75 m_integer = llvm::APInt(sizeof(long long) * 8, v, true); 76 } Scalar(unsigned long long v)77 Scalar(unsigned long long v) : m_type(e_ulonglong), m_float((float)0) { 78 m_integer = llvm::APInt(sizeof(long long) * 8, v); 79 } Scalar(float v)80 Scalar(float v) : m_type(e_float), m_float(v) { m_float = llvm::APFloat(v); } Scalar(double v)81 Scalar(double v) : m_type(e_double), m_float(v) { 82 m_float = llvm::APFloat(v); 83 } Scalar(long double v,bool ieee_quad)84 Scalar(long double v, bool ieee_quad) 85 : m_type(e_long_double), m_float((float)0), m_ieee_quad(ieee_quad) { 86 if (ieee_quad) 87 m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), 88 llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, 89 ((type128 *)&v)->x)); 90 else 91 m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), 92 llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, 93 ((type128 *)&v)->x)); 94 } Scalar(llvm::APInt v)95 Scalar(llvm::APInt v) : m_type(), m_float((float)0) { 96 m_integer = llvm::APInt(v); 97 switch (m_integer.getBitWidth()) { 98 case 8: 99 case 16: 100 case 32: 101 if (m_integer.isSignedIntN(sizeof(sint_t) * 8)) 102 m_type = e_sint; 103 else 104 m_type = e_uint; 105 break; 106 case 64: 107 if (m_integer.isSignedIntN(sizeof(slonglong_t) * 8)) 108 m_type = e_slonglong; 109 else 110 m_type = e_ulonglong; 111 break; 112 case 128: 113 if (m_integer.isSignedIntN(BITWIDTH_INT128)) 114 m_type = e_sint128; 115 else 116 m_type = e_uint128; 117 break; 118 case 256: 119 if (m_integer.isSignedIntN(BITWIDTH_INT256)) 120 m_type = e_sint256; 121 else 122 m_type = e_uint256; 123 break; 124 } 125 } 126 Scalar(const Scalar &rhs); 127 // Scalar(const RegisterValue& reg_value); 128 virtual ~Scalar(); 129 130 bool SignExtend(uint32_t bit_pos); 131 132 bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset); 133 134 bool SetBit(uint32_t bit); 135 136 bool ClearBit(uint32_t bit); 137 138 const void *GetBytes() const; 139 140 size_t GetByteSize() const; 141 142 bool GetData(DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const; 143 144 size_t GetAsMemoryData(void *dst, size_t dst_len, 145 lldb::ByteOrder dst_byte_order, Status &error) const; 146 147 bool IsZero() const; 148 Clear()149 void Clear() { 150 m_type = e_void; 151 m_integer.clearAllBits(); 152 } 153 154 const char *GetTypeAsCString() const; 155 156 void GetValue(Stream *s, bool show_type) const; 157 IsValid()158 bool IsValid() const { 159 return (m_type >= e_sint) && (m_type <= e_long_double); 160 } 161 162 bool Promote(Scalar::Type type); 163 164 bool MakeSigned(); 165 166 bool MakeUnsigned(); 167 168 static const char *GetValueTypeAsCString(Scalar::Type value_type); 169 170 static Scalar::Type 171 GetValueTypeForSignedIntegerWithByteSize(size_t byte_size); 172 173 static Scalar::Type 174 GetValueTypeForUnsignedIntegerWithByteSize(size_t byte_size); 175 176 static Scalar::Type GetValueTypeForFloatWithByteSize(size_t byte_size); 177 178 //---------------------------------------------------------------------- 179 // All operators can benefits from the implicit conversions that will happen 180 // automagically by the compiler, so no temporary objects will need to be 181 // created. As a result, we currently don't need a variety of overloaded set 182 // value accessors. 183 //---------------------------------------------------------------------- 184 Scalar &operator=(const int i); 185 Scalar &operator=(unsigned int v); 186 Scalar &operator=(long v); 187 Scalar &operator=(unsigned long v); 188 Scalar &operator=(long long v); 189 Scalar &operator=(unsigned long long v); 190 Scalar &operator=(float v); 191 Scalar &operator=(double v); 192 Scalar &operator=(long double v); 193 Scalar &operator=(llvm::APInt v); 194 Scalar &operator=(const Scalar &rhs); // Assignment operator 195 Scalar &operator+=(const Scalar &rhs); 196 Scalar &operator<<=(const Scalar &rhs); // Shift left 197 Scalar &operator>>=(const Scalar &rhs); // Shift right (arithmetic) 198 Scalar &operator&=(const Scalar &rhs); 199 200 //---------------------------------------------------------------------- 201 // Shifts the current value to the right without maintaining the current sign 202 // of the value (if it is signed). 203 //---------------------------------------------------------------------- 204 bool ShiftRightLogical(const Scalar &rhs); // Returns true on success 205 206 //---------------------------------------------------------------------- 207 // Takes the absolute value of the current value if it is signed, else the 208 // value remains unchanged. Returns false if the contained value has a void 209 // type. 210 //---------------------------------------------------------------------- 211 bool AbsoluteValue(); // Returns true on success 212 //---------------------------------------------------------------------- 213 // Negates the current value (even for unsigned values). Returns false if the 214 // contained value has a void type. 215 //---------------------------------------------------------------------- 216 bool UnaryNegate(); // Returns true on success 217 //---------------------------------------------------------------------- 218 // Inverts all bits in the current value as long as it isn't void or a 219 // float/double/long double type. Returns false if the contained value has a 220 // void/float/double/long double type, else the value is inverted and true is 221 // returned. 222 //---------------------------------------------------------------------- 223 bool OnesComplement(); // Returns true on success 224 225 //---------------------------------------------------------------------- 226 // Access the type of the current value. 227 //---------------------------------------------------------------------- GetType()228 Scalar::Type GetType() const { return m_type; } 229 230 //---------------------------------------------------------------------- 231 // Returns a casted value of the current contained data without modifying the 232 // current value. FAIL_VALUE will be returned if the type of the value is 233 // void or invalid. 234 //---------------------------------------------------------------------- 235 int SInt(int fail_value = 0) const; 236 237 unsigned char UChar(unsigned char fail_value = 0) const; 238 239 signed char SChar(char fail_value = 0) const; 240 241 unsigned short UShort(unsigned short fail_value = 0) const; 242 243 short SShort(short fail_value = 0) const; 244 245 unsigned int UInt(unsigned int fail_value = 0) const; 246 247 long SLong(long fail_value = 0) const; 248 249 unsigned long ULong(unsigned long fail_value = 0) const; 250 251 long long SLongLong(long long fail_value = 0) const; 252 253 unsigned long long ULongLong(unsigned long long fail_value = 0) const; 254 255 llvm::APInt SInt128(llvm::APInt &fail_value) const; 256 257 llvm::APInt UInt128(const llvm::APInt &fail_value) const; 258 259 llvm::APInt SInt256(llvm::APInt &fail_value) const; 260 261 llvm::APInt UInt256(const llvm::APInt &fail_value) const; 262 263 float Float(float fail_value = 0.0f) const; 264 265 double Double(double fail_value = 0.0) const; 266 267 long double LongDouble(long double fail_value = 0.0) const; 268 269 Status SetValueFromCString(const char *s, lldb::Encoding encoding, 270 size_t byte_size); 271 272 Status SetValueFromData(DataExtractor &data, lldb::Encoding encoding, 273 size_t byte_size); 274 UIntValueIsValidForSize(uint64_t uval64,size_t total_byte_size)275 static bool UIntValueIsValidForSize(uint64_t uval64, size_t total_byte_size) { 276 if (total_byte_size > 8) 277 return false; 278 279 if (total_byte_size == 8) 280 return true; 281 282 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1; 283 return uval64 <= max; 284 } 285 SIntValueIsValidForSize(int64_t sval64,size_t total_byte_size)286 static bool SIntValueIsValidForSize(int64_t sval64, size_t total_byte_size) { 287 if (total_byte_size > 8) 288 return false; 289 290 if (total_byte_size == 8) 291 return true; 292 293 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1; 294 const int64_t min = ~(max); 295 return min <= sval64 && sval64 <= max; 296 } 297 298 protected: 299 typedef char schar_t; 300 typedef unsigned char uchar_t; 301 typedef short sshort_t; 302 typedef unsigned short ushort_t; 303 typedef int sint_t; 304 typedef unsigned int uint_t; 305 typedef long slong_t; 306 typedef unsigned long ulong_t; 307 typedef long long slonglong_t; 308 typedef unsigned long long ulonglong_t; 309 typedef float float_t; 310 typedef double double_t; 311 typedef long double long_double_t; 312 313 //------------------------------------------------------------------ 314 // Classes that inherit from Scalar can see and modify these 315 //------------------------------------------------------------------ 316 Scalar::Type m_type; 317 llvm::APInt m_integer; 318 llvm::APFloat m_float; 319 bool m_ieee_quad = false; 320 321 private: 322 friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs); 323 friend const Scalar operator-(const Scalar &lhs, const Scalar &rhs); 324 friend const Scalar operator/(const Scalar &lhs, const Scalar &rhs); 325 friend const Scalar operator*(const Scalar &lhs, const Scalar &rhs); 326 friend const Scalar operator&(const Scalar &lhs, const Scalar &rhs); 327 friend const Scalar operator|(const Scalar &lhs, const Scalar &rhs); 328 friend const Scalar operator%(const Scalar &lhs, const Scalar &rhs); 329 friend const Scalar operator^(const Scalar &lhs, const Scalar &rhs); 330 friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs); 331 friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs); 332 friend bool operator==(const Scalar &lhs, const Scalar &rhs); 333 friend bool operator!=(const Scalar &lhs, const Scalar &rhs); 334 friend bool operator<(const Scalar &lhs, const Scalar &rhs); 335 friend bool operator<=(const Scalar &lhs, const Scalar &rhs); 336 friend bool operator>(const Scalar &lhs, const Scalar &rhs); 337 friend bool operator>=(const Scalar &lhs, const Scalar &rhs); 338 }; 339 340 //---------------------------------------------------------------------- 341 // Split out the operators into a format where the compiler will be able to 342 // implicitly convert numbers into Scalar objects. 343 // 344 // This allows code like: 345 // Scalar two(2); 346 // Scalar four = two * 2; 347 // Scalar eight = 2 * four; // This would cause an error if the 348 // // operator* was implemented as a 349 // // member function. 350 // SEE: 351 // Item 19 of "Effective C++ Second Edition" by Scott Meyers 352 // Differentiate among members functions, non-member functions, and 353 // friend functions 354 //---------------------------------------------------------------------- 355 const Scalar operator+(const Scalar &lhs, const Scalar &rhs); 356 const Scalar operator-(const Scalar &lhs, const Scalar &rhs); 357 const Scalar operator/(const Scalar &lhs, const Scalar &rhs); 358 const Scalar operator*(const Scalar &lhs, const Scalar &rhs); 359 const Scalar operator&(const Scalar &lhs, const Scalar &rhs); 360 const Scalar operator|(const Scalar &lhs, const Scalar &rhs); 361 const Scalar operator%(const Scalar &lhs, const Scalar &rhs); 362 const Scalar operator^(const Scalar &lhs, const Scalar &rhs); 363 const Scalar operator<<(const Scalar &lhs, const Scalar &rhs); 364 const Scalar operator>>(const Scalar &lhs, const Scalar &rhs); 365 bool operator==(const Scalar &lhs, const Scalar &rhs); 366 bool operator!=(const Scalar &lhs, const Scalar &rhs); 367 bool operator<(const Scalar &lhs, const Scalar &rhs); 368 bool operator<=(const Scalar &lhs, const Scalar &rhs); 369 bool operator>(const Scalar &lhs, const Scalar &rhs); 370 bool operator>=(const Scalar &lhs, const Scalar &rhs); 371 372 } // namespace lldb_private 373 374 #endif // LLDB_UTILITY_SCALAR_H 375