1326949Sdim//===-- RegisterContextPOSIXCore_ppc64le.cpp --------------------*- C++ -*-===// 2326949Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6326949Sdim// 7326949Sdim//===----------------------------------------------------------------------===// 8326949Sdim 9326949Sdim#include "RegisterContextPOSIXCore_ppc64le.h" 10326949Sdim 11326949Sdim#include "lldb/Target/Thread.h" 12326949Sdim#include "lldb/Utility/DataBufferHeap.h" 13344779Sdim#include "lldb/Utility/RegisterValue.h" 14326949Sdim 15326949Sdim#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" 16326949Sdim#include "Plugins/Process/elf-core/RegisterUtilities.h" 17326949Sdim 18353358Sdim#include <memory> 19353358Sdim 20326949Sdimusing namespace lldb_private; 21326949Sdim 22326949SdimRegisterContextCorePOSIX_ppc64le::RegisterContextCorePOSIX_ppc64le( 23326949Sdim Thread &thread, RegisterInfoInterface *register_info, 24326949Sdim const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes) 25326949Sdim : RegisterContextPOSIX_ppc64le(thread, 0, register_info) { 26353358Sdim m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(), 27353358Sdim gpregset.GetByteSize()); 28326949Sdim m_gpr.SetData(m_gpr_buffer); 29326949Sdim m_gpr.SetByteOrder(gpregset.GetByteOrder()); 30326949Sdim 31326949Sdim ArchSpec arch = register_info->GetTargetArchitecture(); 32326949Sdim DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc); 33353358Sdim m_fpr_buffer = std::make_shared<DataBufferHeap>(fpregset.GetDataStart(), 34353358Sdim fpregset.GetByteSize()); 35326949Sdim m_fpr.SetData(m_fpr_buffer); 36326949Sdim m_fpr.SetByteOrder(fpregset.GetByteOrder()); 37326949Sdim 38326949Sdim DataExtractor vmxregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc); 39353358Sdim m_vmx_buffer = std::make_shared<DataBufferHeap>(vmxregset.GetDataStart(), 40353358Sdim vmxregset.GetByteSize()); 41326949Sdim m_vmx.SetData(m_vmx_buffer); 42326949Sdim m_vmx.SetByteOrder(vmxregset.GetByteOrder()); 43326949Sdim 44326949Sdim DataExtractor vsxregset = getRegset(notes, arch.GetTriple(), PPC_VSX_Desc); 45353358Sdim m_vsx_buffer = std::make_shared<DataBufferHeap>(vsxregset.GetDataStart(), 46353358Sdim vsxregset.GetByteSize()); 47326949Sdim m_vsx.SetData(m_vsx_buffer); 48326949Sdim m_vsx.SetByteOrder(vsxregset.GetByteOrder()); 49326949Sdim} 50326949Sdim 51326949Sdimsize_t RegisterContextCorePOSIX_ppc64le::GetFPRSize() const { 52326949Sdim return k_num_fpr_registers_ppc64le * sizeof(uint64_t); 53326949Sdim} 54326949Sdim 55326949Sdimsize_t RegisterContextCorePOSIX_ppc64le::GetVMXSize() const { 56326949Sdim return (k_num_vmx_registers_ppc64le - 1) * sizeof(uint64_t) * 2 + 57326949Sdim sizeof(uint32_t); 58326949Sdim} 59326949Sdim 60326949Sdimsize_t RegisterContextCorePOSIX_ppc64le::GetVSXSize() const { 61326949Sdim return k_num_vsx_registers_ppc64le * sizeof(uint64_t) * 2; 62326949Sdim} 63326949Sdim 64326949Sdimbool RegisterContextCorePOSIX_ppc64le::ReadRegister( 65326949Sdim const RegisterInfo *reg_info, RegisterValue &value) { 66326949Sdim lldb::offset_t offset = reg_info->byte_offset; 67326949Sdim 68326949Sdim if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) { 69326949Sdim uint64_t v; 70326949Sdim offset -= GetGPRSize(); 71326949Sdim offset = m_fpr.CopyData(offset, reg_info->byte_size, &v); 72326949Sdim 73326949Sdim if (offset == reg_info->byte_size) { 74326949Sdim value.SetBytes(&v, reg_info->byte_size, m_fpr.GetByteOrder()); 75326949Sdim return true; 76326949Sdim } 77326949Sdim } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) { 78326949Sdim uint32_t v[4]; 79326949Sdim offset -= GetGPRSize() + GetFPRSize(); 80326949Sdim offset = m_vmx.CopyData(offset, reg_info->byte_size, &v); 81326949Sdim 82326949Sdim if (offset == reg_info->byte_size) { 83326949Sdim value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder()); 84326949Sdim return true; 85326949Sdim } 86326949Sdim } else if (IsVSX(reg_info->kinds[lldb::eRegisterKindLLDB])) { 87326949Sdim uint32_t v[4]; 88326949Sdim lldb::offset_t tmp_offset; 89326949Sdim offset -= GetGPRSize() + GetFPRSize() + GetVMXSize(); 90326949Sdim 91326949Sdim if (offset < GetVSXSize() / 2) { 92326949Sdim tmp_offset = m_vsx.CopyData(offset / 2, reg_info->byte_size / 2, &v); 93326949Sdim 94326949Sdim if (tmp_offset != reg_info->byte_size / 2) { 95326949Sdim return false; 96326949Sdim } 97326949Sdim 98326949Sdim uint8_t *dst = (uint8_t *)&v + sizeof(uint64_t); 99326949Sdim tmp_offset = m_fpr.CopyData(offset / 2, reg_info->byte_size / 2, dst); 100326949Sdim 101326949Sdim if (tmp_offset != reg_info->byte_size / 2) { 102326949Sdim return false; 103326949Sdim } 104326949Sdim 105326949Sdim value.SetBytes(&v, reg_info->byte_size, m_vsx.GetByteOrder()); 106326949Sdim return true; 107326949Sdim } else { 108326949Sdim offset = 109326949Sdim m_vmx.CopyData(offset - GetVSXSize() / 2, reg_info->byte_size, &v); 110326949Sdim if (offset == reg_info->byte_size) { 111326949Sdim value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder()); 112326949Sdim return true; 113326949Sdim } 114326949Sdim } 115326949Sdim } else { 116326949Sdim uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); 117326949Sdim 118326949Sdim if (offset == reg_info->byte_offset + reg_info->byte_size) { 119326949Sdim if (reg_info->byte_size < sizeof(v)) 120326949Sdim value = (uint32_t)v; 121326949Sdim else 122326949Sdim value = v; 123326949Sdim return true; 124326949Sdim } 125326949Sdim } 126326949Sdim 127326949Sdim return false; 128326949Sdim} 129326949Sdim 130326949Sdimbool RegisterContextCorePOSIX_ppc64le::WriteRegister( 131326949Sdim const RegisterInfo *reg_info, const RegisterValue &value) { 132326949Sdim return false; 133326949Sdim} 134