public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/4] [ARM] M-profile MVE extension support
@ 2021-10-05 14:45 Luis Machado
  2021-10-05 14:45 ` [PATCH 1/4] [ARM] Refactor some constants Luis Machado
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Luis Machado @ 2021-10-05 14:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: alan.hayward, srinath.parvathaneni, peter.maydell

The following 4 patches refactor some code (first 3 patches) and add support
for the M-profile MVE extension, which includes a new XML, new architecture
bits and new pseudo register.

The first 3 patches tidy up and reorganize some code around register numbers
and pseudo registers. The last patch adds said MVE support.

Luis Machado (3):
  [ARM] Refactor some constants
  [ARM] Small refactoring of arm gdbarch initialization
  [ARM] Refactor pseudo register numbering

Srinath Parvathaneni (1):
  [ARM] Add support for M-profile MVE extension

 gdb/arch/arm.c                         |   7 +
 gdb/arch/arm.h                         |  17 +-
 gdb/arm-tdep.c                         | 287 +++++++++++++++++++++----
 gdb/arm-tdep.h                         |  17 +-
 gdb/doc/gdb.texinfo                    |  11 +
 gdb/features/Makefile                  |   1 +
 gdb/features/arm/arm-m-profile-mve.c   |  20 ++
 gdb/features/arm/arm-m-profile-mve.xml |  19 ++
 8 files changed, 327 insertions(+), 52 deletions(-)
 create mode 100644 gdb/features/arm/arm-m-profile-mve.c
 create mode 100644 gdb/features/arm/arm-m-profile-mve.xml

-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] [ARM] Refactor some constants
  2021-10-05 14:45 [PATCH 0/4] [ARM] M-profile MVE extension support Luis Machado
@ 2021-10-05 14:45 ` Luis Machado
  2021-10-08 16:03   ` Alan Hayward
  2021-10-05 14:45 ` [PATCH 2/4] [ARM] Small refactoring of arm gdbarch initialization Luis Machado
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Luis Machado @ 2021-10-05 14:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: alan.hayward, srinath.parvathaneni, peter.maydell

In preparation for the MVE extension patch, this one refactors some of
the register-related constants we have for ARM.

Basically I'm separating counting constants from numbering constants.

For example, ARM_A1_REGNUM is a numbering constant, whereas ARM_NUM_ARG_REGS
is a counting constant.
---
 gdb/arch/arm.h | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/gdb/arch/arm.h b/gdb/arch/arm.h
index fa589fd0582..f6a155d6376 100644
--- a/gdb/arch/arm.h
+++ b/gdb/arch/arm.h
@@ -50,17 +50,23 @@ enum gdb_regnum {
   ARM_D31_REGNUM = ARM_D0_REGNUM + 31,
   ARM_FPSCR_REGNUM,
 
-  ARM_NUM_REGS,
-
   /* Other useful registers.  */
   ARM_FP_REGNUM = 11,		/* Frame register in ARM code, if used.  */
   THUMB_FP_REGNUM = 7,		/* Frame register in Thumb code, if used.  */
-  ARM_NUM_ARG_REGS = 4, 
   ARM_LAST_ARG_REGNUM = ARM_A4_REGNUM,
-  ARM_NUM_FP_ARG_REGS = 4,
   ARM_LAST_FP_ARG_REGNUM = ARM_F3_REGNUM
 };
 
+/* Register count constants.  */
+enum arm_register_counts {
+  /* Number of argument registers.  */
+  ARM_NUM_ARG_REGS = 4,
+  /* Number of floating point argument registers.  */
+  ARM_NUM_FP_ARG_REGS = 4,
+  /* Number of registers (old, defined as ARM_FPSCR_REGNUM + 1.  */
+  ARM_NUM_REGS = ARM_FPSCR_REGNUM + 1
+};
+
 /* Enum describing the different kinds of breakpoints.  */
 enum arm_breakpoint_kinds
 {
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/4] [ARM] Small refactoring of arm gdbarch initialization
  2021-10-05 14:45 [PATCH 0/4] [ARM] M-profile MVE extension support Luis Machado
  2021-10-05 14:45 ` [PATCH 1/4] [ARM] Refactor some constants Luis Machado
@ 2021-10-05 14:45 ` Luis Machado
  2021-10-08 16:03   ` Alan Hayward
  2021-10-05 14:45 ` [PATCH 3/4] [ARM] Refactor pseudo register numbering Luis Machado
  2021-10-05 14:45 ` [PATCH 4/4] [ARM] Add support for M-profile MVE extension Luis Machado
  3 siblings, 1 reply; 11+ messages in thread
From: Luis Machado @ 2021-10-05 14:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: alan.hayward, srinath.parvathaneni, peter.maydell

This is in preparation to MVE support, where we will define another
pseudo register. We need to define the pseudo register numbers *after*
accounting for all the registers in the XML description, so move
the call to tdesc_use_registers up.

If we don't do it, GDB's register count won't consider registers contained
in the XML but ignored by GDB, throwing the register numbering off.
---
 gdb/arm-tdep.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index ab6999ae209..2a6bfb1b3f7 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -9470,6 +9470,17 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
     }
 
+  if (tdesc_data != nullptr)
+    {
+      set_tdesc_pseudo_register_name (gdbarch, arm_register_name);
+
+      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
+
+      /* Override tdesc_register_type to adjust the types of VFP
+	 registers for NEON.  */
+      set_gdbarch_register_type (gdbarch, arm_register_type);
+    }
+
   if (have_vfp_pseudos)
     {
       /* NOTE: These are the only pseudo registers used by
@@ -9484,17 +9495,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
     }
 
-  if (tdesc_data != nullptr)
-    {
-      set_tdesc_pseudo_register_name (gdbarch, arm_register_name);
-
-      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
-
-      /* Override tdesc_register_type to adjust the types of VFP
-	 registers for NEON.  */
-      set_gdbarch_register_type (gdbarch, arm_register_type);
-    }
-
   /* Add standard register aliases.  We add aliases even for those
      names which are used by the current architecture - it's simpler,
      and does no harm, since nothing ever lists user registers.  */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/4] [ARM] Refactor pseudo register numbering
  2021-10-05 14:45 [PATCH 0/4] [ARM] M-profile MVE extension support Luis Machado
  2021-10-05 14:45 ` [PATCH 1/4] [ARM] Refactor some constants Luis Machado
  2021-10-05 14:45 ` [PATCH 2/4] [ARM] Small refactoring of arm gdbarch initialization Luis Machado
@ 2021-10-05 14:45 ` Luis Machado
  2021-10-08 16:04   ` Alan Hayward
  2021-10-05 14:45 ` [PATCH 4/4] [ARM] Add support for M-profile MVE extension Luis Machado
  3 siblings, 1 reply; 11+ messages in thread
From: Luis Machado @ 2021-10-05 14:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: alan.hayward, srinath.parvathaneni, peter.maydell

The pseudo register handling for ARM uses some hardcoded constants to
determine types and names.  In preparation to the upcoming MVE support
patch (that will add another pseudo register), this patch refactors and
reorganizes things in order to simplify handling of future pseudo registers.

We keep track of the first pseudo register number in a group and the number of
pseudo registers in that group.

Right now we only have the S and Q pseudo registers.
---
 gdb/arm-tdep.c | 139 +++++++++++++++++++++++++++++++++++--------------
 gdb/arm-tdep.h |  12 ++++-
 2 files changed, 111 insertions(+), 40 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 2a6bfb1b3f7..13bce202585 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -4122,20 +4122,57 @@ arm_neon_quad_type (struct gdbarch *gdbarch)
   return tdep->neon_quad_type;
 }
 
