public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Alan Hayward <alan.hayward@arm.com>
To: gdb-patches@sourceware.org
Cc: nd@arm.com,	Alan Hayward <alan.hayward@arm.com>
Subject: [PATCH v2 01/10] Aarch64 SVE pseudo register support
Date: Wed, 06 Jun 2018 15:17:00 -0000	[thread overview]
Message-ID: <20180606151629.36602-2-alan.hayward@arm.com> (raw)
In-Reply-To: <20180606151629.36602-1-alan.hayward@arm.com>

Add the functionality for reading/writing pseudo registers.

On SVE the V registers are pseudo registers. This is supported
by adding AARCH64_SVE_V0_REGNUM.

2018-06-06  Alan Hayward  <alan.hayward@arm.com>

	* aarch64-tdep.c (AARCH64_SVE_V0_REGNUM): Add define.
	(aarch64_vnv_type): Add function.
	(aarch64_pseudo_register_name): Add V regs for SVE.
	(aarch64_pseudo_register_type): Likewise.
	(aarch64_pseudo_register_reggroup_p): Likewise.
	(aarch64_pseudo_read_value_2): Use V0 offset for SVE
	(aarch64_pseudo_read_value): Add V regs for SVE.
	(aarch64_pseudo_write_2): Use V0 offset for SVE
	(aarch64_pseudo_write): Add V regs for SVE.
	* aarch64-tdep.h (struct gdbarch_tdep): Add vnv_type.
---
 gdb/aarch64-tdep.c | 131 ++++++++++++++++++++++++++++++++++++++++++++---------
 gdb/aarch64-tdep.h |   1 +
 2 files changed, 111 insertions(+), 21 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index c6b1e2a9a3..2fe6a4006c 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -69,6 +69,7 @@
 #define AARCH64_S0_REGNUM (AARCH64_D0_REGNUM + 32)
 #define AARCH64_H0_REGNUM (AARCH64_S0_REGNUM + 32)
 #define AARCH64_B0_REGNUM (AARCH64_H0_REGNUM + 32)
+#define AARCH64_SVE_V0_REGNUM (AARCH64_B0_REGNUM + 32)
 
 /* All possible aarch64 target descriptors.  */
 struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1];
@@ -1766,6 +1767,30 @@ aarch64_vnb_type (struct gdbarch *gdbarch)
   return tdep->vnb_type;
 }
 
+/* Return the type for an AdvSISD V register.  */
+
+static struct type *
+aarch64_vnv_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->vnv_type == NULL)
+    {
+      struct type *t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnv",
+					    TYPE_CODE_UNION);
+
+      append_composite_type_field (t, "d", aarch64_vnd_type (gdbarch));
+      append_composite_type_field (t, "s", aarch64_vns_type (gdbarch));
+      append_composite_type_field (t, "h", aarch64_vnh_type (gdbarch));
+      append_composite_type_field (t, "b", aarch64_vnb_type (gdbarch));
+      append_composite_type_field (t, "q", aarch64_vnq_type (gdbarch));
+
+      tdep->vnv_type = t;
+    }
+
+  return tdep->vnv_type;
+}
+
 /* Implement the "dwarf2_reg_to_regnum" gdbarch method.  */
 
 static int
