aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSagar Thakur <sagar.thakur@imgtec.com>2015-06-05 05:47:54 +0000
committerSagar Thakur <sagar.thakur@imgtec.com>2015-06-05 05:47:54 +0000
commite650b0946e17f41781d27862595a0c948a4b73e9 (patch)
treef5d1a1a1d1225230f176ba5dafd40a007509000c
parent26630427de42129441d66df6e86661ac0018b679 (diff)
downloadlldb-e650b0946e17f41781d27862595a0c948a4b73e9.tar.gz
[lldb-server][MIPS] Read/Write FP registers in FR0 mode
Adding support for read/write FP registers in FR0 mode of mips. Reviewers: clayborg, tberghammer, jaydeep Subscribers: emaste, nitesh.jain, bhushan, mohit.bhakkad, lldb-commits Differential Revision: http://reviews.llvm.org/D10242 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@239132 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp57
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h9
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp13
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_mips.h8
4 files changed, 83 insertions, 4 deletions
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
index 9bce8a80a..ad8b2756c 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
@@ -592,6 +592,63 @@ NativeRegisterContextLinux_mips64::WriteAllRegisterValues (const lldb::DataBuffe
return error;
}
+Error
+NativeRegisterContextLinux_mips64::ReadFPR()
+{
+ void* buf = GetFPRBuffer();
+ if (!buf)
+ return Error("FPR buffer is NULL");
+
+ Error error = NativeRegisterContextLinux::ReadFPR();
+
+ if (IsFR0())
+ {
+ for (int i = 0; i < 16; i++)
+ {
+ // copy odd single from top of neighbouring even double
+ uint8_t * src = (uint8_t *)buf + 4 + (i * 16);
+ uint8_t * dst = (uint8_t *)buf + 8 + (i * 16);
+ *(uint32_t *) dst = *(uint32_t *) src;
+ }
+ }
+
+ return error;
+}
+
+Error
+NativeRegisterContextLinux_mips64::WriteFPR()
+{
+ void* buf = GetFPRBuffer();
+ if (!buf)
+ return Error("FPR buffer is NULL");
+
+ if (IsFR0())
+ {
+ for (int i = 0; i < 16; i++)
+ {
+ // copy odd single to top of neighbouring even double
+ uint8_t * src = (uint8_t *)buf + 8 + (i * 16);
+ uint8_t * dst = (uint8_t *)buf + 4 + (i * 16);
+ *(uint32_t *) dst = *(uint32_t *) src;
+ }
+ }
+
+ return NativeRegisterContextLinux::WriteFPR();
+}
+
+bool
+NativeRegisterContextLinux_mips64::IsFR0()
+{
+ const RegisterInfo *const reg_info_p = GetRegisterInfoAtIndex (36); // Status Register is at index 36 of the register array
+
+ RegisterValue reg_value;
+ ReadRegister (reg_info_p, reg_value);
+
+ uint64_t value = reg_value.GetAsUInt64();
+
+ return (!(value & 0x4000000));
+}
+
bool
NativeRegisterContextLinux_mips64::IsFPR(uint32_t reg_index) const
{
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
index 15ff877df..1c24c91c3 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
@@ -47,6 +47,12 @@ namespace process_linux {
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
Error
+ ReadFPR() override;
+
+ Error
+ WriteFPR() override;
+
+ Error
IsWatchpointHit (uint32_t wp_index, bool &is_hit) override;
Error
@@ -85,6 +91,9 @@ namespace process_linux {
const RegisterValue &value) override;
bool
+ IsFR0();
+
+ bool
IsFPR(uint32_t reg_index) const;
void*
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
index 3cbb823c6..a762930e8 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
@@ -74,6 +74,13 @@ typedef struct _GPR
#include "RegisterInfos_mips64.h"
#undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
+//---------------------------------------------------------------------------
+// Include RegisterInfos_mips to declare our g_register_infos_mips structure.
+//---------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_MIPS_STRUCT
+#include "RegisterInfos_mips.h"
+#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
+
static const RegisterInfo *
GetRegisterInfoPtr (const ArchSpec &target_arch)
{
@@ -81,9 +88,10 @@ GetRegisterInfoPtr (const ArchSpec &target_arch)
{
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
+ return g_register_infos_mips64;
case llvm::Triple::mips:
case llvm::Triple::mipsel:
- return g_register_infos_mips64;
+ return g_register_infos_mips;
default:
assert(false && "Unhandled target architecture.");
return nullptr;
@@ -97,9 +105,10 @@ GetRegisterInfoCount (const ArchSpec &target_arch)
{
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
+ return static_cast<uint32_t> (sizeof (g_register_infos_mips64) / sizeof (g_register_infos_mips64 [0]));
case llvm::Triple::mips:
case llvm::Triple::mipsel:
- return static_cast<uint32_t> (sizeof (g_register_infos_mips64) / sizeof (g_register_infos_mips64 [0]));
+ return static_cast<uint32_t> (sizeof (g_register_infos_mips) / sizeof (g_register_infos_mips [0]));
default:
assert(false && "Unhandled target architecture.");
return 0;
diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips.h b/source/Plugins/Process/Utility/RegisterInfos_mips.h
index ddfb98ab8..0956b2ca9 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_mips.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_mips.h
@@ -26,6 +26,10 @@
eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips }, NULL, NULL }
#define DEFINE_FPR(member, reg, alt, kind1, kind2, kind3, kind4) \
+ { #reg, alt, sizeof(((FPR_mips*)NULL)->member) / 2, FPR_OFFSET(member), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL }
+
+#define DEFINE_FPR_INFO(member, reg, alt, kind1, kind2, kind3, kind4) \
{ #reg, alt, sizeof(((FPR_mips*)NULL)->member), FPR_OFFSET(member), eEncodingUint, \
eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL }
@@ -104,8 +108,8 @@ g_register_infos_mips[] =
DEFINE_FPR (fp_reg[29], f29, NULL, gcc_dwarf_f29_mips, gcc_dwarf_f29_mips, LLDB_INVALID_REGNUM, gdb_f29_mips),
DEFINE_FPR (fp_reg[30], f30, NULL, gcc_dwarf_f30_mips, gcc_dwarf_f30_mips, LLDB_INVALID_REGNUM, gdb_f30_mips),
DEFINE_FPR (fp_reg[31], f31, NULL, gcc_dwarf_f31_mips, gcc_dwarf_f31_mips, LLDB_INVALID_REGNUM, gdb_f31_mips),
- DEFINE_FPR (fcsr, fcsr, NULL, gcc_dwarf_fcsr_mips, gcc_dwarf_fcsr_mips, LLDB_INVALID_REGNUM, gdb_fcsr_mips),
- DEFINE_FPR (fir, fir, NULL, gcc_dwarf_fir_mips, gcc_dwarf_fir_mips, LLDB_INVALID_REGNUM, gdb_fir_mips)
+ DEFINE_FPR_INFO (fcsr, fcsr, NULL, gcc_dwarf_fcsr_mips, gcc_dwarf_fcsr_mips, LLDB_INVALID_REGNUM, gdb_fcsr_mips),
+ DEFINE_FPR_INFO (fir, fir, NULL, gcc_dwarf_fir_mips, gcc_dwarf_fir_mips, LLDB_INVALID_REGNUM, gdb_fir_mips)
};
static_assert((sizeof(g_register_infos_mips) / sizeof(g_register_infos_mips[0])) == k_num_registers_mips,
"g_register_infos_mips has wrong number of register infos");