[LLDB] Use llvm::APInt and llvm::APFloat in Scalar and RegisterValue

Eliminated ENABLE_128_BIT_SUPPORT and union ValueData from Scalar.cpp and use llvm::APInt and llvm::APFloat for all integer and floating point types. Also used Scalar in RegisterValue.cpp

Reviewers: jaydeep, clayborg, jasonmolenda, ovyalov, emaste
Subscribers: tberghammer, ovyalov, emaste, mohit.bhakkad, nitesh.jain, bhushan
Differential: http://reviews.llvm.org/D10919
llvm-svn: 245216
This commit is contained in:
Sagar Thakur 2015-08-17 12:05:31 +00:00
parent e0c900ed05
commit ee3443e0d6
7 changed files with 1930 additions and 1395 deletions

View File

@ -19,8 +19,9 @@
#include "lldb/lldb-public.h"
#include "lldb/lldb-private.h"
#include "lldb/Host/Endian.h"
#include "llvm/ADT/APInt.h"
#include "lldb/Core/Scalar.h"
//#define ENABLE_128_BIT_SUPPORT 1
namespace lldb_private {
class RegisterValue
@ -37,9 +38,7 @@ namespace lldb_private {
eTypeUInt16,
eTypeUInt32,
eTypeUInt64,
#if defined (ENABLE_128_BIT_SUPPORT)
eTypeUInt128,
#endif
eTypeFloat,
eTypeDouble,
eTypeLongDouble,
@ -49,63 +48,62 @@ namespace lldb_private {
RegisterValue () :
m_type (eTypeInvalid)
{
m_scalar = (unsigned long)0;
}
explicit
RegisterValue (uint8_t inst) :
m_type (eTypeUInt8)
{
m_data.uint8 = inst;
m_scalar = inst;
}
explicit
RegisterValue (uint16_t inst) :
m_type (eTypeUInt16)
{
m_data.uint16 = inst;
m_scalar = inst;
}
explicit
RegisterValue (uint32_t inst) :
m_type (eTypeUInt32)
{
m_data.uint32 = inst;
m_scalar = inst;
}
explicit
RegisterValue (uint64_t inst) :
m_type (eTypeUInt64)
{
m_data.uint64 = inst;
m_scalar = inst;
}
#if defined (ENABLE_128_BIT_SUPPORT)
explicit
RegisterValue (__uint128_t inst) :
RegisterValue (llvm::APInt inst) :
m_type (eTypeUInt128)
{
m_data.uint128 = inst;
m_scalar = llvm::APInt(inst);
}
#endif
explicit
RegisterValue (float value) :
m_type (eTypeFloat)
{
m_data.ieee_float = value;
m_scalar = value;
}
explicit
RegisterValue (double value) :
m_type (eTypeDouble)
{
m_data.ieee_double = value;
m_scalar = value;
}
explicit
RegisterValue (long double value) :
m_type (eTypeLongDouble)
{
m_data.ieee_long_double = value;
m_scalar = value;
}
explicit
@ -167,7 +165,7 @@ namespace lldb_private {
{
if (success_ptr)
*success_ptr = true;
return m_data.uint8;
return m_scalar.UChar(fail_value);
}
if (success_ptr)
*success_ptr = true;
@ -183,10 +181,8 @@ namespace lldb_private {
uint64_t
GetAsUInt64 (uint64_t fail_value = UINT64_MAX, bool *success_ptr = NULL) const;
#if defined (ENABLE_128_BIT_SUPPORT)
__uint128_t
GetAsUInt128 (__uint128_t fail_value = ~((__uint128_t)0), bool *success_ptr = NULL) const;
#endif
llvm::APInt
GetAsUInt128 (llvm::APInt& fail_value, bool *success_ptr = NULL) const;
float
GetAsFloat (float fail_value = 0.0f, bool *success_ptr = NULL) const;
@ -219,95 +215,92 @@ namespace lldb_private {
operator = (uint8_t uint)
{
m_type = eTypeUInt8;
m_data.uint8 = uint;
m_scalar = uint;
}
void
operator = (uint16_t uint)
{
m_type = eTypeUInt16;
m_data.uint16 = uint;
m_scalar = uint;
}
void
operator = (uint32_t uint)
{
m_type = eTypeUInt32;
m_data.uint32 = uint;
m_scalar = uint;
}
void
operator = (uint64_t uint)
{
m_type = eTypeUInt64;
m_data.uint64 = uint;
m_scalar = uint;
}
#if defined (ENABLE_128_BIT_SUPPORT)
void
operator = (__uint128_t uint)
operator = (llvm::APInt uint)
{
m_type = eTypeUInt128;
m_data.uint128 = uint;
m_scalar = llvm::APInt(uint);
}
#endif
void
operator = (float f)
{
m_type = eTypeFloat;
m_data.ieee_float = f;
m_scalar = f;
}
void
operator = (double f)
{
m_type = eTypeDouble;
m_data.ieee_double = f;
m_scalar = f;
}
void
operator = (long double f)
{
m_type = eTypeLongDouble;
m_data.ieee_long_double = f;
m_scalar = f;
}
void
SetUInt8 (uint8_t uint)
{
m_type = eTypeUInt8;
m_data.uint8 = uint;
m_scalar = uint;
}
void
SetUInt16 (uint16_t uint)
{
m_type = eTypeUInt16;
m_data.uint16 = uint;
m_scalar = uint;
}
void
SetUInt32 (uint32_t uint, Type t = eTypeUInt32)
{
m_type = t;
m_data.uint32 = uint;
m_scalar = uint;
}
void
SetUInt64 (uint64_t uint, Type t = eTypeUInt64)
{
m_type = t;
m_data.uint64 = uint;
m_scalar = uint;
}
#if defined (ENABLE_128_BIT_SUPPORT)
void
SetUInt128 (__uint128_t uint)
SetUInt128 (llvm::APInt uint)
{
m_type = eTypeUInt128;
m_data.uint128 = uint;
m_scalar = llvm::APInt(uint);
}
#endif
bool
SetUInt (uint64_t uint, uint32_t byte_size);
@ -315,21 +308,21 @@ namespace lldb_private {
SetFloat (float f)
{
m_type = eTypeFloat;
m_data.ieee_float = f;
m_scalar = f;
}
void
SetDouble (double f)
{
m_type = eTypeDouble;
m_data.ieee_double = f;
m_scalar = f;
}
void
SetLongDouble (long double f)
{
m_type = eTypeLongDouble;
m_data.ieee_long_double = f;
m_scalar = f;
}
void
@ -367,7 +360,7 @@ namespace lldb_private {
GetByteOrder () const
{
if (m_type == eTypeBytes)
return m_data.buffer.byte_order;
return buffer.byte_order;
return lldb::endian::InlHostByteOrder();
}
@ -386,25 +379,13 @@ namespace lldb_private {
protected:
RegisterValue::Type m_type;
union
Scalar m_scalar;
struct
{
uint8_t uint8;
uint16_t uint16;
uint32_t uint32;
uint64_t uint64;
#if defined (ENABLE_128_BIT_SUPPORT)
__uint128_t uint128;
#endif
float ieee_float;
double ieee_double;
long double ieee_long_double;
struct
{
uint8_t bytes[kMaxRegisterByteSize]; // This must be big enough to hold any register for any supported target.
uint8_t length;
lldb::ByteOrder byte_order;
} buffer;
} m_data;
uint8_t bytes[kMaxRegisterByteSize]; // This must be big enough to hold any register for any supported target.
uint8_t length;
lldb::ByteOrder byte_order;
} buffer;
};
} // namespace lldb_private

View File

@ -11,6 +11,11 @@
#define liblldb_Scalar_h_
#include "lldb/lldb-private.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APFloat.h"
#define NUM_OF_WORDS_INT128 2
#define BITWIDTH_INT128 128
namespace lldb_private {
@ -34,22 +39,60 @@ public:
e_ulonglong,
e_float,
e_double,
e_long_double
e_long_double,
e_uint128,
e_sint128
};
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
Scalar();
Scalar(int v) : m_type(e_sint), m_data() { m_data.sint = v; }
Scalar(unsigned int v) : m_type(e_uint), m_data() { m_data.uint = v; }
Scalar(long v) : m_type(e_slong), m_data() { m_data.slong = v; }
Scalar(unsigned long v) : m_type(e_ulong), m_data() { m_data.ulong = v; }
Scalar(long long v) : m_type(e_slonglong), m_data() { m_data.slonglong = v; }
Scalar(unsigned long long v): m_type(e_ulonglong), m_data() { m_data.ulonglong = v; }
Scalar(float v) : m_type(e_float), m_data() { m_data.flt = v; }
Scalar(double v) : m_type(e_double), m_data() { m_data.dbl = v; }
Scalar(long double v) : m_type(e_long_double), m_data() { m_data.ldbl = v; }
Scalar(int v) : m_type(e_sint), m_float((float)0) { m_integer = llvm::APInt(sizeof(int) * 8, v, true);}
Scalar(unsigned int v) : m_type(e_uint), m_float((float)0) { m_integer = llvm::APInt(sizeof(int) * 8, v);}
Scalar(long v) : m_type(e_slong), m_float((float)0) { m_integer = llvm::APInt(sizeof(long) * 8, v, true);}
Scalar(unsigned long v) : m_type(e_ulong), m_float((float)0) { m_integer = llvm::APInt(sizeof(long) * 8, v);}
Scalar(long long v) : m_type(e_slonglong), m_float((float)0) { m_integer = llvm::APInt(sizeof(long long) * 8, v, true);}
Scalar(unsigned long long v): m_type(e_ulonglong), m_float((float)0) { m_integer = llvm::APInt(sizeof(long long) * 8, v);}
Scalar(float v) : m_type(e_float), m_float(v) { m_float = llvm::APFloat(v); }
Scalar(double v) : m_type(e_double), m_float(v) { m_float = llvm::APFloat(v); }
Scalar(long double v, bool ieee_quad)
: m_type(e_long_double), m_float((float)0), m_ieee_quad(ieee_quad)
{
if(ieee_quad)
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&v)->x));
else
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&v)->x));
}
Scalar(llvm::APInt v) :
m_type(),
m_float((float)0)
{
m_integer = llvm::APInt(v);
switch(m_integer.getBitWidth())
{
case 8:
case 16:
case 32:
if(m_integer.isSignedIntN(sizeof(sint_t) * 8))
m_type = e_sint;
else
m_type = e_uint;
break;
case 64:
if(m_integer.isSignedIntN(sizeof(slonglong_t) * 8))
m_type = e_slonglong;
else
m_type = e_ulonglong;
break;
case 128:
if(m_integer.isSignedIntN(BITWIDTH_INT128))
m_type = e_sint128;
else
m_type = e_uint128;
break;
}
}
Scalar(const Scalar& rhs);
//Scalar(const RegisterValue& reg_value);
virtual ~Scalar();
@ -61,15 +104,18 @@ public:
ExtractBitfield (uint32_t bit_size,
uint32_t bit_offset);
bool
SetBit(uint32_t bit);
bool
ClearBit(uint32_t bit);
void *
GetBytes() const;
size_t
GetByteSize() const;
static size_t
GetMaxByteSize()
{
return sizeof(ValueData);
}
bool
GetData (DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const;
@ -83,7 +129,7 @@ public:
IsZero() const;
void
Clear() { m_type = e_void; m_data.ulonglong = 0; }
Clear() { m_type = e_void; m_integer.clearAllBits(); }
const char *
GetTypeAsCString() const;
@ -133,6 +179,7 @@ public:
Scalar& operator= (float v);
Scalar& operator= (double v);
Scalar& operator= (long double v);
Scalar& operator= (llvm::APInt v);
Scalar& operator= (const Scalar& rhs); // Assignment operator
Scalar& operator+= (const Scalar& rhs);
Scalar& operator<<= (const Scalar& rhs); // Shift left
@ -174,6 +221,9 @@ public:
Scalar::Type
GetType() const { return m_type; }
void
SetType(const RegisterInfo*);
//----------------------------------------------------------------------
// Returns a casted value of the current contained data without
// modifying the current value. FAIL_VALUE will be returned if the type
@ -194,6 +244,18 @@ public:
unsigned long long
RawULongLong () const;
unsigned char
UChar(unsigned char fail_value = 0) const;
char
SChar(char fail_value = 0) const;
unsigned short
UShort(unsigned short fail_value = 0) const;
short
SShort(short fail_value = 0) const;
unsigned int
UInt(unsigned int fail_value = 0) const;
@ -209,6 +271,12 @@ public:
unsigned long long
ULongLong(unsigned long long fail_value = 0) const;
llvm::APInt
SInt128(llvm::APInt& fail_value) const;
llvm::APInt
UInt128(llvm::APInt& fail_value) const;
float
Float(float fail_value = 0.0f) const;
@ -255,6 +323,10 @@ public:
}
protected:
typedef char schar_t;
typedef unsigned char uchar_t;
typedef short sshort_t;
typedef unsigned short ushort_t;
typedef int sint_t;
typedef unsigned int uint_t;
typedef long slong_t;
@ -265,24 +337,13 @@ protected:
typedef double double_t;
typedef long double long_double_t;
union ValueData
{
int sint;
unsigned int uint;
long slong;
unsigned long ulong;
long long slonglong;
unsigned long long ulonglong;
float flt;
double dbl;
long double ldbl;
};
//------------------------------------------------------------------
// Classes that inherit from Scalar can see and modify these
//------------------------------------------------------------------
Scalar::Type m_type;
ValueData m_data;
llvm::APInt m_integer;
llvm::APFloat m_float;
bool m_ieee_quad = false;
private:
friend const Scalar operator+ (const Scalar& lhs, const Scalar& rhs);