+/* Return true if REGNUM is a Q pseudo register.  Return false
+   otherwise.
+
+   REGNUM is the raw register number and not a pseudo-relative register
+   number.  */
+
+static bool
+is_q_pseudo (struct gdbarch *gdbarch, int regnum)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* Q pseudo registers are available for NEON (Q0~Q15).  */
+  if (tdep->have_q_pseudos
+      && regnum >= tdep->q_pseudo_base
+      && regnum < (tdep->q_pseudo_base + tdep->q_pseudo_count))
+    return true;
+
+  return false;
+}
+
+/* Return true if REGNUM is a VFP pseudo register.  Return false
+   otherwise.
+
+   REGNUM is the raw register number and not a pseudo-relative register
+   number.  */
+
+static bool
+is_vfp_pseudo (struct gdbarch *gdbarch, int regnum)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->have_vfp_pseudos
+      && regnum >= tdep->vfp_pseudo_base
+      && regnum < (tdep->vfp_pseudo_base + tdep->vfp_pseudo_count))
+    return true;
+
+  return false;
+}
+
 /* Return the GDB type object for the "standard" data type of data in
    register N.  */
 
 static struct type *
 arm_register_type (struct gdbarch *gdbarch, int regnum)
 {
-  int num_regs = gdbarch_num_regs (gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  if (gdbarch_tdep (gdbarch)->have_vfp_pseudos
-      && regnum >= num_regs && regnum < num_regs + 32)
+  if (is_vfp_pseudo (gdbarch, regnum))
     return builtin_type (gdbarch)->builtin_float;
 
-  if (gdbarch_tdep (gdbarch)->have_neon_pseudos
-      && regnum >= num_regs + 32 && regnum < num_regs + 32 + 16)
+  if (is_q_pseudo (gdbarch, regnum))
     return arm_neon_quad_type (gdbarch);
 
   /* If the target description has register information, we are only
@@ -4147,7 +4184,7 @@ arm_register_type (struct gdbarch *gdbarch, int regnum)
 
       if (regnum >= ARM_D0_REGNUM && regnum < ARM_D0_REGNUM + 32
 	  && t->code () == TYPE_CODE_FLT
-	  && gdbarch_tdep (gdbarch)->have_neon)
+	  && tdep->have_neon)
 	return arm_neon_double_type (gdbarch);
       else
 	return t;
@@ -4155,7 +4192,7 @@ arm_register_type (struct gdbarch *gdbarch, int regnum)
 
   if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
     {
-      if (!gdbarch_tdep (gdbarch)->have_fpa_registers)
+      if (!tdep->have_fpa_registers)
 	return builtin_type (gdbarch)->builtin_void;
 
       return arm_ext_type (gdbarch);
@@ -8551,10 +8588,9 @@ show_disassembly_style_sfunc (struct ui_file *file, int from_tty,
 static const char *
 arm_register_name (struct gdbarch *gdbarch, int i)
 {
-  const int num_regs = gdbarch_num_regs (gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  if (gdbarch_tdep (gdbarch)->have_vfp_pseudos
-      && i >= num_regs && i < num_regs + 32)
+  if (is_vfp_pseudo (gdbarch, i))
     {
       static const char *const vfp_pseudo_names[] = {
 	"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
@@ -8563,18 +8599,17 @@ arm_register_name (struct gdbarch *gdbarch, int i)
 	"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
       };
 
-      return vfp_pseudo_names[i - num_regs];
+      return vfp_pseudo_names[i - tdep->vfp_pseudo_base];
     }
 
-  if (gdbarch_tdep (gdbarch)->have_neon_pseudos
-      && i >= num_regs + 32 && i < num_regs + 32 + 16)
+  if (is_q_pseudo (gdbarch, i))
     {
-      static const char *const neon_pseudo_names[] = {
+      static const char *const q_pseudo_names[] = {
 	"q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
 	"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
       };
 
-      return neon_pseudo_names[i - num_regs - 32];
+      return q_pseudo_names[i - tdep->q_pseudo_base];
     }
 
   if (i >= ARRAY_SIZE (arm_register_names))
@@ -8582,6 +8617,7 @@ arm_register_name (struct gdbarch *gdbarch, int i)
        an XML description.  */
     return "";
 
+  /* Non-pseudo registers.  */
   return arm_register_names[i];
 }
 
@@ -8719,15 +8755,20 @@ arm_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache,
   int offset, double_regnum;
 
   gdb_assert (regnum >= num_regs);
-  regnum -= num_regs;
 
-  if (gdbarch_tdep (gdbarch)->have_neon_pseudos && regnum >= 32 && regnum < 48)
-    /* Quad-precision register.  */
-    return arm_neon_quad_read (gdbarch, regcache, regnum - 32, buf);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (is_q_pseudo (gdbarch, regnum))
+    {
+      /* Quad-precision register.  */
+      return arm_neon_quad_read (gdbarch, regcache,
+				 regnum - tdep->q_pseudo_base, buf);
+    }
   else
     {
       enum register_status status;
 
+      regnum -= tdep->vfp_pseudo_base;
       /* Single-precision register.  */
       gdb_assert (regnum < 32);
 
@@ -8787,13 +8828,18 @@ arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
   int offset, double_regnum;
 
   gdb_assert (regnum >= num_regs);
-  regnum -= num_regs;
 
-  if (gdbarch_tdep (gdbarch)->have_neon_pseudos && regnum >= 32 && regnum < 48)
-    /* Quad-precision register.  */
-    arm_neon_quad_write (gdbarch, regcache, regnum - 32, buf);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (is_q_pseudo (gdbarch, regnum))
+    {
+      /* Quad-precision register.  */
+      arm_neon_quad_write (gdbarch, regcache,
+			   regnum - tdep->q_pseudo_base, buf);
+    }
   else
     {
+      regnum -= tdep->vfp_pseudo_base;
       /* Single-precision register.  */
       gdb_assert (regnum < 32);
 
@@ -8940,11 +8986,12 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   int i;
   bool is_m = false;
   int vfp_register_count = 0;
-  bool have_vfp_pseudos = false, have_neon_pseudos = false;
+  bool have_vfp_pseudos = false, have_q_pseudos = false;
   bool have_wmmx_registers = false;
   bool have_neon = false;
   bool have_fpa_registers = true;
   const struct target_desc *tdesc = info.target_desc;
+  int register_count = ARM_NUM_REGS;
 
   /* If we have an object to base this architecture on, try to determine
      its ABI.  */
@@ -9248,7 +9295,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 		 their type; otherwise (normally) provide them with
 		 the default type.  */
 	      if (tdesc_unnumbered_register (feature, "q0") == 0)
-		have_neon_pseudos = true;
+		have_q_pseudos = true;
 
 	      have_neon = true;
 	    }
@@ -9299,7 +9346,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	      || vfp_register_count == 32);
   tdep->vfp_register_count = vfp_register_count;
   tdep->have_vfp_pseudos = have_vfp_pseudos;
-  tdep->have_neon_pseudos = have_neon_pseudos;
+  tdep->have_q_pseudos = have_q_pseudos;
   tdep->have_neon = have_neon;
 
   arm_register_g_packet_guesses (gdbarch);
@@ -9387,7 +9434,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Information about registers, etc.  */
   set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
   set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
-  set_gdbarch_num_regs (gdbarch, ARM_NUM_REGS);
+  set_gdbarch_num_regs (gdbarch, register_count);
   set_gdbarch_register_type (gdbarch, arm_register_type);
   set_gdbarch_register_reggroup_p (gdbarch, arm_register_reggroup_p);
 
@@ -9475,21 +9522,29 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_tdesc_pseudo_register_name (gdbarch, arm_register_name);
 
       tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
+      register_count = gdbarch_num_regs (gdbarch);
 
       /* Override tdesc_register_type to adjust the types of VFP
 	 registers for NEON.  */
       set_gdbarch_register_type (gdbarch, arm_register_type);
     }
 
-  if (have_vfp_pseudos)
+  /* Initialize the pseudo register data.  */
+  if (tdep->have_vfp_pseudos)
     {
-      /* NOTE: These are the only pseudo registers used by
-	 the ARM target at the moment.  If more are added, a
-	 little more care in numbering will be needed.  */
+      /* VFP single precision pseudo registers (S0~S31).  */
+      tdep->vfp_pseudo_base = register_count;
+      tdep->vfp_pseudo_count = 32;
+      int num_pseudos = tdep->vfp_pseudo_count;
+
+      if (tdep->have_q_pseudos)
+	{
+	  /* NEON quad precision pseudo registers (Q0~Q15).  */
+	  tdep->q_pseudo_base = register_count + num_pseudos;
+	  tdep->q_pseudo_count = 16;
+	  num_pseudos += tdep->q_pseudo_count;
+	}
 
-      int num_pseudos = 32;
-      if (have_neon_pseudos)
-	num_pseudos += 16;
       set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos);
       set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_read);
       set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
@@ -9526,10 +9581,18 @@ arm_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
 		      (int) tdep->have_wmmx_registers);
   fprintf_unfiltered (file, _("arm_dump_tdep: vfp_register_count = %i\n"),
 		      (int) tdep->vfp_register_count);
-  fprintf_unfiltered (file, _("arm_dump_tdep: have_vfp_pseudos = %i\n"),
-		      (int) tdep->have_vfp_pseudos);
-  fprintf_unfiltered (file, _("arm_dump_tdep: have_neon_pseudos = %i\n"),
-		      (int) tdep->have_neon_pseudos);
+  fprintf_unfiltered (file, _("arm_dump_tdep: have_vfp_pseudos = %s\n"),
+		      tdep->have_vfp_pseudos? "true" : "false");
+  fprintf_unfiltered (file, _("arm_dump_tdep: vfp_pseudo_base = %i\n"),
+		      (int) tdep->vfp_pseudo_base);
+  fprintf_unfiltered (file, _("arm_dump_tdep: vfp_pseudo_count = %i\n"),
+		      (int) tdep->vfp_pseudo_count);
+  fprintf_unfiltered (file, _("arm_dump_tdep: have_q_pseudos = %s\n"),
+		      tdep->have_q_pseudos? "true" : "false");
+  fprintf_unfiltered (file, _("arm_dump_tdep: q_pseudo_base = %i\n"),
+		      (int) tdep->q_pseudo_base);
+  fprintf_unfiltered (file, _("arm_dump_tdep: q_pseudo_count = %i\n"),
+		      (int) tdep->q_pseudo_count);
   fprintf_unfiltered (file, _("arm_dump_tdep: have_neon = %i\n"),
 		      (int) tdep->have_neon);
   fprintf_unfiltered (file, _("arm_dump_tdep: Lowest pc = 0x%lx\n"),
diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
index 969e121b55d..614c1a00ab6 100644
--- a/gdb/arm-tdep.h
+++ b/gdb/arm-tdep.h
@@ -102,9 +102,17 @@ struct gdbarch_tdep
   int vfp_register_count;
   bool have_vfp_pseudos;	/* Are we synthesizing the single precision
 				   VFP registers?  */
-  bool have_neon_pseudos;	/* Are we synthesizing the quad precision
-				   NEON registers?  Requires
+  int vfp_pseudo_base;		/* Register number for the first single
+				   precision VFP pseudo register.  */
+  int vfp_pseudo_count;		/* Number of single precision VFP pseudo
+				   registers.  */
+  bool have_q_pseudos;		/* Are we synthesizing the quad precision
+				   Q (NEON or MVE) registers?  Requires
 				   have_vfp_pseudos.  */
+  int q_pseudo_base;		/* Register number for the first quad
+				   precision pseudo register.  */
+  int q_pseudo_count;		/* Number of quad precision pseudo
+				   registers.  */
   bool have_neon;		/* Do we have a NEON unit?  */
 
   bool is_m;			/* Does the target follow the "M" profile.  */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 4/4] [ARM] Add support for M-profile MVE extension
  2021-10-05 14:45 [PATCH 0/4] [ARM] M-profile MVE extension support Luis Machado
                   ` (2 preceding siblings ...)
  2021-10-05 14:45 ` [PATCH 3/4] [ARM] Refactor pseudo register numbering Luis Machado
