diff options
Diffstat (limited to 'lldb/source/Core/RegisterValue.cpp')
| -rw-r--r-- | lldb/source/Core/RegisterValue.cpp | 1205 |
1 files changed, 0 insertions, 1205 deletions
diff --git a/lldb/source/Core/RegisterValue.cpp b/lldb/source/Core/RegisterValue.cpp deleted file mode 100644 index 5e3844125b1c..000000000000 --- a/lldb/source/Core/RegisterValue.cpp +++ /dev/null @@ -1,1205 +0,0 @@ -//===-- RegisterValue.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Core/RegisterValue.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Core/Stream.h" -#include "lldb/Interpreter/Args.h" - -using namespace lldb; -using namespace lldb_private; - - -bool -RegisterValue::Dump (Stream *s, - const RegisterInfo *reg_info, - bool prefix_with_name, - bool prefix_with_alt_name, - Format format) const -{ - DataExtractor data; - if (GetData (data)) - { - bool name_printed = false; - if (prefix_with_name) - { - if (reg_info->name) - { - s->Printf ("%s", reg_info->name); - name_printed = true; - } - else if (reg_info->alt_name) - { - s->Printf ("%s", reg_info->alt_name); - prefix_with_alt_name = false; - name_printed = true; - } - } - if (prefix_with_alt_name) - { - if (name_printed) - s->PutChar ('/'); - if (reg_info->alt_name) - { - s->Printf ("%s", reg_info->alt_name); - name_printed = true; - } - else if (!name_printed) - { - // No alternate name but we were asked to display a name, so show the main name - s->Printf ("%s", reg_info->name); - name_printed = true; - } - } - if (name_printed) - s->PutCString (" = "); - - if (format == eFormatDefault) - format = reg_info->format; - - data.Dump (s, - 0, // Offset in "data" - format, // Format to use when dumping - reg_info->byte_size, // item_byte_size - 1, // item_count - UINT32_MAX, // num_per_line - LLDB_INVALID_ADDRESS, // base_addr - 0, // item_bit_size - 0); // item_bit_offset - return true; - } - return false; -} - - -bool -RegisterValue::GetData (DataExtractor &data) const -{ - return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0; -} - - -uint32_t -RegisterValue::GetAsMemoryData (const RegisterInfo *reg_info, - void *dst, - uint32_t dst_len, - lldb::ByteOrder dst_byte_order, - Error &error) const -{ - if (reg_info == NULL) - { - error.SetErrorString ("invalid register info argument."); - return 0; - } - - // ReadRegister should have already been called on tgus object prior to - // calling this. - if (GetType() == eTypeInvalid) - { - // No value has been read into this object... - error.SetErrorStringWithFormat("invalid register value type for register %s", reg_info->name); - return 0; - } - - if (dst_len > kMaxRegisterByteSize) - { - error.SetErrorString ("destination is too big"); - return 0; - } - - const uint32_t src_len = reg_info->byte_size; - - // Extract the register data into a data extractor - DataExtractor reg_data; - if (!GetData(reg_data)) - { - error.SetErrorString ("invalid register value to copy into"); - return 0; - } - - // Prepare a memory buffer that contains some or all of the register value - const uint32_t bytes_copied = reg_data.CopyByteOrderedData (0, // src offset - src_len, // src length - dst, // dst buffer - dst_len, // dst length - dst_byte_order); // dst byte order - if (bytes_copied == 0) - error.SetErrorStringWithFormat("failed to copy data for register write of %s", reg_info->name); - - return bytes_copied; -} - -uint32_t -RegisterValue::SetFromMemoryData (const RegisterInfo *reg_info, - const void *src, - uint32_t src_len, - lldb::ByteOrder src_byte_order, - Error &error) -{ - if (reg_info == NULL) - { - error.SetErrorString ("invalid register info argument."); - return 0; - } - - // Moving from addr into a register - // - // Case 1: src_len == dst_len - // - // |AABBCCDD| Address contents - // |AABBCCDD| Register contents - // - // Case 2: src_len > dst_len - // - // Error! (The register should always be big enough to hold the data) - // - // Case 3: src_len < dst_len - // - // |AABB| Address contents - // |AABB0000| Register contents [on little-endian hardware] - // |0000AABB| Register contents [on big-endian hardware] - if (src_len > kMaxRegisterByteSize) - { - error.SetErrorStringWithFormat ("register buffer is too small to receive %u bytes of data.", src_len); - return 0; - } - - const uint32_t dst_len = reg_info->byte_size; - - if (src_len > dst_len) - { - error.SetErrorStringWithFormat("%u bytes is too big to store in register %s (%u bytes)", src_len, reg_info->name, dst_len); - return 0; - } - - // Use a data extractor to correctly copy and pad the bytes read into the - // register value - DataExtractor src_data (src, src_len, src_byte_order, 4); - - // Given the register info, set the value type of this RegisterValue object - SetType (reg_info); - // And make sure we were able to figure out what that register value was - RegisterValue::Type value_type = GetType(); - if (value_type == eTypeInvalid) - { - // No value has been read into this object... - error.SetErrorStringWithFormat("invalid register value type for register %s", reg_info->name); - return 0; - } - else if (value_type == eTypeBytes) - { - m_data.buffer.byte_order = src_byte_order; - // Make sure to set the buffer length of the destination buffer to avoid - // problems due to uninitalized variables. - m_data.buffer.length = src_len; - } - - const uint32_t bytes_copied = src_data.CopyByteOrderedData (0, // src offset - src_len, // src length - GetBytes(), // dst buffer - GetByteSize(), // dst length - GetByteOrder()); // dst byte order - if (bytes_copied == 0) - error.SetErrorStringWithFormat("failed to copy data for register write of %s", reg_info->name); - - return bytes_copied; -} - -bool -RegisterValue::GetScalarValue (Scalar &scalar) const -{ - switch (m_type) - { - case eTypeInvalid: break; - case eTypeBytes: break; - 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; - } - return false; -} - -void -RegisterValue::Clear() -{ - m_type = eTypeInvalid; -} - -RegisterValue::Type -RegisterValue::SetType (const RegisterInfo *reg_info) -{ - m_type = eTypeInvalid; - const uint32_t byte_size = reg_info->byte_size; - switch (reg_info->encoding) - { - case eEncodingInvalid: - break; - - case eEncodingUint: - case eEncodingSint: - if (byte_size == 1) - m_type = eTypeUInt8; - else if (byte_size <= 2) - m_type = eTypeUInt16; - else if (byte_size <= 4) - 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: - if (byte_size == sizeof(float)) - m_type = eTypeFloat; - if (byte_size == sizeof(double)) - m_type = eTypeDouble; - if (byte_size == sizeof(long double)) - m_type = eTypeLongDouble; - break; - - case eEncodingVector: - m_type = eTypeBytes; - break; - } - return m_type; -} - -Error -RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &src, uint32_t src_offset, bool partial_data_ok) -{ - Error error; - - if (src.GetByteSize() == 0) - { - error.SetErrorString ("empty data."); - return error; - } - - if (reg_info->byte_size == 0) - { - error.SetErrorString ("invalid register info."); - return error; - } - - uint32_t src_len = src.GetByteSize() - src_offset; - - if (!partial_data_ok && (src_len < reg_info->byte_size)) - { - error.SetErrorString ("not enough data."); - return error; - } - - // Cap the data length if there is more than enough bytes for this register - // value - if (src_len > reg_info->byte_size) - 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)); - - switch (SetType (reg_info)) - { - case eTypeInvalid: - error.SetErrorString(""); - break; - case eTypeUInt8: SetUInt8 (src.GetMaxU32 (&src_offset, src_len)); break; - 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); - else - SetUInt128 (data2 << 64 + data1); - } - 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; - 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 - { - error.SetErrorString ("data copy failed data."); - return error; - } - } - } - - return error; -} - -#include "llvm/ADT/StringRef.h" -#include <vector> -static inline void StripSpaces(llvm::StringRef &Str) -{ - while (!Str.empty() && isspace(Str[0])) - Str = Str.substr(1); - while (!Str.empty() && isspace(Str.back())) - Str = Str.substr(0, Str.size()-1); -} -static inline void LStrip(llvm::StringRef &Str, char c) -{ - if (!Str.empty() && Str.front() == c) - Str = Str.substr(1); -} -static inline void RStrip(llvm::StringRef &Str, char c) -{ - if (!Str.empty() && Str.back() == c) - Str = Str.substr(0, Str.size()-1); -} -// Helper function for RegisterValue::SetValueFromCString() -static bool -ParseVectorEncoding(const RegisterInfo *reg_info, const char *vector_str, const uint32_t byte_size, RegisterValue *reg_value) -{ - // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}". - llvm::StringRef Str(vector_str); - StripSpaces(Str); - LStrip(Str, '{'); - RStrip(Str, '}'); - StripSpaces(Str); - - char Sep = ' '; - - // The first split should give us: - // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f 0x2a 0x3e'). - std::pair<llvm::StringRef, llvm::StringRef> Pair = Str.split(Sep); - std::vector<uint8_t> bytes; - unsigned byte = 0; - - // Using radix auto-sensing by passing 0 as the radix. - // Keep on processing the vector elements as long as the parsing succeeds and the vector size is < byte_size. - while (!Pair.first.getAsInteger(0, byte) && bytes.size() < byte_size) { - bytes.push_back(byte); - Pair = Pair.second.split(Sep); - } - - // Check for vector of exact byte_size elements. - if (bytes.size() != byte_size) - return false; - - reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle); - return true; -} -Error -RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *value_str) -{ - Error error; - if (reg_info == NULL) - { - error.SetErrorString ("Invalid register info argument."); - return error; - } - - if (value_str == NULL || value_str[0] == '\0') - { - error.SetErrorString ("Invalid c-string value string."); - return error; - } - bool success = false; - const uint32_t byte_size = reg_info->byte_size; - switch (reg_info->encoding) - { - default: - case eEncodingInvalid: - error.SetErrorString ("Invalid encoding."); - break; - - case eEncodingUint: - if (byte_size <= sizeof (uint64_t)) - { - uint64_t uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success); - if (!success) - error.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string value", value_str); - else if (!Args::UInt64ValueIsValidForByteSize (uval64, byte_size)) - error.SetErrorStringWithFormat ("value 0x%llx is too large to fit in a %u byte unsigned integer value", uval64, byte_size); - else - { - if (!SetUInt (uval64, reg_info->byte_size)) - error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %u", byte_size); - } - } - else - { - error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %u", byte_size); - return error; - } - break; - - case eEncodingSint: - if (byte_size <= sizeof (long long)) - { - uint64_t sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success); - if (!success) - error.SetErrorStringWithFormat ("'%s' is not a valid signed integer string value", value_str); - else if (!Args::SInt64ValueIsValidForByteSize (sval64, byte_size)) - error.SetErrorStringWithFormat ("value 0x%llx is too large to fit in a %u byte signed integer value", sval64, byte_size); - else - { - if (!SetUInt (sval64, reg_info->byte_size)) - error.SetErrorStringWithFormat ("unsupported signed integer byte size: %u", byte_size); - } - } - else - { - error.SetErrorStringWithFormat ("unsupported signed integer byte size: %u", byte_size); - return error; - } - break; - - case eEncodingIEEE754: - if (byte_size == sizeof (float)) - { - if (::sscanf (value_str, "%f", &m_data.ieee_float) == 1) - 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) - 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) - m_type = eTypeLongDouble; - else - error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str); - } - else - { - error.SetErrorStringWithFormat ("unsupported float byte size: %u", byte_size); - return error; - } - break; - - case eEncodingVector: - if (!ParseVectorEncoding(reg_info, value_str, byte_size, this)) - error.SetErrorString ("unrecognized vector encoding string value."); - break; - } - if (error.Fail()) - m_type = eTypeInvalid; - - return error; -} - - -bool -RegisterValue::SignExtend (uint32_t sign_bitpos) -{ - switch (m_type) - { - case eTypeInvalid: - 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 - case eTypeFloat: - case eTypeDouble: - case eTypeLongDouble: - case eTypeBytes: - break; - } - return false; -} - -bool -RegisterValue::CopyValue (const RegisterValue &rhs) -{ - m_type = rhs.m_type; - switch (m_type) - { - default: - 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 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; - break; - } - return true; -} - -uint16_t -RegisterValue::GetAsUInt16 (uint16_t 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; - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -uint32_t -RegisterValue::GetAsUInt32 (uint32_t 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 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; - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -uint64_t -RegisterValue::GetAsUInt64 (uint64_t 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 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; - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -#if defined (ENABLE_128_BIT_SUPPORT) -__uint128_t -RegisterValue::GetAsUInt128 (__uint128_t 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 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; - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} -#endif -float -RegisterValue::GetAsFloat (float fail_value, bool *success_ptr) const -{ - if (success_ptr) - *success_ptr = true; - switch (m_type) - { - 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 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; - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -double -RegisterValue::GetAsDouble (double fail_value, bool *success_ptr) const -{ - if (success_ptr) - *success_ptr = true; - switch (m_type) - { - default: - 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 eTypeLongDouble: - if (sizeof(double) == sizeof(long double)) - return m_data.ieee_double; - break; - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -long double -RegisterValue::GetAsLongDouble (long double fail_value, bool *success_ptr) const -{ - if (success_ptr) - *success_ptr = true; - switch (m_type) - { - default: - 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; - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -const void * -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; - } - return NULL; -} - -void * -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; - } - return NULL; -} - -uint32_t -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; - } - return 0; -} - - -bool -RegisterValue::SetUInt (uint64_t uint, uint32_t byte_size) -{ - if (byte_size == 0) - { - SetUInt64 (uint); - } - else if (byte_size == 1) - { - SetUInt8 (uint); - } - else if (byte_size <= 2) - { - SetUInt16 (uint); - } - else if (byte_size <= 4) - { - SetUInt32 (uint); - } - else if (byte_size <= 8) - { - SetUInt64 (uint); - } -#if defined (ENABLE_128_BIT_SUPPORT) - else if (byte_size <= 16) - { - SetUInt128 (uint); - } -#endif - else - return false; - return true; -} - -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 - // the heap. Since the data buffer is in a union, we can't make it - // a collection class like SmallVector... - assert (length <= sizeof (m_data.buffer.bytes)); - if (bytes && length > 0) - { - m_type = eTypeBytes; - m_data.buffer.length = length; - assert (length < sizeof (m_data.buffer.bytes)); - memcpy (m_data.buffer.bytes, bytes, length); - m_data.buffer.byte_order = byte_order; - } - else - { - m_type = eTypeInvalid; - m_data.buffer.length = 0; - } -} - - -bool -RegisterValue::operator == (const RegisterValue &rhs) const -{ - if (m_type == rhs.m_type) - { - 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 eTypeBytes: - if (m_data.buffer.length != rhs.m_data.buffer.length) - return false; - else - { - uint8_t length = m_data.buffer.length; - if (length > kMaxRegisterByteSize) - length = kMaxRegisterByteSize; - return memcmp (m_data.buffer.bytes, rhs.m_data.buffer.bytes, length) == 0; - } - break; - } - } - return false; -} - -bool -RegisterValue::operator != (const RegisterValue &rhs) const -{ - if (m_type != rhs.m_type) - return true; - 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 eTypeBytes: - if (m_data.buffer.length != rhs.m_data.buffer.length) - { - return true; - } - else - { - uint8_t length = m_data.buffer.length; - if (length > kMaxRegisterByteSize) - length = kMaxRegisterByteSize; - return memcmp (m_data.buffer.bytes, rhs.m_data.buffer.bytes, length) != 0; - } - break; - } - return true; -} - -bool -RegisterValue::ClearBit (uint32_t bit) -{ - switch (m_type) - { - case eTypeInvalid: - 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) - { - 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) - { - uint32_t byte_idx; - if (m_data.buffer.byte_order == eByteOrderBig) - byte_idx = m_data.buffer.length - (bit / 8) - 1; - else - byte_idx = bit / 8; - - const uint32_t byte_bit = bit % 8; - if (byte_idx < m_data.buffer.length) - { - m_data.buffer.bytes[byte_idx] &= ~(1u << byte_bit); - return true; - } - } - break; - } - return false; -} - - -bool -RegisterValue::SetBit (uint32_t bit) -{ - switch (m_type) - { - case eTypeInvalid: - 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) - { - 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) - { - uint32_t byte_idx; - if (m_data.buffer.byte_order == eByteOrderBig) - byte_idx = m_data.buffer.length - (bit / 8) - 1; - else - byte_idx = bit / 8; - - const uint32_t byte_bit = bit % 8; - if (byte_idx < m_data.buffer.length) - { - m_data.buffer.bytes[byte_idx] |= (1u << byte_bit); - return true; - } - } - break; - } - return false; -} - |
