blob: 2237e72353acf552fcde88d022d60451f88cc7dc [file] [log] [blame]
//===-- 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;
}