@ 2021-10-05 14:45 ` Luis Machado
  2021-10-05 15:55   ` Eli Zaretskii
  2021-10-08 16:34   ` Alan Hayward
  3 siblings, 2 replies; 11+ messages in thread
From: Luis Machado @ 2021-10-05 14:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: alan.hayward, srinath.parvathaneni, peter.maydell

From: Srinath Parvathaneni <srinath.parvathaneni@arm.com>

This patch adds support for the M-profile MVE extension, which includes the
following:

- New M-profile XML feature m-profile-mve
- MVE vector predication status and control register (VPR)
- p0 pseudo register (contained in the VPR)
- q0 ~ q7 pseudo vector registers
- New feature bits
- Documentation update

Pseudo register p0 is the least significant bits of vpr and can be accessed
as $p0 or displayed through $vpr.  For more information about the register
layout, please refer to [1].

The q0 ~ q7 registers map back to the d0 ~ d15 registers, two d registers
per q register.

The register dump looks like this:

(gdb) info reg all
r0             0x0                 0
r1             0x0                 0
r2             0x0                 0
r3             0x0                 0
r4             0x0                 0
r5             0x0                 0
r6             0x0                 0
r7             0x0                 0
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x0                 0
r12            0x0                 0
sp             0x0                 0x0 <__Vectors>
lr             0xffffffff          -1
pc             0xd0c               0xd0c <Reset_Handler>
xpsr           0x1000000           16777216
d0             0                   (raw 0x0000000000000000)
d1             0                   (raw 0x0000000000000000)
d2             0                   (raw 0x0000000000000000)
d3             0                   (raw 0x0000000000000000)
d4             0                   (raw 0x0000000000000000)
d5             0                   (raw 0x0000000000000000)
d6             0                   (raw 0x0000000000000000)
d7             0                   (raw 0x0000000000000000)
d8             0                   (raw 0x0000000000000000)
d9             0                   (raw 0x0000000000000000)
d10            0                   (raw 0x0000000000000000)
d11            0                   (raw 0x0000000000000000)
d12            0                   (raw 0x0000000000000000)
d13            0                   (raw 0x0000000000000000)
d14            0                   (raw 0x0000000000000000)
d15            0                   (raw 0x0000000000000000)
fpscr          0x0                 0
vpr            0x0                 [ P0=0 MASK01=0 MASK23=0 ]
s0             0                   (raw 0x00000000)
s1             0                   (raw 0x00000000)
s2             0                   (raw 0x00000000)
s3             0                   (raw 0x00000000)
s4             0                   (raw 0x00000000)
s5             0                   (raw 0x00000000)
s6             0                   (raw 0x00000000)
s7             0                   (raw 0x00000000)
s8             0                   (raw 0x00000000)
s9             0                   (raw 0x00000000)
s10            0                   (raw 0x00000000)
s11            0                   (raw 0x00000000)
s12            0                   (raw 0x00000000)
s13            0                   (raw 0x00000000)
s14            0                   (raw 0x00000000)
s15            0                   (raw 0x00000000)
s16            0                   (raw 0x00000000)
s17            0                   (raw 0x00000000)
s18            0                   (raw 0x00000000)
s19            0                   (raw 0x00000000)
s20            0                   (raw 0x00000000)
s21            0                   (raw 0x00000000)
s22            0                   (raw 0x00000000)
s23            0                   (raw 0x00000000)
s24            0                   (raw 0x00000000)
s25            0                   (raw 0x00000000)
s26            0                   (raw 0x00000000)
s27            0                   (raw 0x00000000)
s28            0                   (raw 0x00000000)
s29            0                   (raw 0x00000000)
s30            0                   (raw 0x00000000)
s31            0                   (raw 0x00000000)
q0             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
q1             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
q2             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
q3             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
q4             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
q5             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
q6             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
q7             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
p0             0x0                 0

Built and regtested with a simulator.

[1] https://developer.arm.com/documentation/ddi0553/bn

Co-Authored-By: Luis Machado <luis.machado@linaro.org>
---
 gdb/arch/arm.c                         |   7 ++
 gdb/arch/arm.h                         |   3 +
 gdb/arm-tdep.c                         | 140 ++++++++++++++++++++++++-
 gdb/arm-tdep.h                         |   5 +
 gdb/doc/gdb.texinfo                    |  11 ++
 gdb/features/Makefile                  |   1 +
 gdb/features/arm/arm-m-profile-mve.c   |  20 ++++
 gdb/features/arm/arm-m-profile-mve.xml |  19 ++++
 8 files changed, 202 insertions(+), 4 deletions(-)
 create mode 100644 gdb/features/arm/arm-m-profile-mve.c
 create mode 100644 gdb/features/arm/arm-m-profile-mve.xml

diff --git a/gdb/arch/arm.c b/gdb/arch/arm.c
index 7407c4a7dad..a18b38b9d81 100644
--- a/gdb/arch/arm.c
+++ b/gdb/arch/arm.c
@@ -27,6 +27,7 @@
 #include "../features/arm/xscale-iwmmxt.c"
 #include "../features/arm/arm-m-profile.c"
 #include "../features/arm/arm-m-profile-with-fpa.c"
+#include "../features/arm/arm-m-profile-mve.c"
 
 /* See arm.h.  */
 
@@ -439,6 +440,12 @@ arm_create_mprofile_target_description (arm_m_profile_type m_type)
       regnum = create_feature_arm_arm_m_profile_with_fpa (tdesc, regnum);
       break;
 
+    case ARM_M_TYPE_MVE:
+      regnum = create_feature_arm_arm_m_profile (tdesc, regnum);
+      regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum);
+      regnum = create_feature_arm_arm_m_profile_mve (tdesc, regnum);
+      break;
+
     default:
       error (_("Invalid Arm M type: %d"), m_type);
     }
diff --git a/gdb/arch/arm.h b/gdb/arch/arm.h
index f6a155d6376..eabcb434f1f 100644
--- a/gdb/arch/arm.h
+++ b/gdb/arch/arm.h
@@ -59,6 +59,8 @@ enum gdb_regnum {
 
 /* Register count constants.  */
 enum arm_register_counts {
+  /* Number of Q registers for MVE.  */
+  ARM_MVE_NUM_Q_REGS = 8,
   /* Number of argument registers.  */
   ARM_NUM_ARG_REGS = 4,
   /* Number of floating point argument registers.  */
@@ -89,6 +91,7 @@ enum arm_m_profile_type {
    ARM_M_TYPE_M_PROFILE,
    ARM_M_TYPE_VFP_D16,
    ARM_M_TYPE_WITH_FPA,
+   ARM_M_TYPE_MVE,
    ARM_M_TYPE_INVALID
 };
 
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 13bce202585..7db48e859b7 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -4133,7 +4133,8 @@ is_q_pseudo (struct gdbarch *gdbarch, int regnum)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  /* Q pseudo registers are available for NEON (Q0~Q15).  */
+  /* Q pseudo registers are available for both NEON (Q0~Q15) and
+     MVE (Q0~Q7) features.  */
   if (tdep->have_q_pseudos
       && regnum >= tdep->q_pseudo_base
       && regnum < (tdep->q_pseudo_base + tdep->q_pseudo_count))
@@ -4161,6 +4162,25 @@ is_vfp_pseudo (struct gdbarch *gdbarch, int regnum)
   return false;
 }
 
+/* Return true if REGNUM is a MVE pseudo register (P0).  Return false
+   otherwise.
+
+   REGNUM is the raw register number and not a pseudo-relative register
+   number.  */
+
+static bool
+is_mve_pseudo (struct gdbarch *gdbarch, int regnum)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->have_mve
+      && regnum >= tdep->mve_pseudo_base
+      && regnum < tdep->mve_pseudo_base + tdep->mve_pseudo_count)
+    return true;
+
+  return false;
+}
+
 /* Return the GDB type object for the "standard" data type of data in
    register N.  */
 
@@ -4175,6 +4195,9 @@ arm_register_type (struct gdbarch *gdbarch, int regnum)
   if (is_q_pseudo (gdbarch, regnum))
     return arm_neon_quad_type (gdbarch);
 
+  if (is_mve_pseudo (gdbarch, regnum))
+    return builtin_type (gdbarch)->builtin_int16;
+
   /* If the target description has register information, we are only
      in this function so that we can override the types of
      double-precision registers for NEON.  */
@@ -8612,6 +8635,9 @@ arm_register_name (struct gdbarch *gdbarch, int i)
       return q_pseudo_names[i - tdep->q_pseudo_base];
     }
 
+  if (is_mve_pseudo (gdbarch, i))
+    return "p0";
+
   if (i >= ARRAY_SIZE (arm_register_names))
     /* These registers are only supported on targets which supply
        an XML description.  */
@@ -8745,6 +8771,19 @@ arm_neon_quad_read (struct gdbarch *gdbarch, readable_regcache *regcache,
   return REG_VALID;
 }
 
+/* Read the contents of the MVE pseudo register REGNUM and store it
+   in BUF.  */
+
+static enum register_status
+arm_mve_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache,
+		     int regnum, gdb_byte *buf)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* P0 is the first 16 bits of VPR.  */
+  return regcache->raw_read_part (tdep->mve_vpr_regnum, 0, 2, buf);
+}
+
 static enum register_status
 arm_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache,
 		 int regnum, gdb_byte *buf)
@@ -8764,6 +8803,8 @@ arm_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache,
       return arm_neon_quad_read (gdbarch, regcache,
 				 regnum - tdep->q_pseudo_base, buf);
     }
+  else if (is_mve_pseudo (gdbarch, regnum))
+    return arm_mve_pseudo_read (gdbarch, regcache, regnum, buf);
   else
     {
       enum register_status status;
@@ -8818,6 +8859,18 @@ arm_neon_quad_write (struct gdbarch *gdbarch, struct regcache *regcache,
   regcache->raw_write (double_regnum + 1, buf + offset);
 }
 
+/* Store the contents of BUF to the MVE pseudo register REGNUM.  */
+
+static void
+arm_mve_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
+		      int regnum, const gdb_byte *buf)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* P0 is the first 16 bits of VPR.  */
+  regcache->raw_write_part (tdep->mve_vpr_regnum, 0, 2, buf);
+}
+
 static void
 arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
 		  int regnum, const gdb_byte *buf)
@@ -8837,6 +8890,8 @@ arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
       arm_neon_quad_write (gdbarch, regcache,
 			   regnum - tdep->q_pseudo_base, buf);
     }
+  else if (is_mve_pseudo (gdbarch, regnum))
+    arm_mve_pseudo_write (gdbarch, regcache, regnum, buf);
   else
     {
       regnum -= tdep->vfp_pseudo_base;
@@ -8935,6 +8990,11 @@ arm_register_g_packet_guesses (struct gdbarch *gdbarch)
       register_remote_g_packet_guess (gdbarch,
 				      ARM_CORE_REGS_SIZE + ARM_VFP2_REGS_SIZE,
 				      tdesc);
+      /* M-profile plus MVE.  */
+      tdesc = arm_read_mprofile_description (ARM_M_TYPE_MVE);
+      register_remote_g_packet_guess (gdbarch, ARM_CORE_REGS_SIZE
+				      + ARM_VFP2_REGS_SIZE
+				      + ARM_INT_REGISTER_SIZE, tdesc);
     }
 
   /* Otherwise we don't have a useful guess.  */
@@ -8991,6 +9051,9 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   bool have_neon = false;
   bool have_fpa_registers = true;
   const struct target_desc *tdesc = info.target_desc;
+  bool have_vfp = false;
+  bool have_mve = false;
+  int mve_vpr_regnum = -1;
   int register_count = ARM_NUM_REGS;
 
   /* If we have an object to base this architecture on, try to determine
@@ -9106,6 +9169,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	      if (!tdesc_has_registers (tdesc)
 		  && (attr_arch == TAG_CPU_ARCH_V6_M
 		      || attr_arch == TAG_CPU_ARCH_V6S_M
+		      || attr_arch == TAG_CPU_ARCH_V8_1M_MAIN
 		      || attr_profile == 'M'))
 		is_m = true;
 #endif
@@ -9275,6 +9339,8 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	  if (!valid_p)
 	    return NULL;
 
+	  have_vfp = true;
+
 	  if (tdesc_unnumbered_register (feature, "s0") == 0)
 	    have_vfp_pseudos = true;
 
@@ -9296,8 +9362,41 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 		 the default type.  */
 	      if (tdesc_unnumbered_register (feature, "q0") == 0)
 		have_q_pseudos = true;
+	    }
+	}
+
+      /* Check for MVE after all the checks for GPR's, VFP and Neon.
+	 MVE (Helium) is an M-profile extension.  */
+      if (is_m)
+	{
+	  /* Do we have the MVE feature?  */
+	  feature = tdesc_find_feature (tdesc,"org.gnu.gdb.arm.m-profile-mve");
+
+	  if (feature != nullptr)
+	    {
+	      /* If we have MVE, we must always have the VPR register.  */
+	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+						  register_count, "vpr");
+	      if (!valid_p)
+		{
+		  warning (_("MVE feature is missing required register vpr."));
+		  return nullptr;
+		}
 
-	      have_neon = true;
+	      have_mve = true;
+	      mve_vpr_regnum = register_count;
+	      register_count++;
+
+	      /* We can't have Q pseudo registers available here, as that
+		 would mean we have NEON features, and that is only available
+		 on A and R profiles.  */
+	      gdb_assert (!have_q_pseudos);
+
+	      /* Given we have a M-profile target description, if MVE is
+		 enabled and there are VFP registers, we should have Q
+		 pseudo registers (Q0 ~ Q7).  */
+	      if (have_vfp)
+		have_q_pseudos = true;
 	    }
 	}
     }
@@ -9349,6 +9448,13 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->have_q_pseudos = have_q_pseudos;
   tdep->have_neon = have_neon;
 
+  /* Adjust the MVE feature settings.  */
+  if (have_mve)
+    {
+      tdep->have_mve = true;
+      tdep->mve_vpr_regnum = mve_vpr_regnum;
+    }
+
   arm_register_g_packet_guesses (gdbarch);
 
   /* Breakpoints.  */
@@ -9530,21 +9636,39 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   /* Initialize the pseudo register data.  */
+  int num_pseudos = 0;
   if (tdep->have_vfp_pseudos)
     {
       /* VFP single precision pseudo registers (S0~S31).  */
       tdep->vfp_pseudo_base = register_count;
       tdep->vfp_pseudo_count = 32;
-      int num_pseudos = tdep->vfp_pseudo_count;
+      num_pseudos += tdep->vfp_pseudo_count;
 
       if (tdep->have_q_pseudos)
 	{
 	  /* NEON quad precision pseudo registers (Q0~Q15).  */
 	  tdep->q_pseudo_base = register_count + num_pseudos;
-	  tdep->q_pseudo_count = 16;
+
+	  if (have_neon)
+	    tdep->q_pseudo_count = 16;
+	  else if (have_mve)
+	    tdep->q_pseudo_count = ARM_MVE_NUM_Q_REGS;
+
 	  num_pseudos += tdep->q_pseudo_count;
 	}
+    }
 
+  /* Do we have any MVE pseudo registers?  */
+  if (have_mve)
+    {
+      tdep->mve_pseudo_base = register_count + num_pseudos;
+      tdep->mve_pseudo_count = 1;
+      num_pseudos += tdep->mve_pseudo_count;
+    }
+
+  /* Set some pseudo register hooks, if we have pseudo registers.  */
+  if (tdep->have_vfp_pseudos || have_mve)
+    {
       set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos);
       set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_read);
       set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
@@ -9595,6 +9719,14 @@ arm_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
 		      (int) tdep->q_pseudo_count);
   fprintf_unfiltered (file, _("arm_dump_tdep: have_neon = %i\n"),
 		      (int) tdep->have_neon);
+  fprintf_unfiltered (file, _("arm_dump_tdep: have_mve = %s\n"),
+		      tdep->have_mve? "yes" : "no");
+  fprintf_unfiltered (file, _("arm_dump_tdep: mve_vpr_regnum = %i\n"),
+		      tdep->mve_vpr_regnum);
+  fprintf_unfiltered (file, _("arm_dump_tdep: mve_pseudo_base = %i\n"),
+		      tdep->mve_pseudo_base);
+  fprintf_unfiltered (file, _("arm_dump_tdep: mve_pseudo_count = %i\n"),
+		      tdep->mve_pseudo_count);
   fprintf_unfiltered (file, _("arm_dump_tdep: Lowest pc = 0x%lx\n"),
 		      (unsigned long) tdep->lowest_pc);
 }
diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
index 614c1a00ab6..4664be629ea 100644
--- a/gdb/arm-tdep.h
+++ b/gdb/arm-tdep.h
@@ -115,6 +115,11 @@ struct gdbarch_tdep
 				   registers.  */
   bool have_neon;		/* Do we have a NEON unit?  */
 
+  bool have_mve;		/* Do we have a MVE extension?  */
+  int mve_vpr_regnum;		/* MVE VPR register number.  */
+  int mve_pseudo_base;		/* Number of the first MVE pseudo register.  */
+  int mve_pseudo_count;		/* Total number of MVE pseudo registers.  */
+
   bool is_m;			/* Does the target follow the "M" profile.  */
   CORE_ADDR lowest_pc;		/* Lowest address at which instructions 
 				   will appear.  */
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index c156a1d6739..7ee7508bd8e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -46213,6 +46213,17 @@ and @samp{xpsr}.
 The @samp{org.gnu.gdb.arm.fpa} feature is optional.  If present, it
 should contain registers @samp{f0} through @samp{f7} and @samp{fps}.
 
+The @samp{org.gnu.gdb.arm.m-profile-mve} feature is optional.  If present, it
+must contain register @samp{vpr}.
+
+If the @samp{org.gnu.gdb.arm.m-profile-mve} feature is available, @value{GDBN}
+will synthesize the @samp{p0} pseudo register from @samp{vpr} contents.
+
+If the @samp{org.gnu.gdb.arm.vfp} feature is available alongside the
+@samp{org.gnu.gdb.arm.m-profile-mve} feature, @value{GDBN} will
+synthesize the @samp{q} pseudo registers from @samp{d} register
+contents.
+
 The @samp{org.gnu.gdb.xscale.iwmmxt} feature is optional.  If present,
 it should contain at least registers @samp{wR0} through @samp{wR15} and
 @samp{wCGR0} through @samp{wCGR3}.  The @samp{wCID}, @samp{wCon},
diff --git a/gdb/features/Makefile b/gdb/features/Makefile
index aa38d176539..e478bf838b7 100644
--- a/gdb/features/Makefile
+++ b/gdb/features/Makefile
@@ -203,6 +203,7 @@ FEATURE_XMLFILES = aarch64-core.xml \
 	arm/arm-core.xml \
 	arm/arm-fpa.xml \
 	arm/arm-m-profile.xml \
+	arm/arm-m-profile-mve.xml \
 	arm/arm-m-profile-with-fpa.xml \
 	arm/arm-vfpv2.xml \
 	arm/arm-vfpv3.xml \
diff --git a/gdb/features/arm/arm-m-profile-mve.c b/gdb/features/arm/arm-m-profile-mve.c
new file mode 100644
index 00000000000..532ae3ba1d1
--- /dev/null
+++ b/gdb/features/arm/arm-m-profile-mve.c
@@ -0,0 +1,20 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: arm-m-profile-mve.xml */
+
+#include "gdbsupport/tdesc.h"
+
+static int
+create_feature_arm_arm_m_profile_mve (struct target_desc *result, long regnum)
+{
+  struct tdesc_feature *feature;
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.arm.m-profile-mve");
+  tdesc_type_with_fields *type_with_fields;
+  type_with_fields = tdesc_create_flags (feature, "vpr_reg", 4);
+  tdesc_add_bitfield (type_with_fields, "P0", 0, 15);
+  tdesc_add_bitfield (type_with_fields, "MASK01", 16, 19);
+  tdesc_add_bitfield (type_with_fields, "MASK23", 20, 23);
+
+  tdesc_create_reg (feature, "vpr", regnum++, 1, NULL, 32, "vpr_reg");
+  return regnum;
+}
diff --git a/gdb/features/arm/arm-m-profile-mve.xml b/gdb/features/arm/arm-m-profile-mve.xml
new file mode 100644
index 00000000000..cba664c4c5b
--- /dev/null
+++ b/gdb/features/arm/arm-m-profile-mve.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2021 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.arm.m-profile-mve">
+  <flags id="vpr_reg" size="4">
+    <!-- ARMv8.1-M and MVE: Unprivileged and privileged Access.  -->
+    <field name="P0" start="0" end="15"/>
+    <!-- ARMv8.1-M: Privileged Access only.  -->
+    <field name="MASK01" start="16" end="19"/>
+    <!-- ARMv8.1-M: Privileged Access only.  -->
+    <field name="MASK23" start="20" end="23"/>
+  </flags>
+  <reg name="vpr" bitsize="32" type="vpr_reg"/>
+</feature>
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] [ARM] Add support for M-profile MVE extension
  2021-10-05 14:45 ` [PATCH 4/4] [ARM] Add support for M-profile MVE extension Luis Machado
