| //===-- RegisterValue.h ------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef lldb_RegisterValue_h |
| #define lldb_RegisterValue_h |
| |
| // C Includes |
| #include <string.h> |
| |
| // C++ Includes |
| // Other libraries and framework includes |
| // Project includes |
| #include "lldb/lldb-public.h" |
| #include "lldb/lldb-private.h" |
| #include "lldb/Host/Endian.h" |
| |
| //#define ENABLE_128_BIT_SUPPORT 1 |
| namespace lldb_private { |
| |
| class RegisterValue |
| { |
| public: |
| enum |
| { |
| kMaxRegisterByteSize = 32u |
| }; |
| enum Type |
| { |
| eTypeInvalid, |
| eTypeUInt8, |
| eTypeUInt16, |
| eTypeUInt32, |
| eTypeUInt64, |
| #if defined (ENABLE_128_BIT_SUPPORT) |
| eTypeUInt128, |
| #endif |
| eTypeFloat, |
| eTypeDouble, |
| eTypeLongDouble, |
| eTypeBytes |
| }; |
| |
| RegisterValue () : |
| m_type (eTypeInvalid) |
| { |
| } |
| |
| explicit |
| RegisterValue (uint8_t inst) : |
| m_type (eTypeUInt8) |
| { |
| m_data.uint8 = inst; |
| } |
| |
| explicit |
| RegisterValue (uint16_t inst) : |
| m_type (eTypeUInt16) |
| { |
| m_data.uint16 = inst; |
| } |
| |
| explicit |
| RegisterValue (uint32_t inst) : |
| m_type (eTypeUInt32) |
| { |
| m_data.uint32 = inst; |
| } |
| |
| explicit |
| RegisterValue (uint64_t inst) : |
| m_type (eTypeUInt64) |
| { |
| m_data.uint64 = inst; |
| } |
| |
| #if defined (ENABLE_128_BIT_SUPPORT) |
| explicit |
| RegisterValue (__uint128_t inst) : |
| m_type (eTypeUInt128) |
| { |
| m_data.uint128 = inst; |
| } |
| #endif |
| explicit |
| RegisterValue (float value) : |
| m_type (eTypeFloat) |
| { |
| m_data.ieee_float = value; |
| } |
| |
| explicit |
| RegisterValue (double value) : |
| m_type (eTypeDouble) |
| { |
| m_data.ieee_double = value; |
| } |
| |
| explicit |
| RegisterValue (long double value) : |
| m_type (eTypeLongDouble) |
| { |
| m_data.ieee_long_double = value; |
| } |
| |
| explicit |
| RegisterValue (uint8_t *bytes, size_t length, lldb::ByteOrder byte_order) |
| { |
| SetBytes (bytes, length, byte_order); |
| } |
| |
| RegisterValue::Type |
| GetType () const |
| { |
| return m_type; |
| } |
| |
| bool |
| CopyValue (const RegisterValue &rhs); |
| |
| void |
| SetType (RegisterValue::Type type) |
| { |
| m_type = type; |
| } |
| |
| RegisterValue::Type |
| SetType (const RegisterInfo *reg_info); |
| |
| bool |
| GetData (DataExtractor &data) const; |
| |
| // Copy the register value from this object into a buffer in "dst" |
| // and obey the "dst_byte_order" when copying the data. Also watch out |
| // in case "dst_len" is longer or shorter than the register value |
| // described by "reg_info" and only copy the least significant bytes |
| // of the register value, or pad the destination with zeroes if the |
| // register byte size is shorter that "dst_len" (all while correctly |
| // abiding the "dst_byte_order"). Returns the number of bytes copied |
| // into "dst". |
| uint32_t |
| GetAsMemoryData (const RegisterInfo *reg_info, |
| void *dst, |
| uint32_t dst_len, |
| lldb::ByteOrder dst_byte_order, |
| Error &error) const; |
| |
| uint32_t |
| SetFromMemoryData (const RegisterInfo *reg_info, |
| const void *src, |
| uint32_t src_len, |
| lldb::ByteOrder src_byte_order, |
| Error &error); |
| |
| bool |
| GetScalarValue (Scalar &scalar) const; |
| |
| uint8_t |
| GetAsUInt8 (uint8_t fail_value = UINT8_MAX, bool *success_ptr = NULL) const |
| { |
| if (m_type == eTypeUInt8) |
| { |
| if (success_ptr) |
| *success_ptr = true; |
| return m_data.uint8; |
| } |
| if (success_ptr) |
| *success_ptr = true; |
| return fail_value; |
| } |
| |
| uint16_t |
| GetAsUInt16 (uint16_t fail_value = UINT16_MAX, bool *success_ptr = NULL) const; |
| |
| uint32_t |
| GetAsUInt32 (uint32_t fail_value = UINT32_MAX, bool *success_ptr = NULL) const; |
| |
| 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 |
| |
| float |
| GetAsFloat (float fail_value = 0.0f, bool *success_ptr = NULL) const; |
| |
| double |
| GetAsDouble (double fail_value = 0.0, bool *success_ptr = NULL) const; |
| |
| long double |
| GetAsLongDouble (long double fail_value = 0.0, bool *success_ptr = NULL) const; |
| |
| void |
| SetValueToInvalid () |
| { |
| m_type = eTypeInvalid; |
| } |
| |
| bool |
| ClearBit (uint32_t bit); |
| |
| bool |
| SetBit (uint32_t bit); |
| |
| bool |
| operator == (const RegisterValue &rhs) const; |
| |
| bool |
| operator != (const RegisterValue &rhs) const; |
| |
| void |
| operator = (uint8_t uint) |
| { |
| m_type = eTypeUInt8; |
| m_data.uint8 = uint; |
| } |
| |
| void |
| operator = (uint16_t uint) |
| { |
| m_type = eTypeUInt16; |
| m_data.uint16 = uint; |
| } |
| |
| void |
| operator = (uint32_t uint) |
| { |
| m_type = eTypeUInt32; |
| m_data.uint32 = uint; |
| } |
| |
| void |
| operator = (uint64_t uint) |
| { |
| m_type = eTypeUInt64; |
| m_data.uint64 = uint; |
| } |
| |
| #if defined (ENABLE_128_BIT_SUPPORT) |
| void |
| operator = (__uint128_t uint) |
| { |
| m_type = eTypeUInt128; |
| m_data.uint128 = uint; |
| } |
| #endif |
| void |
| operator = (float f) |
| { |
| m_type = eTypeFloat; |
| m_data.ieee_float = f; |
| } |
| |
| void |
| operator = (double f) |
| { |
| m_type = eTypeDouble; |
| m_data.ieee_double = f; |
| } |
| |
| void |
| operator = (long double f) |
| { |
| m_type = eTypeLongDouble; |
| m_data.ieee_long_double = f; |
| } |
| |
| void |
| SetUInt8 (uint8_t uint) |
| { |
| m_type = eTypeUInt8; |
| m_data.uint8 = uint; |
| } |
| |
| void |
| SetUInt16 (uint16_t uint) |
| { |
| m_type = eTypeUInt16; |
| m_data.uint16 = uint; |
| } |
| |
| void |
| SetUInt32 (uint32_t uint, Type t = eTypeUInt32) |
| { |
| m_type = t; |
| m_data.uint32 = uint; |
| } |
| |
| void |
| SetUInt64 (uint64_t uint, Type t = eTypeUInt64) |
| { |
| m_type = t; |
| m_data.uint64 = uint; |
| } |
| |
| #if defined (ENABLE_128_BIT_SUPPORT) |
| void |
| SetUInt128 (__uint128_t uint) |
| { |
| m_type = eTypeUInt128; |
| m_data.uint128 = uint; |
| } |
| #endif |
| bool |
| SetUInt (uint64_t uint, uint32_t byte_size); |
| |
| void |
| SetFloat (float f) |
| { |
| m_type = eTypeFloat; |
| m_data.ieee_float = f; |
| } |
| |
| void |
| SetDouble (double f) |
| { |
| m_type = eTypeDouble; |
| m_data.ieee_double = f; |
| } |
| |
| void |
| SetLongDouble (long double f) |
| { |
| m_type = eTypeLongDouble; |
| m_data.ieee_long_double = f; |
| } |
| |
| void |
| SetBytes (const void *bytes, size_t length, lldb::ByteOrder byte_order); |
| |
| bool |
| SignExtend (uint32_t sign_bitpos); |
| |
| Error |
| SetValueFromCString (const RegisterInfo *reg_info, |
| const char *value_str); |
| |
| Error |
| SetValueFromData (const RegisterInfo *reg_info, |
| DataExtractor &data, |
| lldb::offset_t offset, |
| bool partial_data_ok); |
| |
| // The default value of 0 for reg_name_right_align_at means no alignment at all. |
| bool |
| Dump (Stream *s, |
| const RegisterInfo *reg_info, |
| bool prefix_with_name, |
| bool prefix_with_alt_name, |
| lldb::Format format, |
| uint32_t reg_name_right_align_at = 0) const; |
| |
| void * |
| GetBytes (); |
| |
| const void * |
| GetBytes () const; |
| |
| lldb::ByteOrder |
| GetByteOrder () const |
| { |
| if (m_type == eTypeBytes) |
| return m_data.buffer.byte_order; |
| return lldb::endian::InlHostByteOrder(); |
| } |
| |
| uint32_t |
| GetByteSize () const; |
| |
| static uint32_t |
| GetMaxByteSize () |
| { |
| return kMaxRegisterByteSize; |
| } |
| |
| void |
| Clear(); |
| |
| protected: |
| |
| RegisterValue::Type m_type; |
| union |
| { |
| 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; |
| }; |
| |
| } // namespace lldb_private |
| |
| #endif // lldb_RegisterValue_h |