//===-- RegisterContextMacOSXFrameBackchain.cpp -----------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "RegisterContextMacOSXFrameBackchain.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Target/Thread.h"
// Project includes
#include "Utility/StringExtractorGDBRemote.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// RegisterContextMacOSXFrameBackchain constructor
//----------------------------------------------------------------------
RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain
(
    Thread &thread,
    uint32_t concrete_frame_idx,
    const UnwindMacOSXFrameBackchain::Cursor &cursor
) :
    RegisterContext (thread, concrete_frame_idx),
    m_cursor (cursor),
    m_cursor_is_valid (true)
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain()
{
}

void
RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters ()
{
    m_cursor_is_valid = false;
}

size_t
RegisterContextMacOSXFrameBackchain::GetRegisterCount ()
{
    return m_thread.GetRegisterContext()->GetRegisterCount();
}

const RegisterInfo *
RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (uint32_t reg)
{
    return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}

size_t
RegisterContextMacOSXFrameBackchain::GetRegisterSetCount ()
{
    return m_thread.GetRegisterContext()->GetRegisterSetCount();
}



const RegisterSet *
RegisterContextMacOSXFrameBackchain::GetRegisterSet (uint32_t reg_set)
{
    return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
}



bool
RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info,
                                                   RegisterValue &value)
{
    if (!m_cursor_is_valid)
        return false;

    uint64_t reg_value = LLDB_INVALID_ADDRESS;
    
    switch (reg_info->kinds[eRegisterKindGeneric])
    {
    case LLDB_REGNUM_GENERIC_PC:
        if (m_cursor.pc == LLDB_INVALID_ADDRESS)
            return false;
        reg_value = m_cursor.pc;
        break;
    
    case LLDB_REGNUM_GENERIC_FP:
        if (m_cursor.fp == LLDB_INVALID_ADDRESS)
            return false;
        reg_value = m_cursor.fp;
        break;
    
    default:
        return false;    
    }
    
    switch (reg_info->encoding)
    {
    case eEncodingInvalid:
    case eEncodingVector:
        break;

    case eEncodingUint:
    case eEncodingSint:
        value.SetUInt(reg_value, reg_info->byte_size);
        return true;

    case eEncodingIEEE754:
        switch (reg_info->byte_size)
        {
        case sizeof (float):
            if (sizeof (float) == sizeof(uint32_t))
            {
                value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
                return true;
            }
            else if (sizeof (float) == sizeof(uint64_t))
            {
                value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
                return true;
            }
            break;

        case sizeof (double):
            if (sizeof (double) == sizeof(uint32_t))
            {
                value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
                return true;
            }
            else if (sizeof (double) == sizeof(uint64_t))
            {
                value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
                return true;
            }
            break;

            // TOOD: need a better way to detect when "long double" types are 
            // the same bytes size as "double"
#if !defined(__arm__)
        case sizeof (long double):
            if (sizeof (long double) == sizeof(uint32_t))
            {
                value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
                return true;
            }
            else if (sizeof (long double) == sizeof(uint64_t))
            {
                value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
                return true;
            }
            break;
#endif
        }
        break;
    }
    return false;
}

bool
RegisterContextMacOSXFrameBackchain::WriteRegister (const RegisterInfo *reg_info,
                                                    const RegisterValue &value)
{
    // Not supported yet. We could easily add support for this by remembering
    // the address of each entry (it would need to be part of the cursor)
    return false;
}

bool
RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
{
    // libunwind frames can't handle this it doesn't always have all register
    // values. This call should only be called on frame zero anyway so there
    // shouldn't be any problem
    return false;
}

bool
RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
{
    // Since this class doesn't respond to "ReadAllRegisterValues()", it must
    // not have been the one that saved all the register values. So we just let
    // the thread's register context (the register context for frame zero) do
    // the writing.
    return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
}


uint32_t
RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
{
    return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num);
}