@ 2021-10-05 15:55   ` Eli Zaretskii
  2021-10-08 16:34   ` Alan Hayward
  1 sibling, 0 replies; 11+ messages in thread
From: Eli Zaretskii @ 2021-10-05 15:55 UTC (permalink / raw)
  To: Luis Machado; +Cc: gdb-patches, peter.maydell

> Date: Tue,  5 Oct 2021 11:45:21 -0300
> From: Luis Machado via Gdb-patches <gdb-patches@sourceware.org>
> Cc: peter.maydell@linaro.org
> 
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index c156a1d6739..7ee7508bd8e 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo

OK for this part.

Thanks.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] [ARM] Refactor some constants
  2021-10-05 14:45 ` [PATCH 1/4] [ARM] Refactor some constants Luis Machado
@ 2021-10-08 16:03   ` Alan Hayward
  0 siblings, 0 replies; 11+ messages in thread
From: Alan Hayward @ 2021-10-08 16:03 UTC (permalink / raw)
  To: Luis Machado
  Cc: gdb-patches\@sourceware.org, Srinath Parvathaneni, Peter Maydell, nd

Lgtm. Helpful regardless of MVE.


Alan.


> On 5 Oct 2021, at 15:45, Luis Machado <luis.machado@linaro.org> wrote:
> 
> In preparation for the MVE extension patch, this one refactors some of
> the register-related constants we have for ARM.
> 
> Basically I'm separating counting constants from numbering constants.
> 
> For example, ARM_A1_REGNUM is a numbering constant, whereas ARM_NUM_ARG_REGS
> is a counting constant.
> ---
> gdb/arch/arm.h | 14 ++++++++++----
> 1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/gdb/arch/arm.h b/gdb/arch/arm.h
> index fa589fd0582..f6a155d6376 100644
> --- a/gdb/arch/arm.h
> +++ b/gdb/arch/arm.h
> @@ -50,17 +50,23 @@ enum gdb_regnum {
>   ARM_D31_REGNUM = ARM_D0_REGNUM + 31,
>   ARM_FPSCR_REGNUM,
> 
> -  ARM_NUM_REGS,
> -
>   /* Other useful registers.  */
>   ARM_FP_REGNUM = 11,		/* Frame register in ARM code, if used.  */
>   THUMB_FP_REGNUM = 7,		/* Frame register in Thumb code, if used.  */
> -  ARM_NUM_ARG_REGS = 4, 
>   ARM_LAST_ARG_REGNUM = ARM_A4_REGNUM,
> -  ARM_NUM_FP_ARG_REGS = 4,
>   ARM_LAST_FP_ARG_REGNUM = ARM_F3_REGNUM
> };
> 
> +/* Register count constants.  */
> +enum arm_register_counts {
> +  /* Number of argument registers.  */
> +  ARM_NUM_ARG_REGS = 4,
> +  /* Number of floating point argument registers.  */
> +  ARM_NUM_FP_ARG_REGS = 4,
> +  /* Number of registers (old, defined as ARM_FPSCR_REGNUM + 1.  */
> +  ARM_NUM_REGS = ARM_FPSCR_REGNUM + 1
> +};
> +
> /* Enum describing the different kinds of breakpoints.  */
> enum arm_breakpoint_kinds
> {
> -- 
> 2.25.1
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] [ARM] Small refactoring of arm gdbarch initialization
  2021-10-05 14:45 ` [PATCH 2/4] [ARM] Small refactoring of arm gdbarch initialization Luis Machado
@ 2021-10-08 16:03   ` Alan Hayward
  0 siblings, 0 replies; 11+ messages in thread
