Skip to content

Commit

Permalink
Implement initial Altivec support
Browse files Browse the repository at this point in the history
Summary:
This adds the register plumbing, as well as register reading in FreeBSD core
dumps.  Further work on the POSIX/FreeBSD ProcessMonitor is required in order to
support ptrace access to these registers.

Reviewers: tfiala, emaste

Reviewed By: emaste

Subscribers: emaste, lldb-commits

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

llvm-svn: 228278
  • Loading branch information
Justin Hibbits committed Feb 5, 2015
1 parent b07ee8d commit f9ec0d1
Show file tree
Hide file tree
Showing 14 changed files with 317 additions and 20 deletions.
4 changes: 1 addition & 3 deletions lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
Expand Up @@ -685,9 +685,7 @@ ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
if (byte_size > 0)
{

const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v0", 0);
if (altivec_reg == NULL)
altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
if (altivec_reg)
{
if (byte_size <= altivec_reg->byte_size)
Expand Down
4 changes: 1 addition & 3 deletions lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
Expand Up @@ -685,9 +685,7 @@ ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
if (byte_size > 0)
{

const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v0", 0);
if (altivec_reg == NULL)
altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
if (altivec_reg)
{
if (byte_size <= altivec_reg->byte_size)
Expand Down
Expand Up @@ -49,6 +49,13 @@ RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR()
return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
}

bool
RegisterContextPOSIXProcessMonitor_powerpc::ReadVMX()
{
// XXX: Need a way to read/write process VMX registers with ptrace.
return false;
}

bool
RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR()
{
Expand All @@ -63,6 +70,13 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR()
return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
}

bool
RegisterContextPOSIXProcessMonitor_powerpc::WriteVMX()
{
// XXX: Need a way to read/write process VMX registers with ptrace.
return false;
}

bool
RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const unsigned reg,
RegisterValue &value)
Expand Down
Expand Up @@ -22,18 +22,27 @@ class RegisterContextPOSIXProcessMonitor_powerpc:
lldb_private::RegisterInfoInterface *register_info);

protected:
bool
IsVMX();

bool
ReadGPR();

bool
ReadFPR();

bool
ReadVMX();

bool
WriteGPR();

bool
WriteFPR();

bool
WriteVMX();

// lldb_private::RegisterContext
bool
ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
Expand Down
Expand Up @@ -134,6 +134,45 @@ typedef struct _FPR
uint64_t fpscr;
} FPR;

typedef struct _VMX
{
uint32_t v0[4];
uint32_t v1[4];
uint32_t v2[4];
uint32_t v3[4];
uint32_t v4[4];
uint32_t v5[4];
uint32_t v6[4];
uint32_t v7[4];
uint32_t v8[4];
uint32_t v9[4];
uint32_t v10[4];
uint32_t v11[4];
uint32_t v12[4];
uint32_t v13[4];
uint32_t v14[4];
uint32_t v15[4];
uint32_t v16[4];
uint32_t v17[4];
uint32_t v18[4];
uint32_t v19[4];
uint32_t v20[4];
uint32_t v21[4];
uint32_t v22[4];
uint32_t v23[4];
uint32_t v24[4];
uint32_t v25[4];
uint32_t v26[4];
uint32_t v27[4];
uint32_t v28[4];
uint32_t v29[4];
uint32_t v30[4];
uint32_t v31[4];
uint32_t pad[2];
uint32_t vrsave;
uint32_t vscr;
} VMX;

//---------------------------------------------------------------------------
// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc structure.
//---------------------------------------------------------------------------
Expand Down
Expand Up @@ -106,17 +106,57 @@ uint32_t g_fpr_regnums[] =
fpr_fpscr_powerpc,
};

