Add PowerPC FPR access to the process monitor

Summary: This adds reading and writing to the POSIX PowerPC ProcessMonitor.

Reviewers: emaste

Reviewed By: emaste

Subscribers: emaste, lldb-commits

Differential Revision: http://reviews.llvm.org/D7040

llvm-svn: 228277
This commit is contained in:
Justin Hibbits 2015-02-05 07:10:11 +00:00
parent ed83ebd77e
commit b07ee8ded9
2 changed files with 23 additions and 21 deletions

View File

@ -45,8 +45,8 @@ RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR()
bool bool
RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR() RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR()
{ {
// XXX not yet implemented ProcessMonitor &monitor = GetMonitor();
return false; return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
} }
bool bool
@ -59,8 +59,8 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR()
bool bool
RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR() RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR()
{ {
// XXX not yet implemented ProcessMonitor &monitor = GetMonitor();
return false; return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
} }
bool bool
@ -146,26 +146,15 @@ RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const RegisterInfo *reg
{ {
if (!ReadFPR()) if (!ReadFPR())
return false; return false;
uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
value.SetUInt64(*(uint64_t*)src);
} }
else else if (IsGPR(reg))
{ {
uint32_t full_reg = reg; bool success = ReadRegister(reg, value);
bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
if (is_subreg)
{
// Read the full aligned 64-bit register.
full_reg = reg_info->invalidate_regs[0];
}
bool success = ReadRegister(full_reg, value);
if (success) if (success)
{ {
// If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
if (is_subreg && (reg_info->byte_offset & 0x1))
value.SetUInt64(value.GetAsUInt64() >> 8);
// If our return byte size was greater than the return value reg size, then // If our return byte size was greater than the return value reg size, then
// use the type specified by reg_info rather than the uint64_t default // use the type specified by reg_info rather than the uint64_t default
if (value.GetByteSize() > reg_info->byte_size) if (value.GetByteSize() > reg_info->byte_size)
@ -183,7 +172,16 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const RegisterInfo *re
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
if (IsGPR(reg)) if (IsGPR(reg))
{
return WriteRegister(reg, value); return WriteRegister(reg, value);
}
else if (IsFPR(reg))
{
assert (reg_info->byte_offset < sizeof(m_fpr_powerpc));
uint8_t *dst = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
*(uint64_t *)dst = value.GetAsUInt64();
return WriteFPR();
}
return false; return false;
} }
@ -221,6 +219,9 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(const DataBuf
if (WriteGPR()) if (WriteGPR())
{ {
src += GetGPRSize(); src += GetGPRSize();
::memcpy (&m_fpr_powerpc, src, sizeof(m_fpr_powerpc));
success = WriteFPR();
} }
} }
} }

View File

@ -147,6 +147,7 @@ public:
protected: protected:
uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers. uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers.
uint64_t m_fpr_powerpc[k_num_fpr_registers_powerpc]; // floating point registers.
std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux) std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
// Determines if an extended register set is supported on the processor running the inferior process. // Determines if an extended register set is supported on the processor running the inferior process.