@@ -2114,6 +2139,8 @@ aarch64_gen_return_address (struct gdbarch *gdbarch,
 static const char *
 aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
   static const char *const q_name[] =
     {
       "q0", "q1", "q2", "q3",
@@ -2191,6 +2218,25 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
   if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
     return b_name[regnum - AARCH64_B0_REGNUM];
 
+  if (tdep->has_sve ())
+    {
+      static const char *const sve_v_name[] =
+	{
+	  "v0", "v1", "v2", "v3",
+	  "v4", "v5", "v6", "v7",
+	  "v8", "v9", "v10", "v11",
+	  "v12", "v13", "v14", "v15",
+	  "v16", "v17", "v18", "v19",
+	  "v20", "v21", "v22", "v23",
+	  "v24", "v25", "v26", "v27",
+	  "v28", "v29", "v30", "v31",
+	};
+
+      if (regnum >= AARCH64_SVE_V0_REGNUM
+	  && regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
+	return sve_v_name[regnum - AARCH64_SVE_V0_REGNUM];
+    }
+
   internal_error (__FILE__, __LINE__,
 		  _("aarch64_pseudo_register_name: bad register number %d"),
 		  regnum);
@@ -2201,6 +2247,8 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
 static struct type *
 aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
   regnum -= gdbarch_num_regs (gdbarch);
 
   if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
@@ -2218,6 +2266,10 @@ aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
   if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
     return aarch64_vnb_type (gdbarch);
 
+  if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
+      && regnum < AARCH64_SVE_V0_REGNUM + 32)
+    return aarch64_vnv_type (gdbarch);
+
   internal_error (__FILE__, __LINE__,
 		  _("aarch64_pseudo_register_type: bad register number %d"),
 		  regnum);
@@ -2229,6 +2281,8 @@ static int
 aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 				    struct reggroup *group)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
   regnum -= gdbarch_num_regs (gdbarch);
 
   if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
@@ -2243,6 +2297,9 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
     return group == all_reggroup || group == vector_reggroup;
   else if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
     return group == all_reggroup || group == vector_reggroup;
+  else if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
+	   && regnum < AARCH64_SVE_V0_REGNUM + 32)
+    return group == all_reggroup || group == vector_reggroup;
 
   return group == all_reggroup;
 }
@@ -2250,17 +2307,22 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 /* Helper for aarch64_pseudo_read_value.  */
 
 static struct value *
-aarch64_pseudo_read_value_1 (readable_regcache *regcache, int regnum_offset,
+aarch64_pseudo_read_value_1 (struct gdbarch *gdbarch,
+			     readable_regcache *regcache, int regnum_offset,
 			     int regsize, struct value *result_value)
 {
-  gdb_byte reg_buf[V_REGISTER_SIZE];
   unsigned v_regnum = AARCH64_V0_REGNUM + regnum_offset;
 
+  /* Enough space for a full vector register.  */
+  gdb_byte reg_buf[register_size (gdbarch, AARCH64_V0_REGNUM)];
+  gdb_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM);
+
   if (regcache->raw_read (v_regnum, reg_buf) != REG_VALID)
     mark_value_bytes_unavailable (result_value, 0,
 				  TYPE_LENGTH (value_type (result_value)));
   else
     memcpy (value_contents_raw (result_value), reg_buf, regsize);
+
   return result_value;
  }
 
@@ -2270,6 +2332,7 @@ static struct value *
 aarch64_pseudo_read_value (struct gdbarch *gdbarch, readable_regcache *regcache,
 			   int regnum)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   struct value *result_value = allocate_value (register_type (gdbarch, regnum));
 
   VALUE_LVAL (result_value) = lval_register;
@@ -2278,42 +2341,56 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch, readable_regcache *regcache,
   regnum -= gdbarch_num_regs (gdbarch);
 
   if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
-    return aarch64_pseudo_read_value_1 (regcache, regnum - AARCH64_Q0_REGNUM,
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+					regnum - AARCH64_Q0_REGNUM,
 					Q_REGISTER_SIZE, result_value);
 
   if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
-    return aarch64_pseudo_read_value_1 (regcache, regnum - AARCH64_D0_REGNUM,
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+					regnum - AARCH64_D0_REGNUM,
 					D_REGISTER_SIZE, result_value);
 
   if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
-    return aarch64_pseudo_read_value_1 (regcache, regnum - AARCH64_S0_REGNUM,
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+					regnum - AARCH64_S0_REGNUM,
 					S_REGISTER_SIZE, result_value);
 
   if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
-    return aarch64_pseudo_read_value_1 (regcache, regnum - AARCH64_H0_REGNUM,
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+					regnum - AARCH64_H0_REGNUM,
 					H_REGISTER_SIZE, result_value);
 
   if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
-    return aarch64_pseudo_read_value_1 (regcache, regnum - AARCH64_B0_REGNUM,
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+					regnum - AARCH64_B0_REGNUM,
 					B_REGISTER_SIZE, result_value);
 