static const
uint32_t g_vmx_regnums[] =
{
vmx_v0_powerpc,
vmx_v1_powerpc,
vmx_v2_powerpc,
vmx_v3_powerpc,
vmx_v4_powerpc,
vmx_v5_powerpc,
vmx_v6_powerpc,
vmx_v7_powerpc,
vmx_v8_powerpc,
vmx_v9_powerpc,
vmx_v10_powerpc,
vmx_v11_powerpc,
vmx_v12_powerpc,
vmx_v13_powerpc,
vmx_v14_powerpc,
vmx_v15_powerpc,
vmx_v16_powerpc,
vmx_v17_powerpc,
vmx_v18_powerpc,
vmx_v19_powerpc,
vmx_v20_powerpc,
vmx_v21_powerpc,
vmx_v22_powerpc,
vmx_v23_powerpc,
vmx_v24_powerpc,
vmx_v25_powerpc,
vmx_v26_powerpc,
vmx_v27_powerpc,
vmx_v28_powerpc,
vmx_v29_powerpc,
vmx_v30_powerpc,
vmx_v31_powerpc,
vmx_vrsave_powerpc,
vmx_vscr_powerpc,
};

// Number of register sets provided by this context.
enum
{
k_num_register_sets = 2
k_num_register_sets = 3
};

static const RegisterSet
g_reg_sets_powerpc[k_num_register_sets] =
{
{ "General Purpose Registers", "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
{ "Floating Point Registers", "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
{ "Altivec/VMX Registers", "vmx", k_num_vmx_registers_powerpc, g_vmx_regnums },
};

bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
Expand All @@ -127,10 +167,15 @@ bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
bool
RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
{
// XXX
return (reg >= k_first_fpr) && (reg <= k_last_fpr);
}

bool
RegisterContextPOSIX_powerpc::IsVMX(unsigned reg)
{
return (reg >= k_first_vmx) && (reg <= k_last_vmx);
}

RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
uint32_t concrete_frame_idx,
RegisterInfoInterface *register_info)
Expand Down
44 changes: 44 additions & 0 deletions lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
Expand Up @@ -97,9 +97,47 @@ enum
fpr_fpscr_powerpc,
k_last_fpr = fpr_fpscr_powerpc,

k_first_vmx,
vmx_v0_powerpc = k_first_vmx,
vmx_v1_powerpc,
vmx_v2_powerpc,
vmx_v3_powerpc,
vmx_v4_powerpc,
vmx_v5_powerpc,
vmx_v6_powerpc,
vmx_v7_powerpc,
vmx_v8_powerpc,
vmx_v9_powerpc,
vmx_v10_powerpc,
vmx_v11_powerpc,
vmx_v12_powerpc,
vmx_v13_powerpc,
vmx_v14_powerpc,
vmx_v15_powerpc,
vmx_v16_powerpc,
vmx_v17_powerpc,
vmx_v18_powerpc,
vmx_v19_powerpc,
vmx_v20_powerpc,
vmx_v21_powerpc,
vmx_v22_powerpc,
vmx_v23_powerpc,
vmx_v24_powerpc,
vmx_v25_powerpc,
vmx_v26_powerpc,
vmx_v27_powerpc,
vmx_v28_powerpc,
vmx_v29_powerpc,
vmx_v30_powerpc,
vmx_v31_powerpc,
vmx_vrsave_powerpc,
vmx_vscr_powerpc,
k_last_vmx = vmx_vscr_powerpc,

k_num_registers_powerpc,
k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1,
k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1,
k_num_vmx_registers_powerpc = k_last_vmx - k_first_vmx + 1,
};

class RegisterContextPOSIX_powerpc
Expand Down Expand Up @@ -148,6 +186,7 @@ class RegisterContextPOSIX_powerpc
protected:
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.
uint32_t m_vmx_powerpc[k_num_vmx_registers_powerpc][4];
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.
Expand All @@ -163,12 +202,17 @@ class RegisterContextPOSIX_powerpc
bool
IsFPR(unsigned reg);

bool
IsVMX(unsigned reg);

lldb::ByteOrder GetByteOrder();

virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
virtual bool ReadVMX() = 0;
virtual bool WriteGPR() = 0;
virtual bool WriteFPR() = 0;
virtual bool WriteVMX() = 0;
};

