diff mbox

[06/24] mips-linux-nat: pick fp64 target description when appropriate

Message ID 1467038991-6600-6-git-send-email-bhushan.attarde@imgtec.com
State New
Headers show

Commit Message

Bhushan Attarde June 27, 2016, 2:49 p.m. UTC
This is decided by reading MIPS FIR register using prace and checking it's
    F64 bit.

    gdb/ChangeLog:

    * mips-linux-nat.c: Include "features/mips-fpu64-linux.c" and
    "features/mips-fpu64-dsp-linux.c".
    (FIR_F64): New definaition for F64 bit of FIR register.
    (supply_fpregset, fill_fpregset): Use 64-bit functions.
    (mips_linux_read_description): New have_fpu64 variable to indicate 64-bit
    FPU target.
    (initialize_tdesc_mips_fpu64_linux, initialize_tdesc_mips_fpu64_dsp_linux):
    Add initializer functions for fpu64 and fpu64_dsp targets.
---
 gdb/mips-linux-nat.c | 55 +++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 44 insertions(+), 11 deletions(-)
diff mbox

Patch

diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index 627c652..543cc36 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -40,6 +40,8 @@ 
 
 #include "features/mips-linux.c"
 #include "features/mips-dsp-linux.c"
+#include "features/mips-fpu64-linux.c"
+#include "features/mips-fpu64-dsp-linux.c"
 #include "features/mips64-linux.c"
 #include "features/mips64-dsp-linux.c"
 
@@ -55,6 +57,8 @@ 
 #define PTRACE_SETREGSET	0x4205
 #endif
 
+#define FIR_F64	  (1 << 22)
+
 /* Assume that we have PTRACE_GETREGS et al. support.  If we do not,
    we'll clear this and use PTRACE_PEEKUSER instead.  */
 static int have_ptrace_regsets = 1;
@@ -203,22 +207,16 @@  fill_gregset (const struct regcache *regcache,
 void
 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
 {
-  if (mips_isa_regsize (get_regcache_arch (regcache)) == 4)
-    mips_supply_fpregset (regcache, (const mips_elf_fpregset_t *) fpregsetp);
-  else
-    mips64_supply_fpregset (regcache,
-			    (const mips64_elf_fpregset_t *) fpregsetp);
+  mips64_supply_fpregset (regcache,
+			  (const mips64_elf_fpregset_t *) fpregsetp);
 }
 
 void
 fill_fpregset (const struct regcache *regcache,
 	       gdb_fpregset_t *fpregsetp, int regno)
 {
-  if (mips_isa_regsize (get_regcache_arch (regcache)) == 4)
-    mips_fill_fpregset (regcache, (mips_elf_fpregset_t *) fpregsetp, regno);
-  else
-    mips64_fill_fpregset (regcache,
-			  (mips64_elf_fpregset_t *) fpregsetp, regno);
+  mips64_fill_fpregset (regcache,
+			(mips64_elf_fpregset_t *) fpregsetp, regno);
 }
 
 
@@ -604,8 +602,41 @@  mips_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
 static const struct target_desc *
 mips_linux_read_description (struct target_ops *ops)
 {
+  const struct target_desc *tdescs[2][2] =
+    {
+	/* have_fpu64 = 0	have_fpu64 = 1 */
+	{ tdesc_mips_linux,	tdesc_mips_fpu64_linux },     /* have_dsp = 0 */
+	{ tdesc_mips_dsp_linux,	tdesc_mips_fpu64_dsp_linux }, /* have_dsp = 1 */
+    };
+
   static int have_dsp = -1;
+  static int have_fpu64 = -1;
 
+  if (have_fpu64 < 0)
+    {
+      int tid;
+      long fir;
+
+      tid = ptid_get_lwp (inferior_ptid);
+      if (tid == 0)
+	tid = ptid_get_pid (inferior_ptid);
+
+      /* Try peeking at FIR.F64 bit */
+      errno = 0;
+      fir = ptrace (PTRACE_PEEKUSER, tid, FPC_EIR, 0);
+      switch (errno)
+	{
+	case 0:
+	  have_fpu64 = !!(fir & FIR_F64);
+	  break;
+	case EIO:
+	  have_fpu64 = 0;
+	  break;
+	default:
+	  perror_with_name ("ptrace");
+	  break;
+	}
+    }
   if (have_dsp < 0)
     {
       int tid;
@@ -633,7 +664,7 @@  mips_linux_read_description (struct target_ops *ops)
   /* Report that target registers are a size we know for sure
      that we can get from ptrace.  */
   if (_MIPS_SIM == _ABIO32)
-    return have_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux;
+    return tdescs[have_dsp][have_fpu64];
   else
     return have_dsp ? tdesc_mips64_dsp_linux : tdesc_mips64_linux;
 }
@@ -990,6 +1021,8 @@  triggers a breakpoint or watchpoint."),
   /* Initialize the standard target descriptions.  */
   initialize_tdesc_mips_linux ();
   initialize_tdesc_mips_dsp_linux ();
+  initialize_tdesc_mips_fpu64_linux ();
+  initialize_tdesc_mips_fpu64_dsp_linux ();
   initialize_tdesc_mips64_linux ();
   initialize_tdesc_mips64_dsp_linux ();
 }