+  if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
+      && regnum < AARCH64_SVE_V0_REGNUM + 32)
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+					regnum - AARCH64_SVE_V0_REGNUM,
+					V_REGISTER_SIZE, result_value);
+
   gdb_assert_not_reached ("regnum out of bound");
 }
 
 /* Helper for aarch64_pseudo_write.  */
 
 static void
-aarch64_pseudo_write_1 (struct regcache *regcache, int regnum_offset,
-			int regsize, const gdb_byte *buf)
+aarch64_pseudo_write_1 (struct gdbarch *gdbarch, struct regcache *regcache,
+			int regnum_offset, int regsize, const gdb_byte *buf)
 {
-  gdb_byte reg_buf[V_REGISTER_SIZE];
   unsigned v_regnum = AARCH64_V0_REGNUM + regnum_offset;
 
+  /* Enough space for a full vector register.  */
+  gdb_byte reg_buf[register_size (gdbarch, AARCH64_V0_REGNUM)];
+  gdb_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM);
+
   /* Ensure the register buffer is zero, we want gdb writes of the
      various 'scalar' pseudo registers to behavior like architectural
      writes, register width bytes are written the remainder are set to
      zero.  */
-  memset (reg_buf, 0, sizeof (reg_buf));
+  memset (reg_buf, 0, register_size (gdbarch, AARCH64_V0_REGNUM));
 
   memcpy (reg_buf, buf, regsize);
   regcache->raw_write (v_regnum, reg_buf);
@@ -2325,27 +2402,39 @@ static void
 aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
 		      int regnum, const gdb_byte *buf)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   regnum -= gdbarch_num_regs (gdbarch);
 
   if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
-    return aarch64_pseudo_write_1 (regcache, regnum - AARCH64_Q0_REGNUM,
-				   Q_REGISTER_SIZE, buf);
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+				   regnum - AARCH64_Q0_REGNUM, Q_REGISTER_SIZE,
+				   buf);
 
   if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
-    return aarch64_pseudo_write_1 (regcache, regnum - AARCH64_D0_REGNUM,
-				   D_REGISTER_SIZE, buf);
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+				   regnum - AARCH64_D0_REGNUM, D_REGISTER_SIZE,
+				   buf);
 
   if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
-    return aarch64_pseudo_write_1 (regcache, regnum - AARCH64_S0_REGNUM,
-				   S_REGISTER_SIZE, buf);
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+				   regnum - AARCH64_S0_REGNUM, S_REGISTER_SIZE,
+				   buf);
 
   if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
-    return aarch64_pseudo_write_1 (regcache, regnum - AARCH64_H0_REGNUM,
-				   H_REGISTER_SIZE, buf);
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+				   regnum - AARCH64_H0_REGNUM, H_REGISTER_SIZE,
+				   buf);
 
   if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
-    return aarch64_pseudo_write_1 (regcache, regnum - AARCH64_B0_REGNUM,
-				   B_REGISTER_SIZE, buf);
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+				   regnum - AARCH64_B0_REGNUM, B_REGISTER_SIZE,
+				   buf);
+
+  if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
+      && regnum < AARCH64_SVE_V0_REGNUM + 32)
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+				   regnum - AARCH64_SVE_V0_REGNUM,
+				   V_REGISTER_SIZE, buf);
 
   gdb_assert_not_reached ("regnum out of bound");
 }
diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h
index 598a0aafa2..5a319551e6 100644
--- a/gdb/aarch64-tdep.h
+++ b/gdb/aarch64-tdep.h
@@ -70,6 +70,7 @@ struct gdbarch_tdep
   struct type *vns_type;
   struct type *vnh_type;
   struct type *vnb_type;
+  struct type *vnv_type;
 
   /* syscall record.  */
   int (*aarch64_syscall_record) (struct regcache *regcache, unsigned long svc_number);
