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