From: Alan Hayward @ 2021-10-08 16:03 UTC (permalink / raw)
  To: Luis Machado
  Cc: gdb-patches\@sourceware.org, Srinath Parvathaneni, Peter Maydell, nd

Lgtm


Alan

> On 5 Oct 2021, at 15:45, Luis Machado <luis.machado@linaro.org> wrote:
> 
> This is in preparation to MVE support, where we will define another
> pseudo register. We need to define the pseudo register numbers *after*
> accounting for all the registers in the XML description, so move
> the call to tdesc_use_registers up.
> 
> If we don't do it, GDB's register count won't consider registers contained
> in the XML but ignored by GDB, throwing the register numbering off.
> ---
> gdb/arm-tdep.c | 22 +++++++++++-----------
> 1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index ab6999ae209..2a6bfb1b3f7 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -9470,6 +9470,17 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>       set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
>     }
> 
> +  if (tdesc_data != nullptr)
> +    {
> +      set_tdesc_pseudo_register_name (gdbarch, arm_register_name);
> +
> +      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
> +
> +      /* Override tdesc_register_type to adjust the types of VFP
> +	 registers for NEON.  */
> +      set_gdbarch_register_type (gdbarch, arm_register_type);
> +    }
> +
>   if (have_vfp_pseudos)
>     {
>       /* NOTE: These are the only pseudo registers used by
> @@ -9484,17 +9495,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>       set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
>     }
> 
> -  if (tdesc_data != nullptr)
> -    {
> -      set_tdesc_pseudo_register_name (gdbarch, arm_register_name);
> -
> -      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
> -
> -      /* Override tdesc_register_type to adjust the types of VFP
> -	 registers for NEON.  */
> -      set_gdbarch_register_type (gdbarch, arm_register_type);
> -    }
> -
>   /* Add standard register aliases.  We add aliases even for those
>      names which are used by the current architecture - it's simpler,
>      and does no harm, since nothing ever lists user registers.  */
> -- 
> 2.25.1
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] [ARM] Refactor pseudo register numbering
  2021-10-05 14:45 ` [PATCH 3/4] [ARM] Refactor pseudo register numbering Luis Machado
@ 2021-10-08 16:04   ` Alan Hayward
  2021-10-11 13:06     ` Luis Machado
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Hayward @ 2021-10-08 16:04 UTC (permalink / raw)
  To: Luis Machado
  Cc: gdb-patches\@sourceware.org, Srinath Parvathaneni, Peter Maydell, nd

This is similar to AArch64 target, so mostly Lgtm...

> On 5 Oct 2021, at 15:45, Luis Machado <luis.machado@linaro.org> wrote:
> 
> The pseudo register handling for ARM uses some hardcoded constants to
> determine types and names.  In preparation to the upcoming MVE support
> patch (that will add another pseudo register), this patch refactors and
> reorganizes things in order to simplify handling of future pseudo registers.
> 
> We keep track of the first pseudo register number in a group and the number of
> pseudo registers in that group.
> 
> Right now we only have the S and Q pseudo registers.

Renaming NEON to Q makes sense.

Why not rename VFP to S?


> ---
> gdb/arm-tdep.c | 139 +++++++++++++++++++++++++++++++++++--------------
> gdb/arm-tdep.h |  12 ++++-
> 2 files changed, 111 insertions(+), 40 deletions(-)
> 
> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 2a6bfb1b3f7..13bce202585 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -4122,20 +4122,57 @@ arm_neon_quad_type (struct gdbarch *gdbarch)
>   return tdep->neon_quad_type;
> }
> 
> +/* Return true if REGNUM is a Q pseudo register.  Return false
> +   otherwise.
> +
> +   REGNUM is the raw register number and not a pseudo-relative register
> +   number.  */
> +
> +static bool
> +is_q_pseudo (struct gdbarch *gdbarch, int regnum)
> +{
> +  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +
> +  /* Q pseudo registers are available for NEON (Q0~Q15).  */
> +  if (tdep->have_q_pseudos
> +      && regnum >= tdep->q_pseudo_base
> +      && regnum < (tdep->q_pseudo_base + tdep->q_pseudo_count))
> +    return true;
> +
> +  return false;
> +}
> +
> +/* Return true if REGNUM is a VFP pseudo register.  Return false
> +   otherwise.
> +
> +   REGNUM is the raw register number and not a pseudo-relative register
> +   number.  */
> +
> +static bool
> +is_vfp_pseudo (struct gdbarch *gdbarch, int regnum)
> +{
> +  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +
> +  if (tdep->have_vfp_pseudos
> +      && regnum >= tdep->vfp_pseudo_base
> +      && regnum < (tdep->vfp_pseudo_base + tdep->vfp_pseudo_count))
> +    return true;
> +
> +  return false;
> +}
> +
> /* Return the GDB type object for the "standard" data type of data in
>    register N.  */
> 
> static struct type *
> arm_register_type (struct gdbarch *gdbarch, int regnum)
> {
> -  int num_regs = gdbarch_num_regs (gdbarch);
> +  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> 
> -  if (gdbarch_tdep (gdbarch)->have_vfp_pseudos
> -      && regnum >= num_regs && regnum < num_regs + 32)
> +  if (is_vfp_pseudo (gdbarch, regnum))
>     return builtin_type (gdbarch)->builtin_float;
> 
> -  if (gdbarch_tdep (gdbarch)->have_neon_pseudos
> -      && regnum >= num_regs + 32 && regnum < num_regs + 32 + 16)
> +  if (is_q_pseudo (gdbarch, regnum))
>     return arm_neon_quad_type (gdbarch);
> 
>   /* If the target description has register information, we are only
> @@ -4147,7 +4184,7 @@ arm_register_type (struct gdbarch *gdbarch, int regnum)
> 
>       if (regnum >= ARM_D0_REGNUM && regnum < ARM_D0_REGNUM + 32
> 	  && t->code () == TYPE_CODE_FLT
> -	  && gdbarch_tdep (gdbarch)->have_neon)
> +	  && tdep->have_neon)
> 	return arm_neon_double_type (gdbarch);
>       else
> 	return t;
> @@ -4155,7 +4192,7 @@ arm_register_type (struct gdbarch *gdbarch, int regnum)
> 
>   if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
>     {
> -      if (!gdbarch_tdep (gdbarch)->have_fpa_registers)
> +      if (!tdep->have_fpa_registers)
> 	return builtin_type (gdbarch)->builtin_void;
> 
>       return arm_ext_type (gdbarch);
> @@ -8551,10 +8588,9 @@ show_disassembly_style_sfunc (struct ui_file *file, int from_tty,
> static const char *
> arm_register_name (struct gdbarch *gdbarch, int i)
> {
> -  const int num_regs = gdbarch_num_regs (gdbarch);
> +  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> 
> -  if (gdbarch_tdep (gdbarch)->have_vfp_pseudos
> -      && i >= num_regs && i < num_regs + 32)
> +  if (is_vfp_pseudo (gdbarch, i))
>     {
>       static const char *const vfp_pseudo_names[] = {
> 	"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
> @@ -8563,18 +8599,17 @@ arm_register_name (struct gdbarch *gdbarch, int i)
> 	"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
>       };
> 
> -      return vfp_pseudo_names[i - num_regs];
> +      return vfp_pseudo_names[i - tdep->vfp_pseudo_base];
>     }
> 
> -  if (gdbarch_tdep (gdbarch)->have_neon_pseudos
> -      && i >= num_regs + 32 && i < num_regs + 32 + 16)
> +  if (is_q_pseudo (gdbarch, i))
>     {
> -      static const char *const neon_pseudo_names[] = {
> +      static const char *const q_pseudo_names[] = {
> 	"q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
> 	"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
>       };
> 
> -      return neon_pseudo_names[i - num_regs - 32];
> +      return q_pseudo_names[i - tdep->q_pseudo_base];
>     }
> 
>   if (i >= ARRAY_SIZE (arm_register_names))
> @@ -8582,6 +8617,7 @@ arm_register_name (struct gdbarch *gdbarch, int i)
>        an XML description.  */
>     return "";
> 
> +  /* Non-pseudo registers.  */
>   return arm_register_names[i];
> }
> 
> @@ -8719,15 +8755,20 @@ arm_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache,
>   int offset, double_regnum;
> 
>   gdb_assert (regnum >= num_regs);
> -  regnum -= num_regs;
> 
> -  if (gdbarch_tdep (gdbarch)->have_neon_pseudos && regnum >= 32 && regnum < 48)
> -    /* Quad-precision register.  */
> -    return arm_neon_quad_read (gdbarch, regcache, regnum - 32, buf);
> +  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +
> +  if (is_q_pseudo (gdbarch, regnum))
> +    {
> +      /* Quad-precision register.  */
> +      return arm_neon_quad_read (gdbarch, regcache,
> +				 regnum - tdep->q_pseudo_base, buf);
> +    }
>   else
>     {
>       enum register_status status;
> 
> +      regnum -= tdep->vfp_pseudo_base;
>       /* Single-precision register.  */
>       gdb_assert (regnum < 32);
> 
> @@ -8787,13 +8828,18 @@ arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
>   int offset, double_regnum;
> 
>   gdb_assert (regnum >= num_regs);
> -  regnum -= num_regs;
> 
> -  if (gdbarch_tdep (gdbarch)->have_neon_pseudos && regnum >= 32 && regnum < 48)
> -    /* Quad-precision register.  */
> -    arm_neon_quad_write (gdbarch, regcache, regnum - 32, buf);
> +  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +
> +  if (is_q_pseudo (gdbarch, regnum))
> +    {
> +      /* Quad-precision register.  */
> +      arm_neon_quad_write (gdbarch, regcache,
> +			   regnum - tdep->q_pseudo_base, buf);
> +    }
>   else
>     {
> +      regnum -= tdep->vfp_pseudo_base;
>       /* Single-precision register.  */
>       gdb_assert (regnum < 32);
> 
> @@ -8940,11 +8986,12 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>   int i;
>   bool is_m = false;
>   int vfp_register_count = 0;
> -  bool have_vfp_pseudos = false, have_neon_pseudos = false;
> +  bool have_vfp_pseudos = false, have_q_pseudos = false;
>   bool have_wmmx_registers = false;
>   bool have_neon = false;
>   bool have_fpa_registers = true;
>   const struct target_desc *tdesc = info.target_desc;
> +  int register_count = ARM_NUM_REGS;
> 
>   /* If we have an object to base this architecture on, try to determine
>      its ABI.  */
> @@ -9248,7 +9295,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> 		 their type; otherwise (normally) provide them with
> 		 the default type.  */
> 	      if (tdesc_unnumbered_register (feature, "q0") == 0)
> -		have_neon_pseudos = true;
> +		have_q_pseudos = true;
> 
> 	      have_neon = true;
> 	    }
> @@ -9299,7 +9346,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> 	      || vfp_register_count == 32);
>   tdep->vfp_register_count = vfp_register_count;
>   tdep->have_vfp_pseudos = have_vfp_pseudos;
> -  tdep->have_neon_pseudos = have_neon_pseudos;
> +  tdep->have_q_pseudos = have_q_pseudos;
>   tdep->have_neon = have_neon;
> 
>   arm_register_g_packet_guesses (gdbarch);
> @@ -9387,7 +9434,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>   /* Information about registers, etc.  */
>   set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
>   set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
> -  set_gdbarch_num_regs (gdbarch, ARM_NUM_REGS);
> +  set_gdbarch_num_regs (gdbarch, register_count);
>   set_gdbarch_register_type (gdbarch, arm_register_type);
>   set_gdbarch_register_reggroup_p (gdbarch, arm_register_reggroup_p);
> 
> @@ -9475,21 +9522,29 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>       set_tdesc_pseudo_register_name (gdbarch, arm_register_name);
> 
>       tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
> +      register_count = gdbarch_num_regs (gdbarch);
> 
>       /* Override tdesc_register_type to adjust the types of VFP
> 	 registers for NEON.  */
>       set_gdbarch_register_type (gdbarch, arm_register_type);
>     }
> 
> -  if (have_vfp_pseudos)
> +  /* Initialize the pseudo register data.  */
> +  if (tdep->have_vfp_pseudos)
>     {
> -      /* NOTE: These are the only pseudo registers used by
> -	 the ARM target at the moment.  If more are added, a
> -	 little more care in numbering will be needed.  */
> +      /* VFP single precision pseudo registers (S0~S31).  */
> +      tdep->vfp_pseudo_base = register_count;
> +      tdep->vfp_pseudo_count = 32;
> +      int num_pseudos = tdep->vfp_pseudo_count;
> +
> +      if (tdep->have_q_pseudos)
> +	{
> +	  /* NEON quad precision pseudo registers (Q0~Q15).  */
> +	  tdep->q_pseudo_base = register_count + num_pseudos;
> +	  tdep->q_pseudo_count = 16;
> +	  num_pseudos += tdep->q_pseudo_count;
> +	}
> 
> -      int num_pseudos = 32;
> -      if (have_neon_pseudos)
> -	num_pseudos += 16;
>       set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos);
>       set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_read);
>       set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
> @@ -9526,10 +9581,18 @@ arm_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
> 		      (int) tdep->have_wmmx_registers);
>   fprintf_unfiltered (file, _("arm_dump_tdep: vfp_register_count = %i\n"),
> 		      (int) tdep->vfp_register_count);
> -  fprintf_unfiltered (file, _("arm_dump_tdep: have_vfp_pseudos = %i\n"),
> -		      (int) tdep->have_vfp_pseudos);
> -  fprintf_unfiltered (file, _("arm_dump_tdep: have_neon_pseudos = %i\n"),
> -		      (int) tdep->have_neon_pseudos);
> +  fprintf_unfiltered (file, _("arm_dump_tdep: have_vfp_pseudos = %s\n"),
> +		      tdep->have_vfp_pseudos? "true" : "false");
> +  fprintf_unfiltered (file, _("arm_dump_tdep: vfp_pseudo_base = %i\n"),
> +		      (int) tdep->vfp_pseudo_base);
> +  fprintf_unfiltered (file, _("arm_dump_tdep: vfp_pseudo_count = %i\n"),
> +		      (int) tdep->vfp_pseudo_count);
> +  fprintf_unfiltered (file, _("arm_dump_tdep: have_q_pseudos = %s\n"),
> +		      tdep->have_q_pseudos? "true" : "false");
> +  fprintf_unfiltered (file, _("arm_dump_tdep: q_pseudo_base = %i\n"),
> +		      (int) tdep->q_pseudo_base);
> +  fprintf_unfiltered (file, _("arm_dump_tdep: q_pseudo_count = %i\n"),
> +		      (int) tdep->q_pseudo_count);
>   fprintf_unfiltered (file, _("arm_dump_tdep: have_neon = %i\n"),
> 		      (int) tdep->have_neon);
>   fprintf_unfiltered (file, _("arm_dump_tdep: Lowest pc = 0x%lx\n"),
> diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
> index 969e121b55d..614c1a00ab6 100644
> --- a/gdb/arm-tdep.h
> +++ b/gdb/arm-tdep.h
> @@ -102,9 +102,17 @@ struct gdbarch_tdep
>   int vfp_register_count;
>   bool have_vfp_pseudos;	/* Are we synthesizing the single precision
> 				   VFP registers?  */
> -  bool have_neon_pseudos;	/* Are we synthesizing the quad precision
> -				   NEON registers?  Requires
> +  int vfp_pseudo_base;		/* Register number for the first single
> +				   precision VFP pseudo register.  */
> +  int vfp_pseudo_count;		/* Number of single precision VFP pseudo
> +				   registers.  */
> +  bool have_q_pseudos;		/* Are we synthesizing the quad precision
> +				   Q (NEON or MVE) registers?  Requires
> 				   have_vfp_pseudos.  */
> +  int q_pseudo_base;		/* Register number for the first quad
> +				   precision pseudo register.  */
> +  int q_pseudo_count;		/* Number of quad precision pseudo
> +				   registers.  */
>   bool have_neon;		/* Do we have a NEON unit?  */
> 
>   bool is_m;			/* Does the target follow the "M" profile.  */
> -- 
> 2.25.1
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] [ARM] Add support for M-profile MVE extension
  2021-10-05 14:45 ` [PATCH 4/4] [ARM] Add support for M-profile MVE extension Luis Machado
  2021-10-05 15:55   ` Eli Zaretskii
@ 2021-10-08 16:34   ` Alan Hayward
  1 sibling, 0 replies; 11+ messages in thread
