]> 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>
Thu, 23 Oct 2025 02:47:59 +0000 (23:47 -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 89ecedda57d480e84b5f6247488c56cdf82d5dc2..279c30dc01e11da2ad5ed84397e11c435c5b037e 100644 (file)
@@ -311,6 +311,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.
 
@@ -324,6 +339,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.
 
@@ -648,8 +676,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);
@@ -759,8 +789,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);