//===-- 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 (size_t reg)
{
    return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}

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



const RegisterSet *
RegisterContextMacOSXFrameBackchain::GetRegisterSet (size_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);
}