-- 
2.15.1 (Apple Git-101)

  parent reply	other threads:[~2018-06-06 15:17 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-06 15:16 [PATCH v2 00/10] gdb/gdbserver support for aarch64 SVE Alan Hayward
2018-06-06 15:17 ` [PATCH v2 03/10] Add reg_buffer_common Alan Hayward
2018-06-07 20:19   ` Simon Marchi
2018-06-07 20:42     ` Simon Marchi
2018-06-08 14:14     ` Alan Hayward
2018-06-10 22:21       ` Simon Marchi
2018-06-06 15:17 ` [PATCH v2 04/10] Add regcache raw_compare method Alan Hayward
2018-06-07 20:56   ` Simon Marchi
2018-06-08 15:16     ` Alan Hayward
2018-06-10 22:26       ` Simon Marchi
2018-06-06 15:17 ` [PATCH v2 08/10] Enable Aarch64 SVE for gdbserver Alan Hayward
2018-06-11  0:49   ` Simon Marchi
2018-06-06 15:17 ` [PATCH v2 10/10] Remove reg2 section from Aarch64 SVE cores Alan Hayward
2018-06-11  2:47   ` Simon Marchi
2018-06-11 16:37     ` Alan Hayward
2018-06-06 15:17 ` [PATCH v2 05/10] Ptrace support for Aarch64 SVE Alan Hayward
2018-06-10 22:52   ` Simon Marchi
2018-06-06 15:17 ` [PATCH v2 06/10] Add Aarch64 SVE dwarf regnums Alan Hayward
2018-06-11  0:43   ` Simon Marchi
2018-06-06 15:17 ` [PATCH v2 02/10] Add Aarch64 SVE Linux headers Alan Hayward
2018-06-08 14:13   ` Alan Hayward
2018-06-08 14:37     ` Simon Marchi
2018-06-08 15:23       ` Simon Marchi
2018-06-12 14:37         ` Alan Hayward
2018-06-12 14:43           ` Pedro Alves
2018-06-12 15:06             ` Simon Marchi
2018-06-12 15:11               ` Pedro Alves
2018-06-12 15:21                 ` Simon Marchi
2018-06-12 15:09             ` Alan Hayward
2018-06-12 14:51           ` Simon Marchi
2018-06-12 16:34             ` Sergio Durigan Junior
2018-06-12 17:51               ` Alan Hayward
2018-06-12 20:29                 ` Sergio Durigan Junior
2018-06-15  9:45                   ` Ramana Radhakrishnan
2018-06-15 17:14                     ` Alan Hayward
2018-09-20 21:16                       ` Status of the AArch* builders (was: Re: [PATCH v2 02/10] Add Aarch64 SVE Linux headers) Sergio Durigan Junior
2018-09-24 14:16                         ` Alan Hayward
2018-09-24 14:42                           ` Status of the AArch* builders Sergio Durigan Junior
2018-10-11  9:23                             ` Alan Hayward
2018-10-12 19:06                               ` Sergio Durigan Junior
2018-10-15 10:16                                 ` Alan Hayward
2018-10-15 12:42                                   ` Sergio Durigan Junior
2018-10-15 14:02                                     ` Alan Hayward
2018-10-15 15:32                                       ` Sergio Durigan Junior
2018-10-17 18:46                                         ` Sergio Durigan Junior
2018-10-24  9:56                                           ` Alan Hayward
2018-10-25 16:26                                             ` Sergio Durigan Junior
2018-06-08 15:27       ` [PATCH v2 02/10] Add Aarch64 SVE Linux headers Alan Hayward
2018-06-06 15:17 ` [PATCH v2 09/10] Ptrace support for AArch64 SVE gdbsever Alan Hayward
2018-06-11  2:43   ` Simon Marchi
2018-06-11  2:44   ` Simon Marchi
2018-06-06 15:17 ` Alan Hayward [this message]
2018-06-06 22:17   ` [PATCH v2 01/10] Aarch64 SVE pseudo register support Simon Marchi
2018-06-07  9:34     ` Alan Hayward
2018-06-06 15:17 ` [PATCH v2 07/10] Increase gdbsever PBUFSIZ Alan Hayward
2018-06-11  0:46   ` Simon Marchi

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=20180606151629.36602-2-alan.hayward@arm.com \
    --to=alan.hayward@arm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=nd@arm.com \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).