From: Alan Hayward @ 2021-10-08 16:34 UTC (permalink / raw)
  To: Luis Machado
  Cc: gdb-patches\@sourceware.org, Srinath Parvathaneni, Peter Maydell, nd

This one Lgtm too. Much easier to read now everything has been refactored.
(Feel we could go further with he pseudo cleanups, but this isn’t the right time to do it)

Alan.

> On 5 Oct 2021, at 15:45, Luis Machado <luis.machado@linaro.org> wrote:
> 
> From: Srinath Parvathaneni <srinath.parvathaneni@arm.com>
> 
> This patch adds support for the M-profile MVE extension, which includes the
> following:
> 
> - New M-profile XML feature m-profile-mve
> - MVE vector predication status and control register (VPR)
> - p0 pseudo register (contained in the VPR)
> - q0 ~ q7 pseudo vector registers
> - New feature bits
> - Documentation update
> 
> Pseudo register p0 is the least significant bits of vpr and can be accessed
> as $p0 or displayed through $vpr.  For more information about the register
> layout, please refer to [1].
> 
> The q0 ~ q7 registers map back to the d0 ~ d15 registers, two d registers
> per q register.
> 
> The register dump looks like this:
> 
> (gdb) info reg all
> r0             0x0                 0
> r1             0x0                 0
> r2             0x0                 0
> r3             0x0                 0
> r4             0x0                 0
> r5             0x0                 0
> r6             0x0                 0
> r7             0x0                 0
> r8             0x0                 0
> r9             0x0                 0
> r10            0x0                 0
> r11            0x0                 0
> r12            0x0                 0
> sp             0x0                 0x0 <__Vectors>
> lr             0xffffffff          -1
> pc             0xd0c               0xd0c <Reset_Handler>
> xpsr           0x1000000           16777216
> d0             0                   (raw 0x0000000000000000)
> d1             0                   (raw 0x0000000000000000)
> d2             0                   (raw 0x0000000000000000)
> d3             0                   (raw 0x0000000000000000)
> d4             0                   (raw 0x0000000000000000)
> d5             0                   (raw 0x0000000000000000)
> d6             0                   (raw 0x0000000000000000)
> d7             0                   (raw 0x0000000000000000)
> d8             0                   (raw 0x0000000000000000)
> d9             0                   (raw 0x0000000000000000)
> d10            0                   (raw 0x0000000000000000)
> d11            0                   (raw 0x0000000000000000)
> d12            0                   (raw 0x0000000000000000)
> d13            0                   (raw 0x0000000000000000)
> d14            0                   (raw 0x0000000000000000)
> d15            0                   (raw 0x0000000000000000)
> fpscr          0x0                 0
> vpr            0x0                 [ P0=0 MASK01=0 MASK23=0 ]
> s0             0                   (raw 0x00000000)
> s1             0                   (raw 0x00000000)
> s2             0                   (raw 0x00000000)
> s3             0                   (raw 0x00000000)
> s4             0                   (raw 0x00000000)
> s5             0                   (raw 0x00000000)
> s6             0                   (raw 0x00000000)
> s7             0                   (raw 0x00000000)
> s8             0                   (raw 0x00000000)
> s9             0                   (raw 0x00000000)
> s10            0                   (raw 0x00000000)
> s11            0                   (raw 0x00000000)
> s12            0                   (raw 0x00000000)
> s13            0                   (raw 0x00000000)
> s14            0                   (raw 0x00000000)
> s15            0                   (raw 0x00000000)
> s16            0                   (raw 0x00000000)
> s17            0                   (raw 0x00000000)
> s18            0                   (raw 0x00000000)
> s19            0                   (raw 0x00000000)
> s20            0                   (raw 0x00000000)
> s21            0                   (raw 0x00000000)
> s22            0                   (raw 0x00000000)
> s23            0                   (raw 0x00000000)
> s24            0                   (raw 0x00000000)
> s25            0                   (raw 0x00000000)
> s26            0                   (raw 0x00000000)
> s27            0                   (raw 0x00000000)
> s28            0                   (raw 0x00000000)
> s29            0                   (raw 0x00000000)
> s30            0                   (raw 0x00000000)
> s31            0                   (raw 0x00000000)
> q0             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
> q1             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
> q2             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
> q3             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
> q4             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
> q5             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
> q6             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
> q7             {u8 = {0x0 <repeats 16 times>}, u16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, u32 = {0x0, 0x0, 0x0, 0x0}, u64 = {0x0, 0x0}, f32 = {0x0, 0x0, 0x0, 0x0}, f64 = {0x0, 0x0}}
> p0             0x0                 0
> 
> Built and regtested with a simulator.
> 
> [1] https://developer.arm.com/documentation/ddi0553/bn
> 
> Co-Authored-By: Luis Machado <luis.machado@linaro.org>
> ---
> gdb/arch/arm.c                         |   7 ++
> gdb/arch/arm.h                         |   3 +
> gdb/arm-tdep.c                         | 140 ++++++++++++++++++++++++-
> gdb/arm-tdep.h                         |   5 +
> gdb/doc/gdb.texinfo                    |  11 ++
> gdb/features/Makefile                  |   1 +
> gdb/features/arm/arm-m-profile-mve.c   |  20 ++++
> gdb/features/arm/arm-m-profile-mve.xml |  19 ++++
> 8 files changed, 202 insertions(+), 4 deletions(-)
> create mode 100644 gdb/features/arm/arm-m-profile-mve.c
> create mode 100644 gdb/features/arm/arm-m-profile-mve.xml
> 
> diff --git a/gdb/arch/arm.c b/gdb/arch/arm.c
> index 7407c4a7dad..a18b38b9d81 100644
> --- a/gdb/arch/arm.c
> +++ b/gdb/arch/arm.c
> @@ -27,6 +27,7 @@
> #include "../features/arm/xscale-iwmmxt.c"
> #include "../features/arm/arm-m-profile.c"
> #include "../features/arm/arm-m-profile-with-fpa.c"
> +#include "../features/arm/arm-m-profile-mve.c"
> 
> /* See arm.h.  */
> 
> @@ -439,6 +440,12 @@ arm_create_mprofile_target_description (arm_m_profile_type m_type)
>       regnum = create_feature_arm_arm_m_profile_with_fpa (tdesc, regnum);
>       break;
> 
> +    case ARM_M_TYPE_MVE:
> +      regnum = create_feature_arm_arm_m_profile (tdesc, regnum);
> +      regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum);
> +      regnum = create_feature_arm_arm_m_profile_mve (tdesc, regnum);
> +      break;
> +
>     default:
>       error (_("Invalid Arm M type: %d"), m_type);
>     }
> diff --git a/gdb/arch/arm.h b/gdb/arch/arm.h
> index f6a155d6376..eabcb434f1f 100644
> --- a/gdb/arch/arm.h
> +++ b/gdb/arch/arm.h
> @@ -59,6 +59,8 @@ enum gdb_regnum {
> 
> /* Register count constants.  */
> enum arm_register_counts {
> +  /* Number of Q registers for MVE.  */
> +  ARM_MVE_NUM_Q_REGS = 8,
>   /* Number of argument registers.  */
>   ARM_NUM_ARG_REGS = 4,
>   /* Number of floating point argument registers.  */
> @@ -89,6 +91,7 @@ enum arm_m_profile_type {
>    ARM_M_TYPE_M_PROFILE,
>    ARM_M_TYPE_VFP_D16,
>    ARM_M_TYPE_WITH_FPA,
> +   ARM_M_TYPE_MVE,
>    ARM_M_TYPE_INVALID
> };
> 
> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 13bce202585..7db48e859b7 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -4133,7 +4133,8 @@ is_q_pseudo (struct gdbarch *gdbarch, int regnum)
> {
>   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> 
> -  /* Q pseudo registers are available for NEON (Q0~Q15).  */
> +  /* Q pseudo registers are available for both NEON (Q0~Q15) and
> +     MVE (Q0~Q7) features.  */
>   if (tdep->have_q_pseudos
>       && regnum >= tdep->q_pseudo_base
>       && regnum < (tdep->q_pseudo_base + tdep->q_pseudo_count))
> @@ -4161,6 +4162,25 @@ is_vfp_pseudo (struct gdbarch *gdbarch, int regnum)
>   return false;
> }
> 
> +/* Return true if REGNUM is a MVE pseudo register (P0).  Return false
> +   otherwise.
> +
> +   REGNUM is the raw register number and not a pseudo-relative register
> +   number.  */
> +
> +static bool
> +is_mve_pseudo (struct gdbarch *gdbarch, int regnum)
> +{
> +  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +
> +  if (tdep->have_mve
> +      && regnum >= tdep->mve_pseudo_base
> +      && regnum < tdep->mve_pseudo_base + tdep->mve_pseudo_count)
> +    return true;
> +
> +  return false;
> +}
> +
> /* Return the GDB type object for the "standard" data type of data in
>    register N.  */
> 
> @@ -4175,6 +4195,9 @@ arm_register_type (struct gdbarch *gdbarch, int regnum)
>   if (is_q_pseudo (gdbarch, regnum))
>     return arm_neon_quad_type (gdbarch);
> 
> +  if (is_mve_pseudo (gdbarch, regnum))
> +    return builtin_type (gdbarch)->builtin_int16;
> +
>   /* If the target description has register information, we are only
>      in this function so that we can override the types of
>      double-precision registers for NEON.  */
> @@ -8612,6 +8635,9 @@ arm_register_name (struct gdbarch *gdbarch, int i)
>       return q_pseudo_names[i - tdep->q_pseudo_base];
>     }
> 
> +  if (is_mve_pseudo (gdbarch, i))
> +    return "p0";
> +
>   if (i >= ARRAY_SIZE (arm_register_names))
>     /* These registers are only supported on targets which supply
>        an XML description.  */
> @@ -8745,6 +8771,19 @@ arm_neon_quad_read (struct gdbarch *gdbarch, readable_regcache *regcache,
>   return REG_VALID;
> }
> 
> +/* Read the contents of the MVE pseudo register REGNUM and store it
> +   in BUF.  */
> +
> +static enum register_status
> +arm_mve_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache,
> +		     int regnum, gdb_byte *buf)
> +{
> +  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +
> +  /* P0 is the first 16 bits of VPR.  */
> +  return regcache->raw_read_part (tdep->mve_vpr_regnum, 0, 2, buf);
> +}
> +
> static enum register_status
> arm_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache,
> 		 int regnum, gdb_byte *buf)
> @@ -8764,6 +8803,8 @@ arm_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache,
>       return arm_neon_quad_read (gdbarch, regcache,
> 				 regnum - tdep->q_pseudo_base, buf);
>     }
> +  else if (is_mve_pseudo (gdbarch, regnum))
> +    return arm_mve_pseudo_read (gdbarch, regcache, regnum, buf);
>   else
>     {
>       enum register_status status;
> @@ -8818,6 +8859,18 @@ arm_neon_quad_write (struct gdbarch *gdbarch, struct regcache *regcache,
>   regcache->raw_write (double_regnum + 1, buf + offset);
> }
> 
> +/* Store the contents of BUF to the MVE pseudo register REGNUM.  */
> +
> +static void
> +arm_mve_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
> +		      int regnum, const gdb_byte *buf)
> +{
> +  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +
> +  /* P0 is the first 16 bits of VPR.  */
> +  regcache->raw_write_part (tdep->mve_vpr_regnum, 0, 2, buf);
> +}
> +
> static void
> arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
> 		  int regnum, const gdb_byte *buf)
> @@ -8837,6 +8890,8 @@ arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
>       arm_neon_quad_write (gdbarch, regcache,
> 			   regnum - tdep->q_pseudo_base, buf);
>     }
> +  else if (is_mve_pseudo (gdbarch, regnum))
> +    arm_mve_pseudo_write (gdbarch, regcache, regnum, buf);
>   else
>     {
>       regnum -= tdep->vfp_pseudo_base;
> @@ -8935,6 +8990,11 @@ arm_register_g_packet_guesses (struct gdbarch *gdbarch)
>       register_remote_g_packet_guess (gdbarch,
> 				      ARM_CORE_REGS_SIZE + ARM_VFP2_REGS_SIZE,
> 				      tdesc);
> +      /* M-profile plus MVE.  */
> +      tdesc = arm_read_mprofile_description (ARM_M_TYPE_MVE);
> +      register_remote_g_packet_guess (gdbarch, ARM_CORE_REGS_SIZE
> +				      + ARM_VFP2_REGS_SIZE
> +				      + ARM_INT_REGISTER_SIZE, tdesc);
>     }
> 
>   /* Otherwise we don't have a useful guess.  */
> @@ -8991,6 +9051,9 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>   bool have_neon = false;
>   bool have_fpa_registers = true;
>   const struct target_desc *tdesc = info.target_desc;
> +  bool have_vfp = false;
> +  bool have_mve = false;
> +  int mve_vpr_regnum = -1;
>   int register_count = ARM_NUM_REGS;
> 
>   /* If we have an object to base this architecture on, try to determine
> @@ -9106,6 +9169,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> 	      if (!tdesc_has_registers (tdesc)
> 		  && (attr_arch == TAG_CPU_ARCH_V6_M
> 		      || attr_arch == TAG_CPU_ARCH_V6S_M
> +		      || attr_arch == TAG_CPU_ARCH_V8_1M_MAIN
> 		      || attr_profile == 'M'))
> 		is_m = true;
> #endif
> @@ -9275,6 +9339,8 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> 	  if (!valid_p)
> 	    return NULL;
> 
> +	  have_vfp = true;
> +
> 	  if (tdesc_unnumbered_register (feature, "s0") == 0)
> 	    have_vfp_pseudos = true;
> 
> @@ -9296,8 +9362,41 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> 		 the default type.  */
> 	      if (tdesc_unnumbered_register (feature, "q0") == 0)
> 		have_q_pseudos = true;
> +	    }
> +	}
> +
> +      /* Check for MVE after all the checks for GPR's, VFP and Neon.
> +	 MVE (Helium) is an M-profile extension.  */
> +      if (is_m)
> +	{
> +	  /* Do we have the MVE feature?  */
> +	  feature = tdesc_find_feature (tdesc,"org.gnu.gdb.arm.m-profile-mve");
> +
> +	  if (feature != nullptr)
> +	    {
> +	      /* If we have MVE, we must always have the VPR register.  */
> +	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
> +						  register_count, "vpr");
> +	      if (!valid_p)
> +		{
> +		  warning (_("MVE feature is missing required register vpr."));
> +		  return nullptr;
> +		}
> 
> -	      have_neon = true;
> +	      have_mve = true;
> +	      mve_vpr_regnum = register_count;
> +	      register_count++;
> +
> +	      /* We can't have Q pseudo registers available here, as that
> +		 would mean we have NEON features, and that is only available
> +		 on A and R profiles.  */
> +	      gdb_assert (!have_q_pseudos);
> +
> +	      /* Given we have a M-profile target description, if MVE is
> +		 enabled and there are VFP registers, we should have Q
> +		 pseudo registers (Q0 ~ Q7).  */
> +	      if (have_vfp)
> +		have_q_pseudos = true;
> 	    }
> 	}
>     }
> @@ -9349,6 +9448,13 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>   tdep->have_q_pseudos = have_q_pseudos;
>   tdep->have_neon = have_neon;
> 
> +  /* Adjust the MVE feature settings.  */
> +  if (have_mve)
> +    {
> +      tdep->have_mve = true;
> +      tdep->mve_vpr_regnum = mve_vpr_regnum;
> +    }
> +
>   arm_register_g_packet_guesses (gdbarch);
> 
>   /* Breakpoints.  */
> @@ -9530,21 +9636,39 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>     }
> 
>   /* Initialize the pseudo register data.  */
> +  int num_pseudos = 0;
>   if (tdep->have_vfp_pseudos)
>     {
>       /* VFP single precision pseudo registers (S0~S31).  */
>       tdep->vfp_pseudo_base = register_count;
>       tdep->vfp_pseudo_count = 32;
> -      int num_pseudos = tdep->vfp_pseudo_count;
> +      num_pseudos += tdep->vfp_pseudo_count;
> 
>       if (tdep->have_q_pseudos)
> 	{
> 	  /* NEON quad precision pseudo registers (Q0~Q15).  */
> 	  tdep->q_pseudo_base = register_count + num_pseudos;
> -	  tdep->q_pseudo_count = 16;
> +
> +	  if (have_neon)
> +	    tdep->q_pseudo_count = 16;
> +	  else if (have_mve)
> +	    tdep->q_pseudo_count = ARM_MVE_NUM_Q_REGS;
> +
> 	  num_pseudos += tdep->q_pseudo_count;
> 	}
> +    }
> 
> +  /* Do we have any MVE pseudo registers?  */
> +  if (have_mve)
> +    {
> +      tdep->mve_pseudo_base = register_count + num_pseudos;
> +      tdep->mve_pseudo_count = 1;
> +      num_pseudos += tdep->mve_pseudo_count;
> +    }
> +
> +  /* Set some pseudo register hooks, if we have pseudo registers.  */
> +  if (tdep->have_vfp_pseudos || have_mve)
> +    {
>       set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos);
>       set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_read);
>       set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
> @@ -9595,6 +9719,14 @@ arm_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
> 		      (int) tdep->q_pseudo_count);
>   fprintf_unfiltered (file, _("arm_dump_tdep: have_neon = %i\n"),
> 		      (int) tdep->have_neon);
> +  fprintf_unfiltered (file, _("arm_dump_tdep: have_mve = %s\n"),
> +		      tdep->have_mve? "yes" : "no");
> +  fprintf_unfiltered (file, _("arm_dump_tdep: mve_vpr_regnum = %i\n"),
> +		      tdep->mve_vpr_regnum);
> +  fprintf_unfiltered (file, _("arm_dump_tdep: mve_pseudo_base = %i\n"),
> +		      tdep->mve_pseudo_base);
> +  fprintf_unfiltered (file, _("arm_dump_tdep: mve_pseudo_count = %i\n"),
> +		      tdep->mve_pseudo_count);
>   fprintf_unfiltered (file, _("arm_dump_tdep: Lowest pc = 0x%lx\n"),
> 		      (unsigned long) tdep->lowest_pc);
> }
> diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
> index 614c1a00ab6..4664be629ea 100644
> --- a/gdb/arm-tdep.h
> +++ b/gdb/arm-tdep.h
> @@ -115,6 +115,11 @@ struct gdbarch_tdep
> 				   registers.  */
>   bool have_neon;		/* Do we have a NEON unit?  */
> 
> +  bool have_mve;		/* Do we have a MVE extension?  */
> +  int mve_vpr_regnum;		/* MVE VPR register number.  */
> +  int mve_pseudo_base;		/* Number of the first MVE pseudo register.  */
> +  int mve_pseudo_count;		/* Total number of MVE pseudo registers.  */
> +
>   bool is_m;			/* Does the target follow the "M" profile.  */
>   CORE_ADDR lowest_pc;		/* Lowest address at which instructions 
> 				   will appear.  */
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index c156a1d6739..7ee7508bd8e 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -46213,6 +46213,17 @@ and @samp{xpsr}.
> The @samp{org.gnu.gdb.arm.fpa} feature is optional.  If present, it
> should contain registers @samp{f0} through @samp{f7} and @samp{fps}.
> 
> +The @samp{org.gnu.gdb.arm.m-profile-mve} feature is optional.  If present, it
> +must contain register @samp{vpr}.
> +
> +If the @samp{org.gnu.gdb.arm.m-profile-mve} feature is available, @value{GDBN}
> +will synthesize the @samp{p0} pseudo register from @samp{vpr} contents.
> +
> +If the @samp{org.gnu.gdb.arm.vfp} feature is available alongside the
> +@samp{org.gnu.gdb.arm.m-profile-mve} feature, @value{GDBN} will
> +synthesize the @samp{q} pseudo registers from @samp{d} register
> +contents.
> +
> The @samp{org.gnu.gdb.xscale.iwmmxt} feature is optional.  If present,
> it should contain at least registers @samp{wR0} through @samp{wR15} and
> @samp{wCGR0} through @samp{wCGR3}.  The @samp{wCID}, @samp{wCon},
> diff --git a/gdb/features/Makefile b/gdb/features/Makefile
> index aa38d176539..e478bf838b7 100644
> --- a/gdb/features/Makefile
> +++ b/gdb/features/Makefile
> @@ -203,6 +203,7 @@ FEATURE_XMLFILES = aarch64-core.xml \
> 	arm/arm-core.xml \
> 	arm/arm-fpa.xml \
> 	arm/arm-m-profile.xml \
> +	arm/arm-m-profile-mve.xml \
> 	arm/arm-m-profile-with-fpa.xml \
> 	arm/arm-vfpv2.xml \
> 	arm/arm-vfpv3.xml \
> diff --git a/gdb/features/arm/arm-m-profile-mve.c b/gdb/features/arm/arm-m-profile-mve.c
> new file mode 100644
> index 00000000000..532ae3ba1d1
> --- /dev/null
> +++ b/gdb/features/arm/arm-m-profile-mve.c
> @@ -0,0 +1,20 @@
> +/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
> +  Original: arm-m-profile-mve.xml */
> +
> +#include "gdbsupport/tdesc.h"
> +
> +static int
> +create_feature_arm_arm_m_profile_mve (struct target_desc *result, long regnum)
> +{
> +  struct tdesc_feature *feature;
> +
> +  feature = tdesc_create_feature (result, "org.gnu.gdb.arm.m-profile-mve");
> +  tdesc_type_with_fields *type_with_fields;
> +  type_with_fields = tdesc_create_flags (feature, "vpr_reg", 4);
> +  tdesc_add_bitfield (type_with_fields, "P0", 0, 15);
> +  tdesc_add_bitfield (type_with_fields, "MASK01", 16, 19);
> +  tdesc_add_bitfield (type_with_fields, "MASK23", 20, 23);
> +
> +  tdesc_create_reg (feature, "vpr", regnum++, 1, NULL, 32, "vpr_reg");
> +  return regnum;
> +}
> diff --git a/gdb/features/arm/arm-m-profile-mve.xml b/gdb/features/arm/arm-m-profile-mve.xml
> new file mode 100644
> index 00000000000..cba664c4c5b
> --- /dev/null
> +++ b/gdb/features/arm/arm-m-profile-mve.xml
> @@ -0,0 +1,19 @@
> +<?xml version="1.0"?>
> +<!-- Copyright (C) 2021 Free Software Foundation, Inc.
> +
> +     Copying and distribution of this file, with or without modification,
> +     are permitted in any medium without royalty provided the copyright
> +     notice and this notice are preserved.  -->
> +
> +<!DOCTYPE feature SYSTEM "gdb-target.dtd">
> +<feature name="org.gnu.gdb.arm.m-profile-mve">
> +  <flags id="vpr_reg" size="4">
> +    <!-- ARMv8.1-M and MVE: Unprivileged and privileged Access.  -->
> +    <field name="P0" start="0" end="15"/>
> +    <!-- ARMv8.1-M: Privileged Access only.  -->
> +    <field name="MASK01" start="16" end="19"/>
> +    <!-- ARMv8.1-M: Privileged Access only.  -->
> +    <field name="MASK23" start="20" end="23"/>
> +  </flags>
> +  <reg name="vpr" bitsize="32" type="vpr_reg"/>
> +</feature>
> -- 
> 2.25.1
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] [ARM] Refactor pseudo register numbering
  2021-10-08 16:04   ` Alan Hayward
@ 2021-10-11 13:06     ` Luis Machado
  0 siblings, 0 replies; 11+ messages in thread
