RegisterContextPOSIXCore_ppc64le.cpp revision 326949
1326949Sdim//===-- RegisterContextPOSIXCore_ppc64le.cpp --------------------*- C++ -*-===// 2326949Sdim// 3326949Sdim// The LLVM Compiler Infrastructure 4326949Sdim// 5326949Sdim// This file is distributed under the University of Illinois Open Source 6326949Sdim// License. See LICENSE.TXT for details. 7326949Sdim// 8326949Sdim//===----------------------------------------------------------------------===// 9326949Sdim 10326949Sdim#include "RegisterContextPOSIXCore_ppc64le.h" 11326949Sdim 12326949Sdim#include "lldb/Core/RegisterValue.h" 13326949Sdim#include "lldb/Target/Thread.h" 14326949Sdim#include "lldb/Utility/DataBufferHeap.h" 15326949Sdim 16326949Sdim#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" 17326949Sdim#include "Plugins/Process/elf-core/RegisterUtilities.h" 18326949Sdim 19326949Sdimusing namespace lldb_private; 20326949Sdim 21326949SdimRegisterContextCorePOSIX_ppc64le::RegisterContextCorePOSIX_ppc64le( 22326949Sdim Thread &thread, RegisterInfoInterface *register_info, 23326949Sdim const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes) 24326949Sdim : RegisterContextPOSIX_ppc64le(thread, 0, register_info) { 25326949Sdim m_gpr_buffer.reset( 26326949Sdim new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); 27326949Sdim m_gpr.SetData(m_gpr_buffer); 28326949Sdim m_gpr.SetByteOrder(gpregset.GetByteOrder()); 29326949Sdim 30326949Sdim ArchSpec arch = register_info->GetTargetArchitecture(); 31326949Sdim DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc); 32326949Sdim m_fpr_buffer.reset( 33326949Sdim new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize())); 34326949Sdim m_fpr.SetData(m_fpr_buffer); 35326949Sdim m_fpr.SetByteOrder(fpregset.GetByteOrder()); 36326949Sdim 37326949Sdim DataExtractor vmxregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc); 38326949Sdim m_vmx_buffer.reset( 39326949Sdim new DataBufferHeap(vmxregset.GetDataStart(), vmxregset.GetByteSize())); 40326949Sdim m_vmx.SetData(m_vmx_buffer); 41326949Sdim m_vmx.SetByteOrder(vmxregset.GetByteOrder()); 42326949Sdim 43326949Sdim DataExtractor vsxregset = getRegset(notes, arch.GetTriple(), PPC_VSX_Desc); 44326949Sdim m_vsx_buffer.reset( 45326949Sdim new DataBufferHeap(vsxregset.GetDataStart(), vsxregset.GetByteSize())); 46326949Sdim m_vsx.SetData(m_vsx_buffer); 47326949Sdim m_vsx.SetByteOrder(vsxregset.GetByteOrder()); 48326949Sdim} 49326949Sdim 50326949Sdimsize_t RegisterContextCorePOSIX_ppc64le::GetFPRSize() const { 51326949Sdim return k_num_fpr_registers_ppc64le * sizeof(uint64_t); 52326949Sdim} 53326949Sdim 54326949Sdimsize_t RegisterContextCorePOSIX_ppc64le::GetVMXSize() const { 55326949Sdim return (k_num_vmx_registers_ppc64le - 1) * sizeof(uint64_t) * 2 + 56326949Sdim sizeof(uint32_t); 57326949Sdim} 58326949Sdim 59326949Sdimsize_t RegisterContextCorePOSIX_ppc64le::GetVSXSize() const { 60326949Sdim return k_num_vsx_registers_ppc64le * sizeof(uint64_t) * 2; 61326949Sdim} 62326949Sdim 63326949Sdimbool RegisterContextCorePOSIX_ppc64le::ReadRegister( 64326949Sdim const RegisterInfo *reg_info, RegisterValue &value) { 65326949Sdim lldb::offset_t offset = reg_info->byte_offset; 66326949Sdim 67326949Sdim if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) { 68326949Sdim uint64_t v; 69326949Sdim offset -= GetGPRSize(); 70326949Sdim offset = m_fpr.CopyData(offset, reg_info->byte_size, &v); 71326949Sdim 72326949Sdim if (offset == reg_info->byte_size) { 73326949Sdim value.SetBytes(&v, reg_info->byte_size, m_fpr.GetByteOrder()); 74326949Sdim return true; 75326949Sdim } 76326949Sdim } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) { 77326949Sdim uint32_t v[4]; 78326949Sdim offset -= GetGPRSize() + GetFPRSize(); 79326949Sdim offset = m_vmx.CopyData(offset, reg_info->byte_size, &v); 80326949Sdim 81326949Sdim if (offset == reg_info->byte_size) { 82326949Sdim value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder()); 83326949Sdim return true; 84326949Sdim } 85326949Sdim } else if (IsVSX(reg_info->kinds[lldb::eRegisterKindLLDB])) { 86326949Sdim uint32_t v[4]; 87326949Sdim lldb::offset_t tmp_offset; 88326949Sdim offset -= GetGPRSize() + GetFPRSize() + GetVMXSize(); 89326949Sdim 90326949Sdim if (offset < GetVSXSize() / 2) { 91326949Sdim tmp_offset = m_vsx.CopyData(offset / 2, reg_info->byte_size / 2, &v); 92326949Sdim 93326949Sdim if (tmp_offset != reg_info->byte_size / 2) { 94326949Sdim return false; 95326949Sdim } 96326949Sdim 97326949Sdim uint8_t *dst = (uint8_t *)&v + sizeof(uint64_t); 98326949Sdim tmp_offset = m_fpr.CopyData(offset / 2, reg_info->byte_size / 2, dst); 99326949Sdim 100326949Sdim if (tmp_offset != reg_info->byte_size / 2) { 101326949Sdim return false; 102326949Sdim } 103326949Sdim 104326949Sdim value.SetBytes(&v, reg_info->byte_size, m_vsx.GetByteOrder()); 105326949Sdim return true; 106326949Sdim } else { 107326949Sdim offset = 108326949Sdim m_vmx.CopyData(offset - GetVSXSize() / 2, reg_info->byte_size, &v); 109326949Sdim if (offset == reg_info->byte_size) { 110326949Sdim value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder()); 111326949Sdim return true; 112326949Sdim } 113326949Sdim } 114326949Sdim } else { 115326949Sdim uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); 116326949Sdim 117326949Sdim if (offset == reg_info->byte_offset + reg_info->byte_size) { 118326949Sdim if (reg_info->byte_size < sizeof(v)) 119326949Sdim value = (uint32_t)v; 120326949Sdim else 121326949Sdim value = v; 122326949Sdim return true; 123326949Sdim } 124326949Sdim } 125326949Sdim 126326949Sdim return false; 127326949Sdim} 128326949Sdim 129326949Sdimbool RegisterContextCorePOSIX_ppc64le::WriteRegister( 130326949Sdim const RegisterInfo *reg_info, const RegisterValue &value) { 131326949Sdim return false; 132326949Sdim} 133