//===-- RegisterContextPOSIX_powerpc.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_powerpc.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"

using namespace lldb_private;
using namespace lldb;

static const
uint32_t g_gpr_regnums[] =
{
    gpr_r0_powerpc,
    gpr_r1_powerpc,
    gpr_r2_powerpc,
    gpr_r3_powerpc,
    gpr_r4_powerpc,
    gpr_r5_powerpc,
    gpr_r6_powerpc,
    gpr_r7_powerpc,
    gpr_r8_powerpc,
    gpr_r9_powerpc,
    gpr_r10_powerpc,
    gpr_r11_powerpc,
    gpr_r12_powerpc,
    gpr_r13_powerpc,
    gpr_r14_powerpc,
    gpr_r15_powerpc,
    gpr_r16_powerpc,
    gpr_r17_powerpc,
    gpr_r18_powerpc,
    gpr_r19_powerpc,
    gpr_r20_powerpc,
    gpr_r21_powerpc,
    gpr_r22_powerpc,
    gpr_r23_powerpc,
    gpr_r24_powerpc,
    gpr_r25_powerpc,
    gpr_r26_powerpc,
    gpr_r27_powerpc,
    gpr_r28_powerpc,
    gpr_r29_powerpc,
    gpr_r30_powerpc,
    gpr_r31_powerpc,
    gpr_lr_powerpc,
    gpr_cr_powerpc,
    gpr_xer_powerpc,
    gpr_ctr_powerpc,
    gpr_pc_powerpc,
};

static const
uint32_t g_fpr_regnums[] =
{
    fpr_f0_powerpc,
    fpr_f1_powerpc,
    fpr_f2_powerpc,
    fpr_f3_powerpc,
    fpr_f4_powerpc,
    fpr_f5_powerpc,
    fpr_f6_powerpc,
    fpr_f7_powerpc,
    fpr_f8_powerpc,
    fpr_f9_powerpc,
    fpr_f10_powerpc,
    fpr_f11_powerpc,
    fpr_f12_powerpc,
    fpr_f13_powerpc,
    fpr_f14_powerpc,
    fpr_f15_powerpc,
    fpr_f16_powerpc,
    fpr_f17_powerpc,
    fpr_f18_powerpc,
    fpr_f19_powerpc,
    fpr_f20_powerpc,
    fpr_f21_powerpc,
    fpr_f22_powerpc,
    fpr_f23_powerpc,
    fpr_f24_powerpc,
    fpr_f25_powerpc,
    fpr_f26_powerpc,
    fpr_f27_powerpc,
    fpr_f28_powerpc,
    fpr_f29_powerpc,
    fpr_f30_powerpc,
    fpr_f31_powerpc,
    fpr_fpscr_powerpc,
};

static const
uint32_t g_vmx_regnums[] =
{
    vmx_v0_powerpc,
    vmx_v1_powerpc,
    vmx_v2_powerpc,
    vmx_v3_powerpc,
    vmx_v4_powerpc,
    vmx_v5_powerpc,
    vmx_v6_powerpc,
    vmx_v7_powerpc,
    vmx_v8_powerpc,
    vmx_v9_powerpc,
    vmx_v10_powerpc,
    vmx_v11_powerpc,
    vmx_v12_powerpc,
    vmx_v13_powerpc,
    vmx_v14_powerpc,
    vmx_v15_powerpc,
    vmx_v16_powerpc,
    vmx_v17_powerpc,
    vmx_v18_powerpc,
    vmx_v19_powerpc,
    vmx_v20_powerpc,
    vmx_v21_powerpc,
    vmx_v22_powerpc,
    vmx_v23_powerpc,
    vmx_v24_powerpc,
    vmx_v25_powerpc,
    vmx_v26_powerpc,
    vmx_v27_powerpc,
    vmx_v28_powerpc,
    vmx_v29_powerpc,
    vmx_v30_powerpc,
    vmx_v31_powerpc,
    vmx_vrsave_powerpc,
    vmx_vscr_powerpc,
};

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

static const RegisterSet
g_reg_sets_powerpc[k_num_register_sets] =
{
    { "General Purpose Registers",  "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
    { "Floating Point Registers",  "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
    { "Altivec/VMX Registers",  "vmx", k_num_vmx_registers_powerpc, g_vmx_regnums },
};

static_assert(k_first_gpr_powerpc == 0, "GPRs must index starting at 0, or fix IsGPR()");
bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
{
    return (reg <= k_last_gpr_powerpc);   // GPR's come first.
}

bool
RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
{
    return (reg >= k_first_fpr) && (reg <= k_last_fpr);
}

bool
RegisterContextPOSIX_powerpc::IsVMX(unsigned reg)
{
    return (reg >= k_first_vmx) && (reg <= k_last_vmx);
}

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

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

RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc()
{
}

void
RegisterContextPOSIX_powerpc::Invalidate()
{
}

void
RegisterContextPOSIX_powerpc::InvalidateAllRegisters()
{
}

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

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

size_t
RegisterContextPOSIX_powerpc::GetRegisterCount()
{
    size_t num_registers = k_num_registers_powerpc;
    return num_registers;
}

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

const RegisterInfo *
RegisterContextPOSIX_powerpc::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 RegisterInfo *
RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg)
{
    if (reg < k_num_registers_powerpc)
        return &GetRegisterInfo()[reg];
    else
        return NULL;
}

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

    return sets;
}

const RegisterSet *
RegisterContextPOSIX_powerpc::GetRegisterSet(size_t set)
{
    if (IsRegisterSetAvailable(set))
        return &g_reg_sets_powerpc[set];
    else
        return NULL;
}

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

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

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

bool
RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index)
{
    size_t num_sets = k_num_register_sets;

    return (set_index < num_sets);
}

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

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

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

    return LLDB_INVALID_REGNUM;
}

