Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Bhushan Attarde <bhushan.attarde@imgtec.com>
To: <gdb-patches@sourceware.org>
Cc: <Maciej.Rozycki@imgtec.com>, <Matthew.Fortune@imgtec.com>,
	<James.Hogan@imgtec.com>, <Andrew.Bennett@imgtec.com>,
	<Jaydeep.Patil@imgtec.com>,
	Bhushan Attarde <bhushan.attarde@imgtec.com>
Subject: [PATCH 18/24]     mips-linux-nat: get msa registers
Date: Mon, 27 Jun 2016 14:51:00 -0000	[thread overview]
Message-ID: <1467038991-6600-18-git-send-email-bhushan.attarde@imgtec.com> (raw)
In-Reply-To: <1467038991-6600-1-git-send-email-bhushan.attarde@imgtec.com>

    This patch gets MSA registers using ptrace and sets up internal register
    state.

    gdb/gdbserver/ChangeLog:
        * mips-linux-nat.c (have_ptrace_getregset_msa): New variable.
        (mips64_linux_regsets_store_registers): Likewaise.
        (mips64_linux_regsets_fetch_registers): New is_vec variable.
        Get MSA regset first and then fp regset.
        (mips64_linux_regsets_store_registers): Likewaise.

    include/ChangeLog:
        * elf/common.h (NT_MIPS_MSA): New definition.
---
 gdb/mips-linux-nat.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++---
 include/elf/common.h |   1 +
 2 files changed, 156 insertions(+), 8 deletions(-)

diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index 20e3d17..a674885 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -68,6 +68,7 @@ static int have_ptrace_regsets = 1;
 /* Does the current host support PTRACE_GETREGSET?  */
 static int have_ptrace_getregset_gp = 1;
 static int have_ptrace_getregset_fp = 1;
+static int have_ptrace_getregset_msa = 1;
 
 /* Saved function pointers to fetch and store a single register using
    PTRACE_PEEKUSER and PTRACE_POKEUSER.  */
