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

#include <cstring>
#include <errno.h>
#include <stdint.h>

#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Host/Endian.h"
#include "llvm/Support/Compiler.h"

#include "RegisterContextPOSIX_arm.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"

using namespace lldb;
using namespace lldb_private;

// arm general purpose registers.
const uint32_t g_gpr_regnums_arm[] =
{
    gpr_r0_arm,
    gpr_r1_arm,
    gpr_r2_arm,
    gpr_r3_arm,
    gpr_r4_arm,
    gpr_r5_arm,
    gpr_r6_arm,
    gpr_r7_arm,
    gpr_r8_arm,
    gpr_r9_arm,
    gpr_r10_arm,
    gpr_r11_arm,
    gpr_r12_arm,
    gpr_sp_arm,
    gpr_lr_arm,
    gpr_pc_arm,
    gpr_cpsr_arm,
    LLDB_INVALID_REGNUM // register sets need to end with this flag

};
static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
              "g_gpr_regnums_arm has wrong number of register infos");

// arm floating point registers.
static const uint32_t g_fpu_regnums_arm[] =
{
    fpu_s0_arm,
    fpu_s1_arm,
    fpu_s2_arm,
    fpu_s3_arm,
    fpu_s4_arm,
    fpu_s5_arm,
    fpu_s6_arm,
    fpu_s7_arm,
    fpu_s8_arm,
    fpu_s9_arm,
    fpu_s10_arm,
    fpu_s11_arm,
    fpu_s12_arm,
    fpu_s13_arm,
    fpu_s14_arm,
    fpu_s15_arm,
    fpu_s16_arm,
    fpu_s17_arm,
    fpu_s18_arm,
    fpu_s19_arm,
    fpu_s20_arm,
    fpu_s21_arm,
    fpu_s22_arm,
    fpu_s23_arm,
    fpu_s24_arm,
    fpu_s25_arm,
    fpu_s26_arm,
    fpu_s27_arm,
    fpu_s28_arm,
    fpu_s29_arm,
    fpu_s30_arm,
    fpu_s31_arm,
    fpu_fpscr_arm,
    LLDB_INVALID_REGNUM // register sets need to end with this flag

};
static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
              "g_fpu_regnums_arm has wrong number of register infos");

// Number of register sets provided by this context.
enum
{
    k_num_register_sets = 2
};

// Register sets for arm.
static const lldb_private::RegisterSet
g_reg_sets_arm[k_num_register_sets] =
{
    { "General Purpose Registers",  "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
    { "Floating Point Registers",   "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
};

bool RegisterContextPOSIX_arm::IsGPR(unsigned reg)
{
    return reg <= m_reg_info.last_gpr;   // GPR's come first.
}

bool RegisterContextPOSIX_arm::IsFPR(unsigned reg)
{
    return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}

RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(lldb_private::Thread &thread,
                                                       uint32_t concrete_frame_idx,
                                                       lldb_private::RegisterInfoInterface *register_info)
    : lldb_private::RegisterContext(thread, concrete_frame_idx)
{
    m_register_info_ap.reset(register_info);

    switch (register_info->m_target_arch.GetMachine())
    {
        case llvm::Triple::arm:
            m_reg_info.num_registers     = k_num_registers_arm;
            m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
            m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
            m_reg_info.last_gpr          = k_last_gpr_arm;
            m_reg_info.first_fpr         = k_first_fpr_arm;
            m_reg_info.last_fpr          = k_last_fpr_arm;
            m_reg_info.first_fpr_v       = fpu_s0_arm;
            m_reg_info.last_fpr_v        = fpu_s31_arm;
            m_reg_info.gpr_flags         = gpr_cpsr_arm;
            break;
        default:
            assert(false && "Unhandled target architecture.");
            break;
    }

    ::memset(&m_fpr, 0, sizeof m_fpr);

    // elf-core yet to support ReadFPR()
    lldb::ProcessSP base = CalculateProcess();
    if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
        return;
}

RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm()
{
}

void
RegisterContextPOSIX_arm::Invalidate()
{
}

void
RegisterContextPOSIX_arm::InvalidateAllRegisters()
{
}

unsigned
RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg)
{
    assert(reg < m_reg_info.num_registers && "Invalid register number.");
    return GetRegisterInfo()[reg].byte_offset;
}

unsigned
RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg)
{
    assert(reg < m_reg_info.num_registers && "Invalid register number.");
    return GetRegisterInfo()[reg].byte_size;
}

size_t
RegisterContextPOSIX_arm::GetRegisterCount()
{
    size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
    return num_registers;
}

size_t
RegisterContextPOSIX_arm::GetGPRSize()
{
    return m_register_info_ap->GetGPRSize ();
}

const lldb_private::RegisterInfo *
RegisterContextPOSIX_arm::GetRegisterInfo()
{
    // Commonly, this method is overridden and g_register_infos is copied and specialized.
    // So, use GetRegisterInfo() rather than g_register_infos in this scope.
    return m_register_info_ap->GetRegisterInfo ();
}

const lldb_private::RegisterInfo *
RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg)
{
    if (reg < m_reg_info.num_registers)
        return &GetRegisterInfo()[reg];
    else
        return NULL;
}

size_t
RegisterContextPOSIX_arm::GetRegisterSetCount()
{
    size_t sets = 0;
    for (size_t set = 0; set < k_num_register_sets; ++set)
    {
        if (IsRegisterSetAvailable(set))
            ++sets;
    }

    return sets;
}

const lldb_private::RegisterSet *
RegisterContextPOSIX_arm::GetRegisterSet(size_t set)
{
    if (IsRegisterSetAvailable(set))
    {
        switch (m_register_info_ap->m_target_arch.GetMachine())
        {
            case llvm::Triple::arm:
                return &g_reg_sets_arm[set];
            default:
                assert(false && "Unhandled target architecture.");
                return NULL;
        }
    }
    return NULL;
}

const char *
RegisterContextPOSIX_arm::GetRegisterName(unsigned reg)
{
    assert(reg < m_reg_info.num_registers && "Invalid register offset.");
    return GetRegisterInfo()[reg].name;
}

lldb::ByteOrder
RegisterContextPOSIX_arm::GetByteOrder()
{
    // Get the target process whose privileged thread was used for the register read.
    lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
    lldb_private::Process *process = CalculateProcess().get();

    if (process)
        byte_order = process->GetByteOrder();
    return byte_order;
}

bool
RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index)
{
    return set_index < k_num_register_sets;
}


// Used when parsing DWARF and EH frame information and any other
// object file sections that contain register numbers in them. 
uint32_t
RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
                                                                uint32_t num)
{
    const uint32_t num_regs = GetRegisterCount();

    assert (kind < lldb::kNumRegisterKinds);
    for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
    {
        const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);

        if (reg_info->kinds[kind] == num)
            return reg_idx;
    }

    return LLDB_INVALID_REGNUM;
}