View File

@ -101,6 +101,7 @@ public:
// Casts a vector, if valid, to an unsigned int of matching or largest supported size.
// Truncates to the beginning of the vector if required.
// Returns a default constructed Scalar if the Vector data is internally inconsistent.
llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)bytes)->x);
Scalar
GetAsScalar() const
{
@ -111,11 +112,7 @@ public:
else if (length == 2) scalar = *(const uint16_t *)bytes;
else if (length == 4) scalar = *(const uint32_t *)bytes;
else if (length == 8) scalar = *(const uint64_t *)bytes;
#if defined (ENABLE_128_BIT_SUPPORT)
else if (length >= 16) scalar = *(const __uint128_t *)bytes;
#else
else if (length >= 16) scalar = *(const uint64_t *)bytes;
#endif
else if (length >= 16) scalar = rhs;
}
return scalar;
}

View File

@ -102,6 +102,8 @@ namespace lldb_private
// pass it.
};
typedef struct type128 { uint64_t x[2]; } type128;
} // namespace lldb_private
#endif // #if defined(__cplusplus)

View File

@ -215,10 +215,10 @@ RegisterValue::SetFromMemoryData (const RegisterInfo *reg_info,
}
else if (value_type == eTypeBytes)
{
m_data.buffer.byte_order = src_byte_order;
buffer.byte_order = src_byte_order;
// Make sure to set the buffer length of the destination buffer to avoid
// problems due to uninitialized variables.
m_data.buffer.length = src_len;
// problems due to uninitalized variables.
buffer.length = src_len;
}
const uint32_t bytes_copied = src_data.CopyByteOrderedData (0, // src offset
@ -240,25 +240,23 @@ RegisterValue::GetScalarValue (Scalar &scalar) const
case eTypeInvalid: break;
case eTypeBytes:
{
switch (m_data.buffer.length)
switch (buffer.length)
{
default: break;
case 1: scalar = m_data.uint8; return true;
case 2: scalar = m_data.uint16; return true;
case 4: scalar = m_data.uint32; return true;
case 8: scalar = m_data.uint64; return true;
case 1: scalar = *(const uint8_t *)buffer.bytes; return true;
case 2: scalar = *(const uint16_t *)buffer.bytes; return true;
case 4: scalar = *(const uint32_t *)buffer.bytes; return true;
case 8: scalar = *(const uint64_t *)buffer.bytes; return true;
}
}
case eTypeUInt8: scalar = m_data.uint8; return true;
case eTypeUInt16: scalar = m_data.uint16; return true;
case eTypeUInt32: scalar = m_data.uint32; return true;
case eTypeUInt64: scalar = m_data.uint64; return true;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128: break;
#endif
case eTypeFloat: scalar = m_data.ieee_float; return true;
case eTypeDouble: scalar = m_data.ieee_double; return true;
case eTypeLongDouble: scalar = m_data.ieee_long_double; return true;
case eTypeUInt8:
case eTypeUInt16:
case eTypeUInt32:
case eTypeUInt64:
case eTypeUInt128:
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble: scalar = m_scalar; return true;
}
return false;
}
@ -289,10 +287,8 @@ RegisterValue::SetType (const RegisterInfo *reg_info)
m_type = eTypeUInt32;
else if (byte_size <= 8)
m_type = eTypeUInt64;
#if defined (ENABLE_128_BIT_SUPPORT)
else if (byte_size <= 16)
m_type = eTypeUInt128;
#endif
break;
case eEncodingIEEE754:
@ -308,6 +304,7 @@ RegisterValue::SetType (const RegisterInfo *reg_info)
m_type = eTypeBytes;
break;
}
m_scalar.SetType(reg_info);
return m_type;
}
@ -342,8 +339,9 @@ RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &sr
src_len = reg_info->byte_size;
// Zero out the value in case we get partial data...
memset (m_data.buffer.bytes, 0, sizeof (m_data.buffer.bytes));
memset (buffer.bytes, 0, sizeof (buffer.bytes));
type128 int128;
switch (SetType (reg_info))
{
case eTypeInvalid:
@ -353,33 +351,36 @@ RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &sr
case eTypeUInt16: SetUInt16 (src.GetMaxU32 (&src_offset, src_len)); break;
case eTypeUInt32: SetUInt32 (src.GetMaxU32 (&src_offset, src_len)); break;
case eTypeUInt64: SetUInt64 (src.GetMaxU64 (&src_offset, src_len)); break;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128:
{
__uint128_t data1 = src.GetU64 (&src_offset);
__uint128_t data2 = src.GetU64 (&src_offset);
if (src.GetByteSize() == eByteOrderBig)
SetUInt128 (data1 << 64 + data2);
{
int128.x[1] = src.GetU64 (&src_offset + 1);
int128.x[0] = src.GetU64 (&src_offset);
}
else
SetUInt128 (data2 << 64 + data1);
{
int128.x[0] = src.GetU64 (&src_offset);
int128.x[1] = src.GetU64 (&src_offset + 1);
}
SetUInt128 (llvm::APInt(128, 2, int128.x));
}
break;
#endif
case eTypeFloat: SetFloat (src.GetFloat (&src_offset)); break;
case eTypeDouble: SetDouble(src.GetDouble (&src_offset)); break;
case eTypeLongDouble: SetFloat (src.GetLongDouble (&src_offset)); break;
case eTypeBytes:
{
m_data.buffer.length = reg_info->byte_size;
m_data.buffer.byte_order = src.GetByteOrder();
assert (m_data.buffer.length <= kMaxRegisterByteSize);
if (m_data.buffer.length > kMaxRegisterByteSize)
m_data.buffer.length = kMaxRegisterByteSize;
buffer.length = reg_info->byte_size;
buffer.byte_order = src.GetByteOrder();
assert (buffer.length <= kMaxRegisterByteSize);
if (buffer.length > kMaxRegisterByteSize)
buffer.length = kMaxRegisterByteSize;
if (src.CopyByteOrderedData (src_offset, // offset within "src" to start extracting data
src_len, // src length
m_data.buffer.bytes, // dst buffer
m_data.buffer.length, // dst length
m_data.buffer.byte_order) == 0)// dst byte order
buffer.bytes, // dst buffer
buffer.length, // dst length
buffer.byte_order) == 0)// dst byte order
{
error.SetErrorString ("data copy failed data.");
return error;
@ -459,6 +460,9 @@ RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *va
}
bool success = false;
const uint32_t byte_size = reg_info->byte_size;
static float flt_val;
static double dbl_val;
static long double ldbl_val;
switch (reg_info->encoding)
{
case eEncodingInvalid:
@ -510,22 +514,31 @@ RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *va
case eEncodingIEEE754:
if (byte_size == sizeof (float))
{
if (::sscanf (value_str, "%f", &m_data.ieee_float) == 1)
if (::sscanf (value_str, "%f", &flt_val) == 1)
{
m_scalar = flt_val;
m_type = eTypeFloat;
}
else
error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
}
else if (byte_size == sizeof (double))
{
if (::sscanf (value_str, "%lf", &m_data.ieee_double) == 1)
if (::sscanf (value_str, "%lf", &dbl_val) == 1)
{
m_scalar = dbl_val;
m_type = eTypeDouble;
}
else
error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
}
else if (byte_size == sizeof (long double))
{
if (::sscanf (value_str, "%Lf", &m_data.ieee_long_double) == 1)
if (::sscanf (value_str, "%Lf", &ldbl_val) == 1)
{
m_scalar = ldbl_val;
m_type = eTypeLongDouble;
}
else
error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
}
@ -557,81 +570,11 @@ RegisterValue::SignExtend (uint32_t sign_bitpos)
break;
case eTypeUInt8:
if (sign_bitpos == (8-1))
return true;
else if (sign_bitpos < (8-1))
{
uint8_t sign_bit = 1u << sign_bitpos;
if (m_data.uint8 & sign_bit)
{
const uint8_t mask = ~(sign_bit) + 1u;
m_data.uint8 |= mask;
}
return true;
}
break;
case eTypeUInt16:
if (sign_bitpos == (16-1))
return true;
else if (sign_bitpos < (16-1))
{
uint16_t sign_bit = 1u << sign_bitpos;
if (m_data.uint16 & sign_bit)
{
const uint16_t mask = ~(sign_bit) + 1u;
m_data.uint16 |= mask;
}
return true;
}
break;
case eTypeUInt32:
if (sign_bitpos == (32-1))
return true;
else if (sign_bitpos < (32-1))
{
uint32_t sign_bit = 1u << sign_bitpos;
if (m_data.uint32 & sign_bit)
{
const uint32_t mask = ~(sign_bit) + 1u;
m_data.uint32 |= mask;
}
return true;
}
break;
case eTypeUInt64:
if (sign_bitpos == (64-1))
return true;
else if (sign_bitpos < (64-1))
{
uint64_t sign_bit = 1ull << sign_bitpos;
if (m_data.uint64 & sign_bit)
{
const uint64_t mask = ~(sign_bit) + 1ull;
m_data.uint64 |= mask;
}
return true;
}
break;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128:
if (sign_bitpos == (128-1))
return true;
else if (sign_bitpos < (128-1))
{
__uint128_t sign_bit = (__uint128_t)1u << sign_bitpos;
if (m_data.uint128 & sign_bit)
{
const uint128_t mask = ~(sign_bit) + 1u;
m_data.uint128 |= mask;
}
return true;
}
break;
#endif
return m_scalar.SignExtend(sign_bitpos);
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble:
@ -649,21 +592,19 @@ RegisterValue::CopyValue (const RegisterValue &rhs)
{
case eTypeInvalid:
return false;
case eTypeUInt8: m_data.uint8 = rhs.m_data.uint8; break;
case eTypeUInt16: m_data.uint16 = rhs.m_data.uint16; break;
case eTypeUInt32: m_data.uint32 = rhs.m_data.uint32; break;
case eTypeUInt64: m_data.uint64 = rhs.m_data.uint64; break;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128: m_data.uint128 = rhs.m_data.uint128; break;
#endif
case eTypeFloat: m_data.ieee_float = rhs.m_data.ieee_float; break;
case eTypeDouble: m_data.ieee_double = rhs.m_data.ieee_double; break;
case eTypeLongDouble: m_data.ieee_long_double = rhs.m_data.ieee_long_double; break;
case eTypeUInt8:
case eTypeUInt16:
case eTypeUInt32:
case eTypeUInt64:
case eTypeUInt128:
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble: m_scalar = rhs.m_scalar; break;
case eTypeBytes:
assert (rhs.m_data.buffer.length <= kMaxRegisterByteSize);
::memcpy (m_data.buffer.bytes, rhs.m_data.buffer.bytes, kMaxRegisterByteSize);
m_data.buffer.length = rhs.m_data.buffer.length;
m_data.buffer.byte_order = rhs.m_data.buffer.byte_order;
assert (rhs.buffer.length <= kMaxRegisterByteSize);
::memcpy (buffer.bytes, rhs.buffer.bytes, kMaxRegisterByteSize);
buffer.length = rhs.buffer.length;
buffer.byte_order = rhs.buffer.byte_order;
break;
}
return true;
@ -678,15 +619,15 @@ RegisterValue::GetAsUInt16 (uint16_t fail_value, bool *success_ptr) const
switch (m_type)
{
default: break;
case eTypeUInt8: return m_data.uint8;
case eTypeUInt16: return m_data.uint16;
case eTypeUInt8:
case eTypeUInt16: return m_scalar.UShort(fail_value);
case eTypeBytes:
{
switch (m_data.buffer.length)
switch (buffer.length)
{
default: break;
case 1: return m_data.uint8;
case 2: return m_data.uint16;
case 1:
case 2: return *(const uint16_t *)buffer.bytes;
}
}
break;
@ -704,29 +645,20 @@ RegisterValue::GetAsUInt32 (uint32_t fail_value, bool *success_ptr) const
switch (m_type)
{
default: break;
case eTypeUInt8: return m_data.uint8;
case eTypeUInt16: return m_data.uint16;
case eTypeUInt32: return m_data.uint32;
case eTypeUInt8:
case eTypeUInt16:
case eTypeUInt32:
case eTypeFloat:
if (sizeof(float) == sizeof(uint32_t))
return m_data.uint32;
break;
case eTypeDouble:
if (sizeof(double) == sizeof(uint32_t))
return m_data.uint32;
break;
case eTypeLongDouble:
if (sizeof(long double) == sizeof(uint32_t))
return m_data.uint32;
break;
case eTypeLongDouble: return m_scalar.UInt(fail_value);
case eTypeBytes:
{
switch (m_data.buffer.length)
switch (buffer.length)
{
default: break;
case 1: return m_data.uint8;
case 2: return m_data.uint16;
case 4: return m_data.uint32;
case 1:
case 2:
case 4: return *(const uint32_t *)buffer.bytes;
}
}
break;
@ -744,31 +676,22 @@ RegisterValue::GetAsUInt64 (uint64_t fail_value, bool *success_ptr) const
switch (m_type)
{
default: break;
case eTypeUInt8: return m_data.uint8;
case eTypeUInt16: return m_data.uint16;
case eTypeUInt32: return m_data.uint32;
case eTypeUInt64: return m_data.uint64;
case eTypeUInt8:
case eTypeUInt16:
case eTypeUInt32:
case eTypeUInt64:
case eTypeFloat:
if (sizeof(float) == sizeof(uint64_t))
return m_data.uint64;
break;
case eTypeDouble:
if (sizeof(double) == sizeof(uint64_t))
return m_data.uint64;
break;
case eTypeLongDouble:
if (sizeof(long double) == sizeof(uint64_t))
return m_data.uint64;
break;
case eTypeLongDouble: return m_scalar.ULongLong(fail_value);
case eTypeBytes:
{
switch (m_data.buffer.length)
switch (buffer.length)
{
default: break;
case 1: return m_data.uint8;
case 2: return m_data.uint16;
case 4: return m_data.uint32;
case 8: return m_data.uint64;
case 1:
case 2:
case 4:
case 8: return *(const uint64_t *)buffer.bytes;
}
}
break;
@ -778,43 +701,36 @@ RegisterValue::GetAsUInt64 (uint64_t fail_value, bool *success_ptr) const
return fail_value;
}
#if defined (ENABLE_128_BIT_SUPPORT)
__uint128_t
RegisterValue::GetAsUInt128 (__uint128_t fail_value, bool *success_ptr) const
llvm::APInt
RegisterValue::GetAsUInt128 (llvm::APInt& fail_value, bool *success_ptr) const
{
if (success_ptr)
*success_ptr = true;
switch (m_type)
{
default: break;
case eTypeUInt8: return m_data.uint8;
case eTypeUInt16: return m_data.uint16;
case eTypeUInt32: return m_data.uint32;
case eTypeUInt64: return m_data.uint64;
case eTypeUInt128: return m_data.uint128;
case eTypeUInt8:
case eTypeUInt16:
case eTypeUInt32:
case eTypeUInt64:
case eTypeUInt128:
case eTypeFloat:
if (sizeof(float) == sizeof(__uint128_t))
return m_data.uint128;
break;
case eTypeDouble:
if (sizeof(double) == sizeof(__uint128_t))
return m_data.uint128;
break;
case eTypeLongDouble:
if (sizeof(long double) == sizeof(__uint128_t))
return m_data.uint128;
break;
case eTypeLongDouble: return m_scalar.UInt128(fail_value);
case eTypeBytes:
{
switch (m_data.buffer.length)
switch (buffer.length)
{
default:
break;
case 1: return m_data.uint8;
case 2: return m_data.uint16;
case 4: return m_data.uint32;
case 8: return m_data.uint64;
case 16: return m_data.uint128;
default:
break;
case 1:
case 2:
case 4:
case 8:
case 16:
{
return llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)buffer.bytes)->x);
}
}
}
break;
@ -823,7 +739,7 @@ RegisterValue::GetAsUInt128 (__uint128_t fail_value, bool *success_ptr) const
*success_ptr = false;
return fail_value;
}
#endif
float
RegisterValue::GetAsFloat (float fail_value, bool *success_ptr) const
{
@ -833,28 +749,12 @@ RegisterValue::GetAsFloat (float fail_value, bool *success_ptr) const
{
default: break;
case eTypeUInt32:
if (sizeof(float) == sizeof(m_data.uint32))
return m_data.ieee_float;
break;
case eTypeUInt64:
if (sizeof(float) == sizeof(m_data.uint64))
return m_data.ieee_float;
break;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128:
if (sizeof(float) == sizeof(m_data.uint128))
return m_data.ieee_float;
break;
#endif
case eTypeFloat: return m_data.ieee_float;
case eTypeFloat:
case eTypeDouble:
if (sizeof(float) == sizeof(double))
return m_data.ieee_float;
break;
case eTypeLongDouble:
if (sizeof(float) == sizeof(long double))
return m_data.ieee_float;
break;
return m_scalar.Float(fail_value);
}
if (success_ptr)
*success_ptr = false;
@ -872,27 +772,12 @@ RegisterValue::GetAsDouble (double fail_value, bool *success_ptr) const
break;
case eTypeUInt32:
if (sizeof(double) == sizeof(m_data.uint32))
return m_data.ieee_double;
break;
case eTypeUInt64:
if (sizeof(double) == sizeof(m_data.uint64))
return m_data.ieee_double;
break;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128:
if (sizeof(double) == sizeof(m_data.uint128))
return m_data.ieee_double;
#endif
case eTypeFloat: return m_data.ieee_float;
case eTypeDouble: return m_data.ieee_double;
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble:
if (sizeof(double) == sizeof(long double))
return m_data.ieee_double;
break;
return m_scalar.Double(fail_value);
}
if (success_ptr)
*success_ptr = false;
@ -910,24 +795,12 @@ RegisterValue::GetAsLongDouble (long double fail_value, bool *success_ptr) const
break;
case eTypeUInt32:
if (sizeof(long double) == sizeof(m_data.uint32))
return m_data.ieee_long_double;
break;
case eTypeUInt64:
if (sizeof(long double) == sizeof(m_data.uint64))
return m_data.ieee_long_double;
break;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128:
if (sizeof(long double) == sizeof(m_data.uint128))
return m_data.ieee_long_double;
#endif
case eTypeFloat: return m_data.ieee_float;
case eTypeDouble: return m_data.ieee_double;
case eTypeLongDouble: return m_data.ieee_long_double;
break;
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble:
return m_scalar.LongDouble();
}
if (success_ptr)
*success_ptr = false;
@ -940,17 +813,15 @@ RegisterValue::GetBytes () const
switch (m_type)
{
case eTypeInvalid: break;
case eTypeUInt8: return &m_data.uint8;
case eTypeUInt16: return &m_data.uint16;
case eTypeUInt32: return &m_data.uint32;
case eTypeUInt64: return &m_data.uint64;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128: return &m_data.uint128;
#endif
case eTypeFloat: return &m_data.ieee_float;
case eTypeDouble: return &m_data.ieee_double;
case eTypeLongDouble: return &m_data.ieee_long_double;
case eTypeBytes: return m_data.buffer.bytes;
case eTypeUInt8:
case eTypeUInt16:
case eTypeUInt32:
case eTypeUInt64:
case eTypeUInt128:
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble: return m_scalar.GetBytes();
case eTypeBytes: return buffer.bytes;
}
return NULL;
}
@ -961,17 +832,15 @@ RegisterValue::GetBytes ()
switch (m_type)
{
case eTypeInvalid: break;
case eTypeUInt8: return &m_data.uint8;
case eTypeUInt16: return &m_data.uint16;
case eTypeUInt32: return &m_data.uint32;
case eTypeUInt64: return &m_data.uint64;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128: return &m_data.uint128;
#endif
case eTypeFloat: return &m_data.ieee_float;
case eTypeDouble: return &m_data.ieee_double;
case eTypeLongDouble: return &m_data.ieee_long_double;
case eTypeBytes: return m_data.buffer.bytes;
case eTypeUInt8:
case eTypeUInt16:
case eTypeUInt32:
case eTypeUInt64:
case eTypeUInt128:
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble: return m_scalar.GetBytes();
case eTypeBytes: return buffer.bytes;
}
return NULL;
}
@ -982,17 +851,15 @@ RegisterValue::GetByteSize () const
switch (m_type)
{
case eTypeInvalid: break;
case eTypeUInt8: return sizeof(m_data.uint8);
case eTypeUInt16: return sizeof(m_data.uint16);
case eTypeUInt32: return sizeof(m_data.uint32);
case eTypeUInt64: return sizeof(m_data.uint64);
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128: return sizeof(m_data.uint128);
#endif
case eTypeFloat: return sizeof(m_data.ieee_float);
case eTypeDouble: return sizeof(m_data.ieee_double);
case eTypeLongDouble: return sizeof(m_data.ieee_long_double);
case eTypeBytes: return m_data.buffer.length;
case eTypeUInt8: return 1;
case eTypeUInt16: return 2;
case eTypeUInt32:
case eTypeUInt64:
case eTypeUInt128:
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble: return m_scalar.GetByteSize();
case eTypeBytes: return buffer.length;
}
return 0;
}
@ -1021,12 +888,10 @@ RegisterValue::SetUInt (uint64_t uint, uint32_t byte_size)
{
SetUInt64 (uint);
}
#if defined (ENABLE_128_BIT_SUPPORT)
else if (byte_size <= 16)
{
SetUInt128 (uint);
SetUInt128 (llvm::APInt(64, uint));
}
#endif
else
return false;
return true;
@ -1036,21 +901,21 @@ void
RegisterValue::SetBytes (const void *bytes, size_t length, lldb::ByteOrder byte_order)
{
// If this assertion fires off we need to increase the size of
// m_data.buffer.bytes, or make it something that is allocated on
// buffer.bytes, or make it something that is allocated on
// the heap. Since the data buffer is in a union, we can't make it
// a collection class like SmallVector...
if (bytes && length > 0)
{
assert (length <= sizeof (m_data.buffer.bytes) && "Storing too many bytes in a RegisterValue.");
assert (length <= sizeof (buffer.bytes) && "Storing too many bytes in a RegisterValue.");
m_type = eTypeBytes;
m_data.buffer.length = length;
memcpy (m_data.buffer.bytes, bytes, length);
m_data.buffer.byte_order = byte_order;
buffer.length = length;
memcpy (buffer.bytes, bytes, length);
buffer.byte_order = byte_order;
}
else
{
m_type = eTypeInvalid;
m_data.buffer.length = 0;
buffer.length = 0;
}
}
@ -1063,25 +928,23 @@ RegisterValue::operator == (const RegisterValue &rhs) const
switch (m_type)
{
case eTypeInvalid: return true;
case eTypeUInt8: return m_data.uint8 == rhs.m_data.uint8;
case eTypeUInt16: return m_data.uint16 == rhs.m_data.uint16;
case eTypeUInt32: return m_data.uint32 == rhs.m_data.uint32;
case eTypeUInt64: return m_data.uint64 == rhs.m_data.uint64;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128: return m_data.uint128 == rhs.m_data.uint128;
#endif
case eTypeFloat: return m_data.ieee_float == rhs.m_data.ieee_float;
case eTypeDouble: return m_data.ieee_double == rhs.m_data.ieee_double;
case eTypeLongDouble: return m_data.ieee_long_double == rhs.m_data.ieee_long_double;
case eTypeUInt8:
case eTypeUInt16:
case eTypeUInt32:
case eTypeUInt64:
case eTypeUInt128:
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble: return m_scalar == rhs.m_scalar;
case eTypeBytes:
if (m_data.buffer.length != rhs.m_data.buffer.length)
if (buffer.length != rhs.buffer.length)
return false;
else
{
uint8_t length = m_data.buffer.length;
uint8_t length = buffer.length;
if (length > kMaxRegisterByteSize)
length = kMaxRegisterByteSize;
return memcmp (m_data.buffer.bytes, rhs.m_data.buffer.bytes, length) == 0;
return memcmp (buffer.bytes, rhs.buffer.bytes, length) == 0;
}
break;
}
@ -1097,27 +960,25 @@ RegisterValue::operator != (const RegisterValue &rhs) const
switch (m_type)
{
case eTypeInvalid: return false;
case eTypeUInt8: return m_data.uint8 != rhs.m_data.uint8;
case eTypeUInt16: return m_data.uint16 != rhs.m_data.uint16;
case eTypeUInt32: return m_data.uint32 != rhs.m_data.uint32;
case eTypeUInt64: return m_data.uint64 != rhs.m_data.uint64;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128: return m_data.uint128 != rhs.m_data.uint128;
#endif
case eTypeFloat: return m_data.ieee_float != rhs.m_data.ieee_float;
case eTypeDouble: return m_data.ieee_double != rhs.m_data.ieee_double;
case eTypeLongDouble: return m_data.ieee_long_double != rhs.m_data.ieee_long_double;
case eTypeUInt8:
case eTypeUInt16:
case eTypeUInt32:
case eTypeUInt64:
case eTypeUInt128:
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble: return m_scalar != rhs.m_scalar;
case eTypeBytes:
if (m_data.buffer.length != rhs.m_data.buffer.length)
if (buffer.length != rhs.buffer.length)
{
return true;
}
else
{
uint8_t length = m_data.buffer.length;
uint8_t length = buffer.length;
if (length > kMaxRegisterByteSize)
length = kMaxRegisterByteSize;
return memcmp (m_data.buffer.bytes, rhs.m_data.buffer.bytes, length) != 0;
return memcmp (buffer.bytes, rhs.buffer.bytes, length) != 0;
}
break;
}
@ -1132,63 +993,35 @@ RegisterValue::ClearBit (uint32_t bit)
case eTypeInvalid:
break;
case eTypeUInt8:
if (bit < 8)
{
m_data.uint8 &= ~(1u << bit);
return true;
}
break;
case eTypeUInt8:
case eTypeUInt16:
if (bit < 16)
case eTypeUInt32:
case eTypeUInt64:
case eTypeUInt128:
if (bit < (GetByteSize() * 8))
{
m_data.uint16 &= ~(1u << bit);
return true;
return m_scalar.ClearBit(bit);
}
break;
case eTypeUInt32:
if (bit < 32)
{
m_data.uint32 &= ~(1u << bit);
return true;
}
break;
case eTypeUInt64:
if (bit < 64)
{
m_data.uint64 &= ~(1ull << (uint64_t)bit);
return true;
}
break;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128:
if (bit < 64)
{
m_data.uint128 &= ~((__uint128_t)1ull << (__uint128_t)bit);
return true;
}
#endif
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble:
break;
case eTypeBytes:
if (m_data.buffer.byte_order == eByteOrderBig || m_data.buffer.byte_order == eByteOrderLittle)
if (buffer.byte_order == eByteOrderBig || buffer.byte_order == eByteOrderLittle)
{
uint32_t byte_idx;
if (m_data.buffer.byte_order == eByteOrderBig)
byte_idx = m_data.buffer.length - (bit / 8) - 1;
if (buffer.byte_order == eByteOrderBig)
byte_idx = buffer.length - (bit / 8) - 1;
else
byte_idx = bit / 8;
const uint32_t byte_bit = bit % 8;
if (byte_idx < m_data.buffer.length)
if (byte_idx < buffer.length)
{
m_data.buffer.bytes[byte_idx] &= ~(1u << byte_bit);
buffer.bytes[byte_idx] &= ~(1u << byte_bit);
return true;
}
}
@ -1207,62 +1040,34 @@ RegisterValue::SetBit (uint32_t bit)
break;
case eTypeUInt8:
if (bit < 8)
{
m_data.uint8 |= (1u << bit);
return true;
}
break;
case eTypeUInt16:
if (bit < 16)
{
m_data.uint16 |= (1u << bit);
return true;
}
break;
case eTypeUInt32:
if (bit < 32)
{
m_data.uint32 |= (1u << bit);
return true;
}
break;
case eTypeUInt64:
if (bit < 64)
case eTypeUInt128:
if (bit < (GetByteSize() * 8))
{
m_data.uint64 |= (1ull << (uint64_t)bit);
return true;
return m_scalar.SetBit(bit);
}
break;
#if defined (ENABLE_128_BIT_SUPPORT)
case eTypeUInt128:
if (bit < 64)
{
m_data.uint128 |= ((__uint128_t)1ull << (__uint128_t)bit);
return true;
}
#endif
case eTypeFloat:
case eTypeDouble:
case eTypeLongDouble:
break;
case eTypeBytes:
if (m_data.buffer.byte_order == eByteOrderBig || m_data.buffer.byte_order == eByteOrderLittle)
if (buffer.byte_order == eByteOrderBig || buffer.byte_order == eByteOrderLittle)
{
uint32_t byte_idx;
if (m_data.buffer.byte_order == eByteOrderBig)
byte_idx = m_data.buffer.length - (bit / 8) - 1;
if (buffer.byte_order == eByteOrderBig)
byte_idx = buffer.length - (bit / 8) - 1;
else
byte_idx = bit / 8;
const uint32_t byte_bit = bit % 8;
if (byte_idx < m_data.buffer.length)
if (byte_idx < buffer.length)
{
m_data.buffer.bytes[byte_idx] |= (1u << byte_bit);
buffer.bytes[byte_idx] |= (1u << byte_bit);
return true;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1897,7 +1897,7 @@ ValueObject::SetValueFromCString (const char *value_str, Error& error)
// If the value is already a scalar, then let the scalar change itself:
m_value.GetScalar().SetValueFromCString (value_str, encoding, byte_size);
}
else if (byte_size <= Scalar::GetMaxByteSize())
else if (byte_size <= 16)
{
// If the value fits in a scalar, then make a new scalar and again let the
// scalar code do the conversion, then figure out where to put the new value.