#endif // #ifndef liblldb_RegisterContextPOSIX_powerpc_H_
79 changes: 74 additions & 5 deletions lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h
Expand Up @@ -79,10 +79,45 @@ enum
gcc_dwarf_f31_powerpc,
gcc_dwarf_cr_powerpc,
gcc_dwarf_fpscr_powerpc,
gcc_dwarf_msr_powerpc,
gcc_dwarf_vscr_powerpc,
gcc_dwarf_xer_powerpc = 101,
gcc_dwarf_lr_powerpc = 108,
gcc_dwarf_ctr_powerpc,
gcc_dwarf_pc_powerpc,
gcc_dwarf_vrsave_powerpc = 356,
gcc_dwarf_v0_powerpc = 1124,
gcc_dwarf_v1_powerpc,
gcc_dwarf_v2_powerpc,
gcc_dwarf_v3_powerpc,
gcc_dwarf_v4_powerpc,
gcc_dwarf_v5_powerpc,
gcc_dwarf_v6_powerpc,
gcc_dwarf_v7_powerpc,
gcc_dwarf_v8_powerpc,
gcc_dwarf_v9_powerpc,
gcc_dwarf_v10_powerpc,
gcc_dwarf_v11_powerpc,
gcc_dwarf_v12_powerpc,
gcc_dwarf_v13_powerpc,
gcc_dwarf_v14_powerpc,
gcc_dwarf_v15_powerpc,
gcc_dwarf_v16_powerpc,
gcc_dwarf_v17_powerpc,
gcc_dwarf_v18_powerpc,
gcc_dwarf_v19_powerpc,
gcc_dwarf_v20_powerpc,
gcc_dwarf_v21_powerpc,
gcc_dwarf_v22_powerpc,
gcc_dwarf_v23_powerpc,
gcc_dwarf_v24_powerpc,
gcc_dwarf_v25_powerpc,
gcc_dwarf_v26_powerpc,
gcc_dwarf_v27_powerpc,
gcc_dwarf_v28_powerpc,
gcc_dwarf_v29_powerpc,
gcc_dwarf_v30_powerpc,
gcc_dwarf_v31_powerpc,
};

// GDB Register numbers (eRegisterKindGDB)
Expand Down Expand Up @@ -152,12 +187,46 @@ enum
gdb_f29_powerpc,
gdb_f30_powerpc,
gdb_f31_powerpc,
gdb_cr_powerpc,
gdb_fpscr_powerpc,
gdb_xer_powerpc = 101,
gdb_lr_powerpc = 108,
gdb_ctr_powerpc,
gdb_pc_powerpc,
gdb_cr_powerpc = 66,
gdb_lr_powerpc,
gdb_ctr_powerpc,
gdb_xer_powerpc,
gdb_fpscr_powerpc,
gdb_v0_powerpc = 106,
gdb_v1_powerpc,
gdb_v2_powerpc,
gdb_v3_powerpc,
gdb_v4_powerpc,
gdb_v5_powerpc,
gdb_v6_powerpc,
gdb_v7_powerpc,
gdb_v8_powerpc,
gdb_v9_powerpc,
gdb_v10_powerpc,
gdb_v11_powerpc,
gdb_v12_powerpc,
gdb_v13_powerpc,
gdb_v14_powerpc,
gdb_v15_powerpc,
gdb_v16_powerpc,
gdb_v17_powerpc,
gdb_v18_powerpc,
gdb_v19_powerpc,
gdb_v20_powerpc,
gdb_v21_powerpc,
gdb_v22_powerpc,
gdb_v23_powerpc,
gdb_v24_powerpc,
gdb_v25_powerpc,
gdb_v26_powerpc,
gdb_v27_powerpc,
gdb_v28_powerpc,
gdb_v29_powerpc,
gdb_v30_powerpc,
gdb_v31_powerpc,
gdb_vscr_powerpc,
gdb_vrsave_powerpc,
};

#endif // liblldb_RegisterContext_powerpc_H_

0 comments on commit f9ec0d1

Please sign in to comment.