//===-- 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
#include <vector>

// Other libraries and framework includes
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"

// Project includes
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Host/StringConvert.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,
                     uint32_t reg_name_right_align_at) const
{
    DataExtractor data;
    if (GetData (data))
    {
        bool name_printed = false;
        // For simplicity, alignment of the register name printing applies only
        // in the most common case where:
        // 
        //     prefix_with_name^prefix_with_alt_name is true
        //
        StreamString format_string;
        if (reg_name_right_align_at && (prefix_with_name^prefix_with_alt_name))
            format_string.Printf("%%%us", reg_name_right_align_at);
        else
            format_string.Printf("%%s");
        const char *fmt = format_string.GetData();
        if (prefix_with_name)
        {
            if (reg_info->name)
            {
                s->Printf (fmt, reg_info->name);
                name_printed = true;
            }
            else if (reg_info->alt_name)
            {
                s->Printf (fmt, 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 (fmt, 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 (fmt, 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 == nullptr)
    {
        error.SetErrorString ("invalid register info argument.");
        return 0;
    }
    
    // ReadRegister should have already been called on this 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 == nullptr)
    {
        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);

    error = SetValueFromData(reg_info, src_data, 0, true);
    if (error.Fail())
        return 0;

    // If SetValueFromData succeeded, we must have copied all of src_len
    return src_len;
}

bool
RegisterValue::GetScalarValue (Scalar &scalar) const
{
    switch (m_type)
    {
        case eTypeInvalid:      break;
        case eTypeBytes:
            {
                switch (buffer.length)
                {
                default:    break;
                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 16:
                case 32:
                            if (buffer.length % sizeof(uint64_t) == 0)
                            {
                                const auto length_in_bits = buffer.length * 8;
                                const auto length_in_uint64 = buffer.length / sizeof(uint64_t);
                                scalar = llvm::APInt(length_in_bits, llvm::ArrayRef<uint64_t>((const uint64_t *)buffer.bytes, length_in_uint64));
                                return true;
                            }
                            break;
                }
            }
            break;
        case eTypeUInt8:
        case eTypeUInt16:
        case eTypeUInt32:
        case eTypeUInt64:
        case eTypeUInt128:
        case eTypeFloat:
        case eTypeDouble:
        case eTypeLongDouble:   scalar = m_scalar; return true;
    }
    return false;
}

void
RegisterValue::Clear()
{
    m_type = eTypeInvalid;
}

RegisterValue::Type
RegisterValue::SetType (const RegisterInfo *reg_info)
{
    // To change the type, we simply copy the data in again, using the new format
    RegisterValue copy;
    DataExtractor copy_data;
    if (copy.CopyValue(*this) && copy.GetData(copy_data))
        SetValueFromData(reg_info, copy_data, 0, true);

    return m_type;
}

Error
RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &src, lldb::offset_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 (buffer.bytes, 0, sizeof (buffer.bytes));

    type128 int128;

    m_type = eTypeInvalid;
    switch (reg_info->encoding)
    {
        case eEncodingInvalid:
            break;
        case eEncodingUint:
        case eEncodingSint:
            if (reg_info->byte_size == 1)
                SetUInt8(src.GetMaxU32(&src_offset, src_len));
            else if (reg_info->byte_size <= 2)
                SetUInt16(src.GetMaxU32(&src_offset, src_len));
            else if (reg_info->byte_size <= 4)
                SetUInt32(src.GetMaxU32(&src_offset, src_len));
            else if (reg_info->byte_size <= 8)
                SetUInt64(src.GetMaxU64(&src_offset, src_len));
            else if (reg_info->byte_size <= 16)
            {
                uint64_t data1 = src.GetU64 (&src_offset);
                uint64_t data2 = src.GetU64 (&src_offset);
                if (src.GetByteSize() == eByteOrderBig)
                {
                    int128.x[0] = data1;
                    int128.x[1] = data2;
                }
                else
                {
                    int128.x[0] = data2;
                    int128.x[1] = data1;
                }
                SetUInt128 (llvm::APInt(128, 2, int128.x));
            }
            break;
        case eEncodingIEEE754:
            if (reg_info->byte_size == sizeof(float))
                SetFloat(src.GetFloat(&src_offset));
            else if (reg_info->byte_size == sizeof(double))
                SetDouble(src.GetDouble(&src_offset));
            else if (reg_info->byte_size == sizeof(long double))
                SetLongDouble(src.GetLongDouble(&src_offset));
            break;
        case eEncodingVector:
        {
            m_type = eTypeBytes;
            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
                                         buffer.bytes,           // dst buffer
                                         buffer.length,          // dst length
                                         buffer.byte_order) == 0)// dst byte order
            {
                error.SetErrorStringWithFormat("failed to copy data for register write of %s", reg_info->name);
                return error;
            }
        }
    }

    if (m_type == eTypeInvalid)
        error.SetErrorStringWithFormat("invalid register value type for register %s", reg_info->name);
    return error;
}

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 == nullptr)
    {
        error.SetErrorString ("Invalid register info argument.");
        return error;
    }

    if (value_str == nullptr || 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;
    static float flt_val;
    static double dbl_val;
    static long double ldbl_val;
    switch (reg_info->encoding)
    {
        case eEncodingInvalid:
            error.SetErrorString ("Invalid encoding.");
            break;
            
        case eEncodingUint:
            if (byte_size <= sizeof (uint64_t))
            {
                uint64_t uval64 = StringConvert::ToUInt64(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%" PRIx64 " 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 = StringConvert::ToSInt64(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%" PRIx64 " 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", &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", &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", &ldbl_val) == 1)
                {
                    m_scalar = ldbl_val;
                    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:        
        case eTypeUInt16:
        case eTypeUInt32:
        case eTypeUInt64:
        case eTypeUInt128:
            return m_scalar.SignExtend(sign_bitpos);
        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)
    {
        case eTypeInvalid: 
            return false;
        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.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;
}

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:
        case eTypeUInt16:   return m_scalar.UShort(fail_value);
        case eTypeBytes:
        {
            switch (buffer.length)
            {
            default:    break;
            case 1:
            case 2:     return *(const uint16_t *)buffer.bytes;
            }
        }
        break;
    }
    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:
        case eTypeUInt16:
        case eTypeUInt32:
        case eTypeFloat:
        case eTypeDouble:
        case eTypeLongDouble:   return m_scalar.UInt(fail_value);
        case eTypeBytes:
        {
            switch (buffer.length)
            {
            default:    break;
            case 1:
            case 2:
            case 4:     return *(const uint32_t *)buffer.bytes;
            }
        }
        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:
  case eTypeUInt16:
  case eTypeUInt32:
  case eTypeUInt64:
  case eTypeFloat:
  case eTypeDouble:
  case eTypeLongDouble:
    return m_scalar.ULongLong(fail_value);
  case eTypeBytes: {
    switch (buffer.length) {
    default:
      break;
    case 1:
      return *(const uint8_t *)buffer.bytes;
    case 2:
      return *(const uint16_t *)buffer.bytes;
    case 4:
      return *(const uint32_t *)buffer.bytes;
    case 8:
      return *(const uint64_t *)buffer.bytes;
    }
  } break;
  }
  if (success_ptr)
    *success_ptr = false;
  return fail_value;
}

llvm::APInt
RegisterValue::GetAsUInt128 (const llvm::APInt& fail_value, bool *success_ptr) const
{
    if (success_ptr)
        *success_ptr = true;
    switch (m_type)
    {
        default:            break;
        case eTypeUInt8:
        case eTypeUInt16:
        case eTypeUInt32:
        case eTypeUInt64:
        case eTypeUInt128:
        case eTypeFloat:
        case eTypeDouble:
        case eTypeLongDouble:  return m_scalar.UInt128(fail_value);
        case eTypeBytes:
        {
            switch (buffer.length)
            {
                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;
    }
    if (success_ptr)
        *success_ptr = false;
    return fail_value;
}

float
RegisterValue::GetAsFloat (float fail_value, bool *success_ptr) const
{
    if (success_ptr)
        *success_ptr = true;
    switch (m_type)
    {
        default:            break;
        case eTypeUInt32:
        case eTypeUInt64:
        case eTypeUInt128:
        case eTypeFloat:
        case eTypeDouble:
        case eTypeLongDouble:
            return m_scalar.Float(fail_value);
    }
    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:
        case eTypeUInt64:
        case eTypeUInt128:
        case eTypeFloat:
        case eTypeDouble:
        case eTypeLongDouble:
            return m_scalar.Double(fail_value);
    }
    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:
        case eTypeUInt64:
        case eTypeUInt128:
        case eTypeFloat:
        case eTypeDouble:
        case eTypeLongDouble:
            return m_scalar.LongDouble();
    }
    if (success_ptr)
        *success_ptr = false;
    return fail_value;
}

const void *
RegisterValue::GetBytes () const
{
    switch (m_type)
    {
        case eTypeInvalid:      break;
        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 nullptr;
}

uint32_t
RegisterValue::GetByteSize () const
{
    switch (m_type)
    {
        case eTypeInvalid: break;
        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;
}

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);
    }
    else if (byte_size <= 16)
    {
        SetUInt128 (llvm::APInt(128, uint));
    }
    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
    // 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 (buffer.bytes) && "Storing too many bytes in a RegisterValue.");
        m_type = eTypeBytes;
        buffer.length = length;
        memcpy (buffer.bytes, bytes, length);
        buffer.byte_order = byte_order;
    }
    else
    {
        m_type = eTypeInvalid;
        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:
            case eTypeUInt16:
            case eTypeUInt32:
            case eTypeUInt64:
            case eTypeUInt128:
            case eTypeFloat:
            case eTypeDouble:
            case eTypeLongDouble:   return m_scalar == rhs.m_scalar;
            case eTypeBytes:        
                if (buffer.length != rhs.buffer.length)
                    return false;
                else
                {
                    uint8_t length = buffer.length;
                    if (length > kMaxRegisterByteSize)
                        length = kMaxRegisterByteSize;
                    return memcmp (buffer.bytes, rhs.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:
        case eTypeUInt16:
        case eTypeUInt32:
        case eTypeUInt64:
        case eTypeUInt128:
        case eTypeFloat:
        case eTypeDouble:
        case eTypeLongDouble:   return m_scalar != rhs.m_scalar;
        case eTypeBytes:        
            if (buffer.length != rhs.buffer.length)
            {
                return true;
            }
            else
            {
                uint8_t length = buffer.length;
                if (length > kMaxRegisterByteSize)
                    length = kMaxRegisterByteSize;
                return memcmp (buffer.bytes, rhs.buffer.bytes, length) != 0;
            }
            break;
    }
    return true;
}

bool
RegisterValue::ClearBit (uint32_t bit)
{
    switch (m_type)
    {
        case eTypeInvalid:
            break;

        case eTypeUInt8:
        case eTypeUInt16:
        case eTypeUInt32:
        case eTypeUInt64:
        case eTypeUInt128:
            if (bit < (GetByteSize() * 8))
            {
                return m_scalar.ClearBit(bit);
            }
            break;

        case eTypeFloat:
        case eTypeDouble:
        case eTypeLongDouble:
            break;

        case eTypeBytes:
            if (buffer.byte_order == eByteOrderBig || buffer.byte_order == eByteOrderLittle)
            {
                uint32_t byte_idx;
                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 < buffer.length)
                {
                    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:        
        case eTypeUInt16:
        case eTypeUInt32:
        case eTypeUInt64:
        case eTypeUInt128:
            if (bit < (GetByteSize() * 8))
            {
                return m_scalar.SetBit(bit);
            }
            break;

        case eTypeFloat:
        case eTypeDouble:
        case eTypeLongDouble:
            break;
            
        case eTypeBytes:
            if (buffer.byte_order == eByteOrderBig || buffer.byte_order == eByteOrderLittle)
            {
                uint32_t byte_idx;
                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 < buffer.length)
                {
                    buffer.bytes[byte_idx] |= (1u << byte_bit);
                    return true;
                }
            }
            break;
    }
    return false;
}
