summaryrefslogtreecommitdiff
path: root/lldb/source/Core/RegisterValue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core/RegisterValue.cpp')
-rw-r--r--lldb/source/Core/RegisterValue.cpp1205
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;
-}
-