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

#include "RegisterContextPOSIXCore_ppc64le.h"

#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"

#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"

using namespace lldb_private;

RegisterContextCorePOSIX_ppc64le::RegisterContextCorePOSIX_ppc64le(
    Thread &thread, RegisterInfoInterface *register_info,
    const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
    : RegisterContextPOSIX_ppc64le(thread, 0, register_info) {
  m_gpr_buffer.reset(
      new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
  m_gpr.SetData(m_gpr_buffer);
  m_gpr.SetByteOrder(gpregset.GetByteOrder());

  ArchSpec arch = register_info->GetTargetArchitecture();
  DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc);
  m_fpr_buffer.reset(
      new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
  m_fpr.SetData(m_fpr_buffer);
  m_fpr.SetByteOrder(fpregset.GetByteOrder());

  DataExtractor vmxregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc);
  m_vmx_buffer.reset(
      new DataBufferHeap(vmxregset.GetDataStart(), vmxregset.GetByteSize()));
  m_vmx.SetData(m_vmx_buffer);
  m_vmx.SetByteOrder(vmxregset.GetByteOrder());

  DataExtractor vsxregset = getRegset(notes, arch.GetTriple(), PPC_VSX_Desc);
  m_vsx_buffer.reset(
      new DataBufferHeap(vsxregset.GetDataStart(), vsxregset.GetByteSize()));
  m_vsx.SetData(m_vsx_buffer);
  m_vsx.SetByteOrder(vsxregset.GetByteOrder());
}

size_t RegisterContextCorePOSIX_ppc64le::GetFPRSize() const {
  return k_num_fpr_registers_ppc64le * sizeof(uint64_t);
}

size_t RegisterContextCorePOSIX_ppc64le::GetVMXSize() const {
  return (k_num_vmx_registers_ppc64le - 1) * sizeof(uint64_t) * 2 +
         sizeof(uint32_t);
}

size_t RegisterContextCorePOSIX_ppc64le::GetVSXSize() const {
  return k_num_vsx_registers_ppc64le * sizeof(uint64_t) * 2;
}

bool RegisterContextCorePOSIX_ppc64le::ReadRegister(
    const RegisterInfo *reg_info, RegisterValue &value) {
  lldb::offset_t offset = reg_info->byte_offset;

  if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
    uint64_t v;
    offset -= GetGPRSize();
    offset = m_fpr.CopyData(offset, reg_info->byte_size, &v);

    if (offset == reg_info->byte_size) {
      value.SetBytes(&v, reg_info->byte_size, m_fpr.GetByteOrder());
      return true;
    }
  } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
    uint32_t v[4];
    offset -= GetGPRSize() + GetFPRSize();
    offset = m_vmx.CopyData(offset, reg_info->byte_size, &v);

    if (offset == reg_info->byte_size) {
      value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder());
      return true;
    }
  } else if (IsVSX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
    uint32_t v[4];
    lldb::offset_t tmp_offset;
    offset -= GetGPRSize() + GetFPRSize() + GetVMXSize();

    if (offset < GetVSXSize() / 2) {
      tmp_offset = m_vsx.CopyData(offset / 2, reg_info->byte_size / 2, &v);

      if (tmp_offset != reg_info->byte_size / 2) {
        return false;
      }

      uint8_t *dst = (uint8_t *)&v + sizeof(uint64_t);
      tmp_offset = m_fpr.CopyData(offset / 2, reg_info->byte_size / 2, dst);

      if (tmp_offset != reg_info->byte_size / 2) {
        return false;
      }

      value.SetBytes(&v, reg_info->byte_size, m_vsx.GetByteOrder());
      return true;
    } else {
      offset =
          m_vmx.CopyData(offset - GetVSXSize() / 2, reg_info->byte_size, &v);
      if (offset == reg_info->byte_size) {
        value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder());
        return true;
      }
    }
  } else {
    uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);

    if (offset == reg_info->byte_offset + reg_info->byte_size) {
      if (reg_info->byte_size < sizeof(v))
        value = (uint32_t)v;
      else
        value = v;
      return true;
    }
  }

  return false;
}

bool RegisterContextCorePOSIX_ppc64le::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &value) {
  return false;
}
