blob: 1b1a71a11c5ac82514477f0658a8d143fae125c1 [file] [log] [blame]
//===-- 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