]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
GDB: aarch64-linux: Load and store VG separately from other SVE registers
authorThiago Jung Bauermann <thiago.bauermann@linaro.org>
Sat, 5 Oct 2024 03:31:08 +0000 (00:31 -0300)
committerThiago Jung Bauermann <thiago.bauermann@linaro.org>
Mon, 21 Apr 2025 03:16:45 +0000 (00:16 -0300)
GDB currently loads and stores all SVE registers, including the VG
register, at the same time.

To suport variable-size SVE registers, GDB needs to be able to load and
store VG separately from them so that it knows the size of the SVE
vector registers in advance.  So change it to fetch or store VG
separately when only that register is requested.

gdb/aarch64-linux-nat.c

index d7869f42e82520aa5cbcc109916aeaefe0f457f4..b5caf004cafcc03ef5490f21484eb299ae5d0ff4 100644 (file)
@@ -310,6 +310,21 @@ store_fpregs_to_thread (const struct regcache *regcache)
     }
 }
 
+/* Fill GDB's REGCACHE with the SVE VG register value from the thread
+   associated with REGCACHE.
+
+   This function handles reading data from SVE or SSVE states, depending
+   on which state is active at the moment.  */
+
+static void
+fetch_sve_vg_from_thread (struct regcache *regcache)
+{
+  uint64_t vq = aarch64_sve_get_vq (regcache->ptid ().lwp ());
+  uint64_t vg = sve_vg_from_vq (vq);
+
+  regcache->raw_supply (AARCH64_SVE_VG_REGNUM, &vg);
+}
+
 /* Fill GDB's REGCACHE with the valid SVE register values from the thread
    associated with REGCACHE.
 
@@ -323,6 +338,19 @@ fetch_sveregs_from_thread (struct regcache *regcache)
   aarch64_sve_regs_copy_to_reg_buf (regcache->ptid ().lwp (), regcache);
 }
 
+/* Store the SVE VG register value from GDB's REGCACHE to the thread
+   associated with REGCACHE.
+
+   This function handles writing data to SVE or SSVE state, depending
+   on which state is active at the moment.  */
+
+static void
+store_sve_vg_to_thread (struct regcache *regcache)
+{
+  if (!aarch64_sve_set_vq (regcache->ptid ().lwp (), regcache))
+    perror_with_name (_ ("Unable to set VG register"));
+}
+
 /* Store the valid SVE register values from GDB's REGCACHE to the thread
    associated with REGCACHE.
 
@@ -583,8 +611,10 @@ aarch64_fetch_registers (struct regcache *regcache, int regno)
     fetch_gregs_from_thread (regcache);
   /* SVE register?  */
   else if ((tdep->has_sve () || tdep->has_sme ())
-          && regno <= AARCH64_SVE_VG_REGNUM)
+          && regno < AARCH64_SVE_VG_REGNUM)
     fetch_sveregs_from_thread (regcache);
+  else if (tdep->has_sve () && regno == AARCH64_SVE_VG_REGNUM)
+    fetch_sve_vg_from_thread (regcache);
   /* FPSIMD register?  */
   else if (regno <= AARCH64_FPCR_REGNUM)
     fetch_fpregs_from_thread (regcache);
@@ -686,8 +716,10 @@ aarch64_store_registers (struct regcache *regcache, int regno)
     store_gregs_to_thread (regcache);
   /* SVE register?  */
   else if ((tdep->has_sve () || tdep->has_sme ())
-          && regno <= AARCH64_SVE_VG_REGNUM)
+          && regno < AARCH64_SVE_VG_REGNUM)
     store_sveregs_to_thread (regcache);
+  else if (tdep->has_sve () && regno == AARCH64_SVE_VG_REGNUM)
+    store_sve_vg_to_thread (regcache);
   /* FPSIMD register?  */
   else if (regno <= AARCH64_FPCR_REGNUM)
     store_fpregs_to_thread (regcache);