@@ -231,7 +232,7 @@ mips64_linux_regsets_fetch_registers (struct target_ops *ops,
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int big_endian = (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG);
-  int is_fp, is_dsp;
+  int is_fp, is_dsp, is_vec;
   int have_dsp;
   int regi;
   int tid;
@@ -252,6 +253,14 @@ mips64_linux_regsets_fetch_registers (struct target_ops *ops,
   else
     is_fp = 0;
 
+  /* Vector registers are optional but overlap fp registers */
+  if (regno == mips_regnum (gdbarch)->msa_csr)
+    is_vec = 1;
+  else if (regno == mips_regnum (gdbarch)->msa_ir)
+    is_vec = 1;
+  else
+    is_vec = 0;
+
   /* DSP registers are optional and not a part of any set.  */
   have_dsp = mips_regnum (gdbarch)->dspctl != -1;
   if (!have_dsp)
@@ -268,7 +277,7 @@ mips64_linux_regsets_fetch_registers (struct target_ops *ops,
   if (tid == 0)
     tid = ptid_get_pid (inferior_ptid);
 
-  if (regno == -1 || (!is_fp && !is_dsp))
+  if (regno == -1 || (!is_fp && !is_dsp && !is_vec))
     {
       mips64_elf_gregset_t regs;
 
@@ -286,13 +295,72 @@ mips64_linux_regsets_fetch_registers (struct target_ops *ops,
 			     (const mips64_elf_gregset_t *) &regs);
     }
 
-  if (is_fp)
+  if (is_fp || is_vec)
     {
       const struct mips_regnum *rn = mips_regnum (gdbarch);
       int float_regnum = rn->fp0;
 
+      /* Try the MSA regset first if vector registers are desired */
+      if (rn->msa_csr != -1
+	  && have_ptrace_getregset_gp && have_ptrace_getregset_msa)
+	{
+	  unsigned char w_regs[34][16];
+	  unsigned char buf[16];
+	  struct iovec iovec;
+	  int ret;
+
+	  iovec.iov_base = &w_regs;
+	  iovec.iov_len = sizeof (w_regs);
+
+	  ret = ptrace (PTRACE_GETREGSET, tid, NT_MIPS_MSA, &iovec);
+	  if (ret < 0)
+	    {
+	      if (errno == EIO)
+		have_ptrace_getregset_gp = 0;
+	      else if (errno == EINVAL)
+		have_ptrace_getregset_msa = 0;
+	      else
+		perror_with_name (_("Unable to fetch FP/MSA registers."));
+	    }
+	  else
+	    {
+	      /* full vector including float */
+	      if (big_endian)
+		for (regi = 0; regi < 32; regi++)
+		  {
+		    /* swap 64-bit halves, so it's a single word */
+		    memcpy(buf, w_regs[regi] + 8, 8);
+		    memcpy(buf + 8, w_regs[regi], 8);
+		    regcache_raw_supply (regcache, float_regnum + regi, buf);
+		  }
+	      else
+		for (regi = 0; regi < 32; regi++)
+		  regcache_raw_supply (regcache, float_regnum + regi,
+				       (char *) w_regs[regi]);
+
+	      if (iovec.iov_len >= 32*16 + 4)
+		regcache_raw_supply (regcache, rn->fp_implementation_revision,
+				     (char *) (w_regs + 32) + 0);
+	      if (iovec.iov_len >= 32*16 + 8)
+		regcache_raw_supply (regcache, rn->fp_control_status,
+				     (char *) (w_regs + 32) + 4);
+	      if (iovec.iov_len >= 32*16 + 12)
+		regcache_raw_supply (regcache, rn->msa_ir,
+				     (char *) (w_regs + 32) + 8);
+	      if (iovec.iov_len >= 32*16 + 16)
+		regcache_raw_supply (regcache, rn->msa_csr,
+				     (char *) (w_regs + 32) + 12);
+	      if (iovec.iov_len >= 33*16 + 4)
+		regcache_raw_supply (regcache, rn->config5,
+				     (char *) (w_regs + 33) + 0);
+
+	      /* we've got fp registers now */
+	      is_fp = 0;
+	    }
+	}
+
       /* Try the FP regset next as it may contain Config5 */
-      if (have_ptrace_getregset_gp && have_ptrace_getregset_fp)
+      if (is_fp && have_ptrace_getregset_gp && have_ptrace_getregset_fp)
 	{
 	  unsigned char fp_regs[34][8];
 	  struct iovec iovec;
@@ -396,7 +464,7 @@ mips64_linux_regsets_store_registers (struct target_ops *ops,
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int big_endian = (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG);
-  int is_fp, is_dsp;
+  int is_fp, is_dsp, is_vec;
   int have_dsp;
   int regi;
   int tid;
@@ -417,6 +485,17 @@ mips64_linux_regsets_store_registers (struct target_ops *ops,
   else
     is_fp = 0;
 
+  /* Vector registers are optional but overlap fp registers */
+  if (regno >= mips_regnum (gdbarch)->w0
+      && regno <= mips_regnum (gdbarch)->w0 + 32)
+    is_vec = 1;
+  else if (regno == mips_regnum (gdbarch)->msa_csr)
+    is_vec = 1;
+  else if (regno == mips_regnum (gdbarch)->msa_ir)
+    is_vec = 1;
+  else
+    is_vec = 0;
+
   /* DSP registers are optional and not a part of any set.  */
   have_dsp = mips_regnum (gdbarch)->dspctl != -1;
   if (!have_dsp)
@@ -433,7 +512,7 @@ mips64_linux_regsets_store_registers (struct target_ops *ops,
   if (tid == 0)
     tid = ptid_get_pid (inferior_ptid);
 
-  if (regno == -1 || (!is_fp && !is_dsp))
+  if (regno == -1 || (!is_fp && !is_dsp && !is_vec))
     {
       mips64_elf_gregset_t regs;
 
@@ -446,13 +525,81 @@ mips64_linux_regsets_store_registers (struct target_ops *ops,
 	perror_with_name (_("Couldn't set registers"));
     }
 
-  if (is_fp)
+  if (is_fp || is_vec)
     {
       const struct mips_regnum *rn = mips_regnum (gdbarch);
       int float_regnum = rn->fp0;
 
+      /* Try the MSA regset first if vector registers are desired */
+      if (rn->msa_csr != -1
+	  && have_ptrace_getregset_gp && have_ptrace_getregset_msa)
+	{
+	  unsigned char w_regs[34][16];
+	  unsigned char buf[16];
+	  struct iovec iovec;
+	  int ret;
+
+	  iovec.iov_base = &w_regs;
+	  iovec.iov_len = sizeof (w_regs);
+
+	  ret = ptrace (PTRACE_GETREGSET, tid, NT_MIPS_MSA, &iovec);
+	  if (ret < 0)
+	    {
+	      if (errno == EIO)
+		have_ptrace_getregset_gp = 0;
+	      else if (errno == EINVAL)
+		have_ptrace_getregset_msa = 0;
+	      else
+		perror_with_name (_("Unable to fetch FP/MSA registers."));
+	    }
+	  else
+	    {
+	      /* full vector including float */
+	      if (big_endian)
+		for (regi = 0; regi < 32; regi++)
+		  {
+		    regcache_raw_collect (regcache, float_regnum + regi, buf);
+		    /* swap 64-bit halves, as it's a single word */
+		    memcpy(w_regs[regi], buf + 8, 8);
+		    memcpy(w_regs[regi] + 8, buf, 8);
+		  }
+	      else
+		for (regi = 0; regi < 32; regi++)
+		  regcache_raw_collect (regcache, float_regnum + regi,
+					(char *) w_regs[regi]);
+
+	      regcache_raw_collect (regcache, rn->fp_implementation_revision,
+				    (char *) (w_regs + 32) + 0);
+	      regcache_raw_collect (regcache, rn->fp_control_status,
+				    (char *) (w_regs + 32) + 4);
+	      regcache_raw_collect (regcache, rn->msa_ir,
+				    (char *) (w_regs + 32) + 8);
+	      regcache_raw_collect (regcache, rn->msa_csr,
+				    (char *) (w_regs + 32) + 12);
+	      regcache_raw_collect (regcache, rn->config5,
+				    (char *) (w_regs + 33) + 0);
+
+	      /* don't modify iovec length from amount of data returned */
+	      ret = ptrace (PTRACE_SETREGSET, tid, NT_MIPS_MSA, &iovec);
+	      if (ret < 0)
+		{
+		  if (errno == EIO)
+		    have_ptrace_getregset_gp = 0;
+		  if (errno == EINVAL)
+		    have_ptrace_getregset_msa = 0;
+		  else
+		    perror_with_name (_("Unable to store FP/MSA registers."));
+		}
+	      else
+		{
+		  /* we've written fp registers now */
+		  is_fp = 0;
+		}
+	    }
+	}
+
       /* Try the FP regset next as it may contain Config5 */
-      if (have_ptrace_getregset_gp && have_ptrace_getregset_fp)
+      if (is_fp && have_ptrace_getregset_gp && have_ptrace_getregset_fp)
 	{
 	  unsigned char fp_regs[34][8];
 	  struct iovec iovec;
diff --git a/include/elf/common.h b/include/elf/common.h
index 087d876..5955874 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -580,6 +580,7 @@
 					/*   note name must be "LINUX".  */
 #define NT_ARM_HW_WATCH	0x403		/* AArch hardware watchpoint registers */
 					/*   note name must be "LINUX".  */
+#define NT_MIPS_MSA	0x600		/* MIPS MSA vector registers. */
 #define NT_SIGINFO	0x53494749	/* Fields of siginfo_t.  */
 #define NT_FILE		0x46494c45	/* Description of mapped files.  */
 
-- 
1.9-rc2


  parent reply	other threads:[~2016-06-27 14:51 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-27 14:50 [PATCH 01/24] MIPS: Handle run-time reconfigurable FPR size Bhushan Attarde
2016-06-27 14:50 ` [PATCH 03/24] regcache: handle invalidated regcache Bhushan Attarde
2016-10-21 22:42   ` Maciej W. Rozycki
2016-06-27 14:50 ` [PATCH 10/24] MIPS: override fscr/fir types and print control registers specially Bhushan Attarde
2016-06-27 14:50 ` [PATCH 08/24] MIPS: Convert FP mode to enum and put fp registers into fp reggroup Bhushan Attarde
2016-06-27 14:50 ` [PATCH 11/24] MIPS: Add support for hybrid fp32/fp64 mode Bhushan Attarde
2016-06-27 14:50 ` [PATCH 06/24] mips-linux-nat: pick fp64 target description when appropriate Bhushan Attarde
2016-06-27 14:51 ` [PATCH 21/24] MIPSR6 support for GDB Bhushan Attarde
2016-07-29 21:10   ` Maciej W. Rozycki
2016-06-27 14:51 ` [PATCH 23/24] MIPS R6 opcode table shuffle for LDC2/SDC2 Bhushan Attarde
2016-06-27 14:51 ` [PATCH 04/24] Add MIPS Config5 register related support Bhushan Attarde
2016-06-27 14:51 ` [PATCH 02/24] Add MIPS32 FPU64 GDB target descriptions Bhushan Attarde
2016-10-12 12:42   ` Maciej W. Rozycki
2016-10-12 13:58     ` James Hogan
2016-10-12 16:30       ` Maciej W. Rozycki
2016-10-12 18:05         ` James Hogan
2016-10-12 22:04           ` Maciej W. Rozycki
2016-10-13 10:09             ` Matthew Fortune
2016-10-21 19:17               ` Maciej W. Rozycki
2016-10-21 19:24                 ` Maciej W. Rozycki
2016-06-27 14:51 ` Bhushan Attarde [this message]
2016-06-27 14:51 ` [PATCH 13/24] Add MIPS MSA " Bhushan Attarde
2016-06-27 14:51 ` [PATCH 07/24] MIPS: Make Linux restart register more dynamic Bhushan Attarde
2016-06-27 14:51 ` [PATCH 09/24] MIPS: Enhance cooked FP format Bhushan Attarde
2016-06-27 14:51 ` [PATCH 19/24] Add MIPS MSA vector branch instruction support Bhushan Attarde
2016-06-27 14:51 ` [PATCH 22/24] Support all new ABIs when detecting if an FPU is present Bhushan Attarde
2016-06-27 14:51 ` [PATCH 20/24] Drop FP and MSA control registers from default info registers Bhushan Attarde
2016-06-27 14:51 ` [PATCH 14/24] Implement core MSA stuff Bhushan Attarde
2016-06-27 14:51 ` [PATCH 12/24] o32 sigframe unwinding with FR1 Bhushan Attarde
2016-06-27 14:51 ` [PATCH 24/24] MIPS R6 forbidden slot support Bhushan Attarde
2016-06-27 14:51 ` [PATCH 05/24] MIPS: Add config5 to MIPS GDB target descriptions Bhushan Attarde
2016-07-25 14:03 ` [PATCH 01/24] MIPS: Handle run-time reconfigurable FPR size Maciej W. Rozycki
2016-10-18 17:37   ` Maciej W. Rozycki
2016-11-08 19:46 ` Yao Qi
2016-11-10 12:43   ` Maciej W. Rozycki
2016-11-11 12:29     ` Yao Qi
2016-12-02  2:31       ` Maciej W. Rozycki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1467038991-6600-18-git-send-email-bhushan.attarde@imgtec.com \
    --to=bhushan.attarde@imgtec.com \
    --cc=Andrew.Bennett@imgtec.com \
    --cc=James.Hogan@imgtec.com \
    --cc=Jaydeep.Patil@imgtec.com \
    --cc=Maciej.Rozycki@imgtec.com \
    --cc=Matthew.Fortune@imgtec.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox