]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / elf-core / RegisterContextPOSIXCore_ppc64le.cpp
1 //===-- RegisterContextPOSIXCore_ppc64le.cpp --------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "RegisterContextPOSIXCore_ppc64le.h"
11
12 #include "lldb/Target/Thread.h"
13 #include "lldb/Utility/DataBufferHeap.h"
14 #include "lldb/Utility/RegisterValue.h"
15
16 #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
17 #include "Plugins/Process/elf-core/RegisterUtilities.h"
18
19 using namespace lldb_private;
20
21 RegisterContextCorePOSIX_ppc64le::RegisterContextCorePOSIX_ppc64le(
22     Thread &thread, RegisterInfoInterface *register_info,
23     const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
24     : RegisterContextPOSIX_ppc64le(thread, 0, register_info) {
25   m_gpr_buffer.reset(
26       new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
27   m_gpr.SetData(m_gpr_buffer);
28   m_gpr.SetByteOrder(gpregset.GetByteOrder());
29
30   ArchSpec arch = register_info->GetTargetArchitecture();
31   DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc);
32   m_fpr_buffer.reset(
33       new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
34   m_fpr.SetData(m_fpr_buffer);
35   m_fpr.SetByteOrder(fpregset.GetByteOrder());
36
37   DataExtractor vmxregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc);
38   m_vmx_buffer.reset(
39       new DataBufferHeap(vmxregset.GetDataStart(), vmxregset.GetByteSize()));
40   m_vmx.SetData(m_vmx_buffer);
41   m_vmx.SetByteOrder(vmxregset.GetByteOrder());
42
43   DataExtractor vsxregset = getRegset(notes, arch.GetTriple(), PPC_VSX_Desc);
44   m_vsx_buffer.reset(
45       new DataBufferHeap(vsxregset.GetDataStart(), vsxregset.GetByteSize()));
46   m_vsx.SetData(m_vsx_buffer);
47   m_vsx.SetByteOrder(vsxregset.GetByteOrder());
48 }
49
50 size_t RegisterContextCorePOSIX_ppc64le::GetFPRSize() const {
51   return k_num_fpr_registers_ppc64le * sizeof(uint64_t);
52 }
53
54 size_t RegisterContextCorePOSIX_ppc64le::GetVMXSize() const {
55   return (k_num_vmx_registers_ppc64le - 1) * sizeof(uint64_t) * 2 +
56          sizeof(uint32_t);
57 }
58
59 size_t RegisterContextCorePOSIX_ppc64le::GetVSXSize() const {
60   return k_num_vsx_registers_ppc64le * sizeof(uint64_t) * 2;
61 }
62
63 bool RegisterContextCorePOSIX_ppc64le::ReadRegister(
64     const RegisterInfo *reg_info, RegisterValue &value) {
65   lldb::offset_t offset = reg_info->byte_offset;
66
67   if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
68     uint64_t v;
69     offset -= GetGPRSize();
70     offset = m_fpr.CopyData(offset, reg_info->byte_size, &v);
71
72     if (offset == reg_info->byte_size) {
73       value.SetBytes(&v, reg_info->byte_size, m_fpr.GetByteOrder());
74       return true;
75     }
76   } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
77     uint32_t v[4];
78     offset -= GetGPRSize() + GetFPRSize();
79     offset = m_vmx.CopyData(offset, reg_info->byte_size, &v);
80
81     if (offset == reg_info->byte_size) {
82       value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder());
83       return true;
84     }
85   } else if (IsVSX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
86     uint32_t v[4];
87     lldb::offset_t tmp_offset;
88     offset -= GetGPRSize() + GetFPRSize() + GetVMXSize();
89
90     if (offset < GetVSXSize() / 2) {
91       tmp_offset = m_vsx.CopyData(offset / 2, reg_info->byte_size / 2, &v);
92
93       if (tmp_offset != reg_info->byte_size / 2) {
94         return false;
95       }
96
97       uint8_t *dst = (uint8_t *)&v + sizeof(uint64_t);
98       tmp_offset = m_fpr.CopyData(offset / 2, reg_info->byte_size / 2, dst);
99
100       if (tmp_offset != reg_info->byte_size / 2) {
101         return false;
102       }
103
104       value.SetBytes(&v, reg_info->byte_size, m_vsx.GetByteOrder());
105       return true;
106     } else {
107       offset =
108           m_vmx.CopyData(offset - GetVSXSize() / 2, reg_info->byte_size, &v);
109       if (offset == reg_info->byte_size) {
110         value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder());
111         return true;
112       }
113     }
114   } else {
115     uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
116
117     if (offset == reg_info->byte_offset + reg_info->byte_size) {
118       if (reg_info->byte_size < sizeof(v))
119         value = (uint32_t)v;
120       else
121         value = v;
122       return true;
123     }
124   }
125
126   return false;
127 }
128
129 bool RegisterContextCorePOSIX_ppc64le::WriteRegister(
130     const RegisterInfo *reg_info, const RegisterValue &value) {
131   return false;
132 }