From: Luis Machado @ 2021-10-11 13:06 UTC (permalink / raw)
  To: Alan Hayward
  Cc: gdb-patches\@sourceware.org, Srinath Parvathaneni, Peter Maydell, nd

On 10/8/21 1:04 PM, Alan Hayward wrote:
> This is similar to AArch64 target, so mostly Lgtm...
> 
>> On 5 Oct 2021, at 15:45, Luis Machado <luis.machado@linaro.org> wrote:
>>
>> The pseudo register handling for ARM uses some hardcoded constants to
>> determine types and names.  In preparation to the upcoming MVE support
>> patch (that will add another pseudo register), this patch refactors and
>> reorganizes things in order to simplify handling of future pseudo registers.
>>
>> We keep track of the first pseudo register number in a group and the number of
>> pseudo registers in that group.
>>
>> Right now we only have the S and Q pseudo registers.
> 
> Renaming NEON to Q makes sense.
> 
> Why not rename VFP to S?

Yeah, might as well, since it makes more sense. I'll do it before pushing.

Thanks.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-10-11 13:06 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-05 14:45 [PATCH 0/4] [ARM] M-profile MVE extension support Luis Machado
2021-10-05 14:45 ` [PATCH 1/4] [ARM] Refactor some constants Luis Machado
2021-10-08 16:03   ` Alan Hayward
2021-10-05 14:45 ` [PATCH 2/4] [ARM] Small refactoring of arm gdbarch initialization Luis Machado
2021-10-08 16:03   ` Alan Hayward
2021-10-05 14:45 ` [PATCH 3/4] [ARM] Refactor pseudo register numbering Luis Machado
2021-10-08 16:04   ` Alan Hayward
2021-10-11 13:06     ` Luis Machado
2021-10-05 14:45 ` [PATCH 4/4] [ARM] Add support for M-profile MVE extension Luis Machado
2021-10-05 15:55   ` Eli Zaretskii
2021-10-08 16:34   ` Alan Hayward

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).