@@ -586,7 +586,7 @@ aarch64_fetch_registers (struct regcache *regcache, int regno)
/* We attempt to fetch SVE registers if there is support for either
SVE or SME (due to the SSVE state of SME). */
- if (tdep->has_sve () || tdep->has_sme ())
+ if (tdep->has_sve || tdep->has_sme ())
fetch_sveregs_from_thread (regcache);
else
fetch_fpregs_from_thread (regcache);
@@ -610,10 +610,9 @@ aarch64_fetch_registers (struct regcache *regcache, int regno)
else if (regno < AARCH64_V0_REGNUM)
fetch_gregs_from_thread (regcache);
/* SVE register? */
- else if ((tdep->has_sve () || tdep->has_sme ())
- && regno < AARCH64_SVE_VG_REGNUM)
+ else if ((tdep->has_sve || tdep->has_sme ()) && regno < AARCH64_SVE_VG_REGNUM)
fetch_sveregs_from_thread (regcache);
- else if (tdep->has_sve () && regno == AARCH64_SVE_VG_REGNUM)
+ else if (tdep->has_sve && regno == AARCH64_SVE_VG_REGNUM)
fetch_sve_vg_from_thread (regcache);
/* FPSIMD register? */
else if (regno <= AARCH64_FPCR_REGNUM)
@@ -694,7 +693,7 @@ aarch64_store_registers (struct regcache *regcache, int regno)
/* We attempt to store SVE registers if there is support for either
SVE or SME (due to the SSVE state of SME). */
- if (tdep->has_sve () || tdep->has_sme ())
+ if (tdep->has_sve || tdep->has_sme ())
store_sveregs_to_thread (regcache);
else
store_fpregs_to_thread (regcache);
@@ -715,10 +714,9 @@ aarch64_store_registers (struct regcache *regcache, int regno)
else if (regno < AARCH64_V0_REGNUM)
store_gregs_to_thread (regcache);
/* SVE register? */
- else if ((tdep->has_sve () || tdep->has_sme ())
- && regno < AARCH64_SVE_VG_REGNUM)
+ else if ((tdep->has_sve || tdep->has_sme ()) && regno < AARCH64_SVE_VG_REGNUM)
store_sveregs_to_thread (regcache);
- else if (tdep->has_sve () && regno == AARCH64_SVE_VG_REGNUM)
+ else if (tdep->has_sve && regno == AARCH64_SVE_VG_REGNUM)
store_sve_vg_to_thread (regcache);
/* FPSIMD register? */
else if (regno <= AARCH64_FPCR_REGNUM)
@@ -911,7 +909,7 @@ aarch64_linux_nat_target::read_description ()
/* SVE/SSVE check. Reading VQ may return either the regular vector length
or the streaming vector length, depending on whether streaming mode is
active or not. */
- features.vq = aarch64_sve_get_vq (tid);
+ features.sve = aarch64_sve_get_vq (tid) != 0;
features.pauth = hwcap & AARCH64_HWCAP_PACA;
features.mte = hwcap2 & HWCAP2_MTE;
features.tls = aarch64_tls_register_count (tid);
@@ -1025,19 +1023,19 @@ aarch64_linux_nat_target::thread_architecture (ptid_t ptid)
the tdep. */
aarch64_gdbarch_tdep *tdep
= gdbarch_tdep<aarch64_gdbarch_tdep> (inf->arch ());
- uint64_t vq = aarch64_sve_get_vq (ptid.lwp ());
+ bool sve = aarch64_sve_get_vq (ptid.lwp ()) != 0;
uint64_t svq = aarch64_za_get_svq (ptid.lwp ());
- if (vq == tdep->vq && svq == tdep->sme_svq)
+ if (sve == tdep->has_sve && svq == tdep->sme_svq)
return inf->arch ();
/* We reach here if any vector length for the thread is different from its
value at process start. Lookup gdbarch via info (potentially creating a
- new one) by using a target description that corresponds to the new vq/svq
- value and the current architecture features. */
+ new one) by using a target description that corresponds to the new
+ vector/matrix state and the current architecture features. */
const struct target_desc *tdesc = gdbarch_target_desc (inf->arch ());
aarch64_features features = aarch64_features_from_target_desc (tdesc);
- features.vq = vq;
+ features.sve = sve;
features.svq = svq;
/* Check for the SME2 feature. */
@@ -275,7 +275,8 @@ read_aarch64_ctx (CORE_ADDR ctx_addr, enum bfd_endian byte_order,
static void
aarch64_linux_restore_vregs (struct gdbarch *gdbarch,
struct trad_frame_cache *cache,
- CORE_ADDR fpsimd_context)
+ CORE_ADDR fpsimd_context,
+ ULONGEST vl)
{
/* WARNING: SIMD state is laid out in memory in target-endian format.
@@ -335,7 +336,7 @@ aarch64_linux_restore_vregs (struct gdbarch *gdbarch,
num_regs + AARCH64_B0_REGNUM
+ i, {buf, B_REGISTER_SIZE});
- if (tdep->has_sve ())
+ if (tdep->has_sve)
trad_frame_set_reg_value_bytes (cache,
num_regs + AARCH64_SVE_V0_REGNUM
+ i, {buf, V_REGISTER_SIZE});
@@ -356,22 +357,22 @@ aarch64_linux_restore_vregs (struct gdbarch *gdbarch,
trad_frame_set_reg_addr (cache, num_regs + AARCH64_B0_REGNUM + i,
offset);
- if (tdep->has_sve ())
+ if (tdep->has_sve)
trad_frame_set_reg_addr (cache, num_regs + AARCH64_SVE_V0_REGNUM
+ i, offset);
}
- if (tdep->has_sve ())
+ if (tdep->has_sve)
{
/* If SVE is supported for this target, zero out the Z
registers then copy the first 16 bytes of each of the V
registers to the associated Z register. Otherwise the Z
registers will contain uninitialized data. */
- std::vector<gdb_byte> z_buffer (tdep->vq * 16);
+ std::vector<gdb_byte> z_buffer (vl);
/* We have already handled the endianness swap above, so we don't need
to worry about it here. */
- memcpy (z_buffer.data (), buf, V_REGISTER_SIZE);
+ memcpy (z_buffer.data (), buf, vl);
trad_frame_set_reg_value_bytes (cache,
AARCH64_SVE_Z0_REGNUM + i,
z_buffer);
@@ -403,8 +404,8 @@ aarch64_linux_read_signal_frame_info (const frame_info_ptr &this_frame,
CORE_ADDR section_end = signal_frame.section_end;
uint32_t size, magic;
bool extra_found = false;
- enum bfd_endian byte_order
- = gdbarch_byte_order (get_frame_arch (this_frame));
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
while ((magic = read_aarch64_ctx (section, byte_order, &size)) != 0
&& size != 0)
@@ -423,6 +424,11 @@ aarch64_linux_read_signal_frame_info (const frame_info_ptr &this_frame,
/* Check if the section is followed by a full SVE dump, and set
sve_regs if it is. */
gdb_byte buf[4];
+ aarch64_gdbarch_tdep *tdep
+ = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch);
+
+ if (!tdep->has_sve)
+ break;
/* Extract the vector length. */
if (target_read_memory (section + AARCH64_SVE_CONTEXT_VL_OFFSET,
@@ -436,6 +442,10 @@ aarch64_linux_read_signal_frame_info (const frame_info_ptr &this_frame,
signal_frame.vl = extract_unsigned_integer (buf, 2, byte_order);
+ if (signal_frame.vl == 0)
+ error (_ ("Invalid vector length in signal frame %" PRIu64 "."),
+ signal_frame.vl);
+
/* Extract the flags to check if we are in streaming mode. */
if (target_read_memory (section
+ AARCH64_SVE_CONTEXT_FLAGS_OFFSET,
@@ -598,7 +608,7 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self,
aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch);
/* Restore the SVE / FPSIMD registers. */
- if (tdep->has_sve () && signal_frame.sve_section != 0)
+ if (tdep->has_sve && signal_frame.sve_section != 0)
{
ULONGEST vq = sve_vq_from_vl (signal_frame.vl);
CORE_ADDR sve_regs = signal_frame.sve_section;
@@ -648,8 +658,9 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self,
fpsimd + AARCH64_FPSIMD_FPCR_OFFSET);
/* If there was no SVE section then set up the V registers. */
- if (!tdep->has_sve () || signal_frame.sve_section == 0)
- aarch64_linux_restore_vregs (gdbarch, this_cache, fpsimd);
+ if (!tdep->has_sve || signal_frame.sve_section == 0)
+ aarch64_linux_restore_vregs (gdbarch, this_cache, fpsimd,
+ tdep->has_sve ? signal_frame.vl : 0);
}
/* Restore the SME registers. */
@@ -726,7 +737,7 @@ aarch64_linux_sigframe_prev_arch (const frame_info_ptr &this_frame,
const struct target_desc *tdesc
= gdbarch_target_desc (get_frame_arch (this_frame));
aarch64_features features = aarch64_features_from_target_desc (tdesc);
- features.vq = sve_vq_from_vl (signal_frame.vl);
+ features.sve = signal_frame.vl != 0;
features.svq = (uint8_t) sve_vq_from_vl (signal_frame.svl);
struct gdbarch_info info;
@@ -1053,9 +1064,12 @@ collect_sve_regset (const struct regset *regset,
gdb_byte *header = (gdb_byte *) buf;
struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch);
- uint64_t vq = tdep->vq;
+ ULONGEST vg;
+ // FIXME: Remove this cast.
+ enum register_status vg_status
+ = const_cast<struct regcache *> (regcache)->raw_read (AARCH64_SVE_VG_REGNUM, &vg);
+ gdb_assert (vg_status == REG_VALID);
gdb_assert (buf != NULL);
gdb_assert (size > SVE_HEADER_SIZE);
@@ -1067,7 +1081,7 @@ collect_sve_regset (const struct regset *regset,
store_unsigned_integer (header + SVE_HEADER_MAX_SIZE_OFFSET,
SVE_HEADER_MAX_SIZE_LENGTH, byte_order, max_size);
store_unsigned_integer (header + SVE_HEADER_VL_OFFSET, SVE_HEADER_VL_LENGTH,
- byte_order, sve_vl_from_vq (vq));
+ byte_order, sve_vl_from_vg (vg));
uint16_t max_vl = SVE_CORE_DUMMY_MAX_VL;
store_unsigned_integer (header + SVE_HEADER_MAX_VL_OFFSET,
SVE_HEADER_MAX_VL_LENGTH, byte_order,
@@ -1437,14 +1451,15 @@ aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
cb (".reg", AARCH64_LINUX_SIZEOF_GREGSET, AARCH64_LINUX_SIZEOF_GREGSET,
&aarch64_linux_gregset, NULL, cb_data);
- if (tdep->has_sve ())
+ if (tdep->has_sve)
{
/* Create this on the fly in order to handle vector register sizes. */
+ // FIXME: Don't use maximum VQ.
const struct regcache_map_entry sve_regmap[] =
{
- { 32, AARCH64_SVE_Z0_REGNUM, (int) (tdep->vq * 16) },
- { 16, AARCH64_SVE_P0_REGNUM, (int) (tdep->vq * 16 / 8) },
- { 1, AARCH64_SVE_FFR_REGNUM, (int) (tdep->vq * 16 / 8) },
+ { 32, AARCH64_SVE_Z0_REGNUM, (int)(AARCH64_MAX_SVE_VQ * 16) },
+ { 16, AARCH64_SVE_P0_REGNUM, (int)(AARCH64_MAX_SVE_VQ * 16 / 8) },
+ { 1, AARCH64_SVE_FFR_REGNUM, (int)(AARCH64_MAX_SVE_VQ * 16 / 8) },
{ 1, AARCH64_FPSR_REGNUM, 4 },
{ 1, AARCH64_FPCR_REGNUM, 4 },
{ 0 }
@@ -1627,7 +1642,7 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch,
Otherwise the SVE section is considered active. This guarantees we will
have the correct target description with the correct SVE vector
length. */
- features.vq = aarch64_linux_core_read_vq_from_sections (gdbarch, abfd);
+ features.sve = aarch64_linux_core_read_vq_from_sections (gdbarch, abfd) != 0;
features.pauth = hwcap & AARCH64_HWCAP_PACA;
features.mte = hwcap2 & HWCAP2_MTE;
@@ -2468,38 +2468,54 @@ aarch64_vnv_type (struct gdbarch *gdbarch)
/* Implement the "dwarf2_reg_to_regnum" gdbarch method. */
static int
-aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
+aarch64_tdep_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
+ int ret = aarch64_dwarf_reg_to_regnum (reg);
+
+ if (ret != -1)
+ return ret;
+
aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch);
+ if (tdep->has_pauth () && reg == AARCH64_DWARF_RA_SIGN_STATE)
+ return tdep->ra_sign_state_regnum;
- if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30)
- return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0;
+ return -1;
+}
+
+/* Implement the "regnum_to_dwarf2_reg" gdbarch method. */
+
+static int
+aarch64_regnum_to_dwarf_reg (struct gdbarch *gdbarch, int regnum)
+{
+ if (regnum >= AARCH64_X0_REGNUM && regnum <= AARCH64_X0_REGNUM + 30)
+ return AARCH64_DWARF_X0 + regnum - AARCH64_X0_REGNUM;
- if (reg == AARCH64_DWARF_SP)
- return AARCH64_SP_REGNUM;
+ if (regnum == AARCH64_SP_REGNUM)
+ return AARCH64_DWARF_SP;
- if (reg == AARCH64_DWARF_PC)
- return AARCH64_PC_REGNUM;
+ if (regnum == AARCH64_PC_REGNUM)
+ return AARCH64_DWARF_PC;
- if (reg >= AARCH64_DWARF_V0 && reg <= AARCH64_DWARF_V0 + 31)
- return AARCH64_V0_REGNUM + reg - AARCH64_DWARF_V0;
+ if (regnum >= AARCH64_V0_REGNUM && regnum <= AARCH64_V0_REGNUM + 31)
+ return AARCH64_DWARF_V0 + regnum - AARCH64_V0_REGNUM;
- if (reg == AARCH64_DWARF_SVE_VG)
- return AARCH64_SVE_VG_REGNUM;
+ if (regnum == AARCH64_SVE_VG_REGNUM)
+ return AARCH64_DWARF_SVE_VG;
- if (reg == AARCH64_DWARF_SVE_FFR)
- return AARCH64_SVE_FFR_REGNUM;
+ if (regnum == AARCH64_SVE_FFR_REGNUM)
+ return AARCH64_DWARF_SVE_FFR;
- if (reg >= AARCH64_DWARF_SVE_P0 && reg <= AARCH64_DWARF_SVE_P0 + 15)
- return AARCH64_SVE_P0_REGNUM + reg - AARCH64_DWARF_SVE_P0;
+ if (regnum >= AARCH64_SVE_P0_REGNUM && regnum <= AARCH64_SVE_P0_REGNUM + 15)
+ return AARCH64_DWARF_SVE_P0 + regnum - AARCH64_SVE_P0_REGNUM;
- if (reg >= AARCH64_DWARF_SVE_Z0 && reg <= AARCH64_DWARF_SVE_Z0 + 15)
- return AARCH64_SVE_Z0_REGNUM + reg - AARCH64_DWARF_SVE_Z0;
+ if (regnum >= AARCH64_SVE_Z0_REGNUM && regnum <= AARCH64_SVE_Z0_REGNUM + 15)
+ return AARCH64_DWARF_SVE_Z0 + regnum - AARCH64_SVE_Z0_REGNUM;
+ aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch);
if (tdep->has_pauth ())
{
- if (reg == AARCH64_DWARF_RA_SIGN_STATE)
- return tdep->ra_sign_state_regnum;
+ if (regnum == tdep->ra_sign_state_regnum)
+ return AARCH64_DWARF_RA_SIGN_STATE;
}
return -1;
@@ -2994,7 +3010,7 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
if (is_w_pseudo_register (gdbarch, regnum))
return w_name[regnum - tdep->w_pseudo_base];
- if (tdep->has_sve ())
+ if (tdep->has_sve)
{
static const char *const sve_v_name[] =
{
@@ -3050,7 +3066,7 @@ aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32)
return aarch64_vnb_type (gdbarch);
- if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM
+ if (tdep->has_sve && p_regnum >= AARCH64_SVE_V0_REGNUM
&& p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
return aarch64_vnv_type (gdbarch);
@@ -3090,7 +3106,7 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
return group == all_reggroup || group == vector_reggroup;
else if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32)
return group == all_reggroup || group == vector_reggroup;
- else if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM
+ else if (tdep->has_sve && p_regnum >= AARCH64_SVE_V0_REGNUM
&& p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
return group == all_reggroup || group == vector_reggroup;
else if (is_sme_pseudo_register (gdbarch, regnum))
@@ -3285,7 +3301,7 @@ aarch64_pseudo_read_value (gdbarch *gdbarch, const frame_info_ptr &next_frame,
return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num,
pseudo_offset - AARCH64_B0_REGNUM);
- if (tdep->has_sve () && pseudo_offset >= AARCH64_SVE_V0_REGNUM
+ if (tdep->has_sve && pseudo_offset >= AARCH64_SVE_V0_REGNUM
&& pseudo_offset < AARCH64_SVE_V0_REGNUM + 32)
return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num,
pseudo_offset - AARCH64_SVE_V0_REGNUM);
@@ -3425,7 +3441,7 @@ aarch64_pseudo_write (gdbarch *gdbarch, const frame_info_ptr &next_frame,
return aarch64_pseudo_write_1 (gdbarch, next_frame,
pseudo_offset - AARCH64_B0_REGNUM, buf);
- if (tdep->has_sve () && pseudo_offset >= AARCH64_SVE_V0_REGNUM
+ if (tdep->has_sve && pseudo_offset >= AARCH64_SVE_V0_REGNUM
&& pseudo_offset < AARCH64_SVE_V0_REGNUM + 32)
return aarch64_pseudo_write_1 (gdbarch, next_frame,
pseudo_offset - AARCH64_SVE_V0_REGNUM, buf);
@@ -3941,10 +3957,6 @@ aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch)
const target_desc *
aarch64_read_description (const aarch64_features &features)
{
- if (features.vq > AARCH64_MAX_SVE_VQ)
- error (_("VQ is %" PRIu64 ", maximum supported value is %d"), features.vq,
- AARCH64_MAX_SVE_VQ);
-
struct target_desc *tdesc = tdesc_aarch64_map[features];
if (tdesc == NULL)
@@ -3956,27 +3968,6 @@ aarch64_read_description (const aarch64_features &features)
return tdesc;
}
-/* Return the VQ used when creating the target description TDESC. */
-
-static uint64_t
-aarch64_get_tdesc_vq (const struct target_desc *tdesc)
-{
- const struct tdesc_feature *feature_sve;
-
- if (!tdesc_has_registers (tdesc))
- return 0;
-
- feature_sve = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sve");
-
- if (feature_sve == nullptr)
- return 0;
-
- uint64_t vl = tdesc_register_bitsize (feature_sve,
- aarch64_sve_register_names[0]) / 8;
- return sve_vq_from_vl (vl);
-}
-
-
/* Return the svq (streaming vector quotient) used when creating the target
description TDESC. */
@@ -4013,7 +4004,8 @@ aarch64_features_from_target_desc (const struct target_desc *tdesc)
if (tdesc == nullptr)
return features;
- features.vq = aarch64_get_tdesc_vq (tdesc);
+ features.sve
+ = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sve") != nullptr;
/* We need to look for a couple pauth feature name variations. */
features.pauth
@@ -4358,13 +4350,11 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
int i, num_regs = 0, num_pseudo_regs = 0;
int first_pauth_regnum = -1, ra_sign_state_offset = -1;
int first_mte_regnum = -1, first_tls_regnum = -1;
- uint64_t vq = aarch64_get_tdesc_vq (info.target_desc);
+ bool has_sve = (info.target_desc == nullptr ? false
+ : tdesc_find_feature (info.target_desc,
+ "org.gnu.gdb.aarch64.sve") != nullptr);
uint64_t svq = aarch64_get_tdesc_svq (info.target_desc);
- if (vq > AARCH64_MAX_SVE_VQ)
- internal_error (_("VQ out of bounds: %s (max %d)"),
- pulongest (vq), AARCH64_MAX_SVE_VQ);
-
if (svq > AARCH64_MAX_SVE_VQ)
internal_error (_("Streaming vector quotient (svq) out of bounds: %s"
" (max %d)"),
@@ -4377,18 +4367,17 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
aarch64_gdbarch_tdep *tdep
= gdbarch_tdep<aarch64_gdbarch_tdep> (best_arch->gdbarch);
- if (tdep && tdep->vq == vq && tdep->sme_svq == svq)
+ if (tdep && tdep->has_sve == has_sve && tdep->sme_svq == svq)
return best_arch->gdbarch;
}
/* Ensure we always have a target descriptor, and that it is for the given VQ
value. */
const struct target_desc *tdesc = info.target_desc;
- if (!tdesc_has_registers (tdesc) || vq != aarch64_get_tdesc_vq (tdesc)
- || svq != aarch64_get_tdesc_svq (tdesc))
+ if (!tdesc_has_registers (tdesc))
{
aarch64_features features;
- features.vq = vq;
+ features.sve = has_sve;
features.svq = svq;
tdesc = aarch64_read_description (features);
}
@@ -4603,7 +4592,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->lowest_pc = 0x20;
tdep->jb_pc = -1; /* Longjump support not enabled by default. */
tdep->jb_elt_size = 8;
- tdep->vq = vq;
+ tdep->has_sve = feature_sve != nullptr;
tdep->pauth_reg_base = first_pauth_regnum;
tdep->pauth_reg_count = pauth_masks;
tdep->ra_sign_state_regnum = -1;
@@ -4690,7 +4679,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_stack_frame_destroyed_p (gdbarch, aarch64_stack_frame_destroyed_p);
/* Internal <-> external register number maps. */
- set_gdbarch_dwarf2_reg_to_regnum (gdbarch, aarch64_dwarf_reg_to_regnum);
+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, aarch64_tdep_dwarf_reg_to_regnum);
+ set_gdbarch_regnum_to_dwarf2_reg (gdbarch, aarch64_regnum_to_dwarf_reg);
/* Returning results. */
set_gdbarch_return_value_as_value (gdbarch, aarch64_return_value);
@@ -4857,6 +4847,9 @@ aarch64_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
gdb_printf (file, _("aarch64_dump_tdep: Lowest pc = 0x%s\n"),
paddress (gdbarch, tdep->lowest_pc));
+ gdb_printf (file, _ ("aarch64_dump_tdep: has_sve = %s\n"),
+ tdep->has_sve ? "true" : "false");
+
/* SME fields. */
gdb_printf (file, _("aarch64_dump_tdep: sme_tile_type_q = %s\n"),
host_address_to_string (tdep->sme_tile_type_q));
@@ -31,17 +31,6 @@
struct gdbarch;
struct regset;
-/* AArch64 Dwarf register numbering. */
-#define AARCH64_DWARF_X0 0
-#define AARCH64_DWARF_SP 31
-#define AARCH64_DWARF_PC 32
-#define AARCH64_DWARF_RA_SIGN_STATE 34
-#define AARCH64_DWARF_V0 64
-#define AARCH64_DWARF_SVE_VG 46
-#define AARCH64_DWARF_SVE_FFR 47
-#define AARCH64_DWARF_SVE_P0 48
-#define AARCH64_DWARF_SVE_Z0 96
-
/* Size of integer registers. */
#define X_REGISTER_SIZE 8
#define B_REGISTER_SIZE 1
@@ -100,14 +89,8 @@ struct aarch64_gdbarch_tdep : gdbarch_tdep_base
int (*aarch64_syscall_record) (struct regcache *regcache,
unsigned long svc_number) = nullptr;
- /* The VQ value for SVE targets, or zero if SVE is not supported. */
- uint64_t vq = 0;
-
- /* Returns true if the target supports SVE. */
- bool has_sve () const
- {
- return vq != 0;
- }
+ /* Whether SVE is supported. */
+ bool has_sve = false;
int pauth_reg_base = 0;
/* Number of pauth masks. */
@@ -42,10 +42,10 @@ aarch64_create_target_description (const aarch64_features &features)
regnum = create_feature_aarch64_core (tdesc.get (), regnum);
- if (features.vq == 0)
+ if (!features.sve)
regnum = create_feature_aarch64_fpu (tdesc.get (), regnum);
else
- regnum = create_feature_aarch64_sve (tdesc.get (), regnum, features.vq);
+ regnum = create_feature_aarch64_sve (tdesc.get (), regnum);
if (features.pauth)
regnum = create_feature_aarch64_pauth (tdesc.get (), regnum);
@@ -98,3 +98,35 @@ aarch64_mask_from_pac_registers (const CORE_ADDR cmask, const CORE_ADDR dmask)
return cmask;
}
+
+/* See arch/aarch64.h. */
+
+int
+aarch64_dwarf_reg_to_regnum (int reg)
+{
+ if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30)
+ return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0;
+
+ if (reg == AARCH64_DWARF_SP)
+ return AARCH64_SP_REGNUM;
+
+ if (reg == AARCH64_DWARF_PC)
+ return AARCH64_PC_REGNUM;
+
+ if (reg >= AARCH64_DWARF_V0 && reg <= AARCH64_DWARF_V0 + 31)
+ return AARCH64_V0_REGNUM + reg - AARCH64_DWARF_V0;
+
+ if (reg == AARCH64_DWARF_SVE_VG)
+ return AARCH64_SVE_VG_REGNUM;
+
+ if (reg == AARCH64_DWARF_SVE_FFR)
+ return AARCH64_SVE_FFR_REGNUM;
+
+ if (reg >= AARCH64_DWARF_SVE_P0 && reg <= AARCH64_DWARF_SVE_P0 + 15)
+ return AARCH64_SVE_P0_REGNUM + reg - AARCH64_DWARF_SVE_P0;
+
+ if (reg >= AARCH64_DWARF_SVE_Z0 && reg <= AARCH64_DWARF_SVE_Z0 + 15)
+ return AARCH64_SVE_Z0_REGNUM + reg - AARCH64_DWARF_SVE_Z0;
+
+ return -1;
+}
@@ -26,12 +26,7 @@
used to select register sets. */
struct aarch64_features
{
- /* A non zero VQ value indicates both the presence of SVE and the
- Vector Quotient - the number of 128-bit chunks in an SVE Z
- register.
-
- The maximum value for VQ is 16 (5 bits). */
- uint64_t vq = 0;
+ bool sve = false;
bool pauth = false;
bool mte = false;
@@ -55,7 +50,7 @@ struct aarch64_features
inline bool operator==(const aarch64_features &lhs, const aarch64_features &rhs)
{
- return lhs.vq == rhs.vq
+ return lhs.sve == rhs.sve
&& lhs.pauth == rhs.pauth
&& lhs.mte == rhs.mte
&& lhs.tls == rhs.tls
@@ -72,7 +67,7 @@ namespace std
{
std::size_t h;
- h = features.vq;
+ h = features.sve;
h = h << 1 | features.pauth;
h = h << 1 | features.mte;
/* Shift by two bits for now. We may need to increase this in the future
@@ -107,6 +102,9 @@ CORE_ADDR aarch64_remove_top_bits (CORE_ADDR pointer, CORE_ADDR mask);
CORE_ADDR
aarch64_mask_from_pac_registers (const CORE_ADDR cmask, const CORE_ADDR dmask);
+/* Map DWARF reg number to GDB regnum. */
+int aarch64_dwarf_reg_to_regnum (int reg);
+
/* Register numbers of various important registers.
Note that on SVE, the Z registers reuse the V register numbers and the V
registers become pseudo registers. */
@@ -136,6 +134,17 @@ enum aarch64_regnum
AARCH64_LAST_V_ARG_REGNUM = AARCH64_V0_REGNUM + 7
};
+/* AArch64 Dwarf register numbering. */
+#define AARCH64_DWARF_X0 0
+#define AARCH64_DWARF_SP 31
+#define AARCH64_DWARF_PC 32
+#define AARCH64_DWARF_RA_SIGN_STATE 34
+#define AARCH64_DWARF_V0 64
+#define AARCH64_DWARF_SVE_VG 46
+#define AARCH64_DWARF_SVE_FFR 47
+#define AARCH64_DWARF_SVE_P0 48
+#define AARCH64_DWARF_SVE_Z0 96
+
/* Sizes of various AArch64 registers. */
#define AARCH64_TLS_REGISTER_SIZE 8
#define V_REGISTER_SIZE 16
@@ -202,6 +202,7 @@ FEATURE_XMLFILES = aarch64-core.xml \
aarch64-fpu.xml \
aarch64-pauth.xml \
aarch64-mte.xml \
+ aarch64-sve.xml \
arc/v1-core.xml \
arc/v1-aux.xml \
arc/v2-core.xml \
@@ -1,76 +1,86 @@
-/* Copyright (C) 2018-2024 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: aarch64-sve.xml */
#include "gdbsupport/tdesc.h"
-
-/* This function is NOT auto generated from xml. Create the aarch64 with SVE
- feature into RESULT, where SCALE is the number of 128 bit chunks in a Z
- register. */
+#include "dwarf2.h"
static int
-create_feature_aarch64_sve (struct target_desc *result, long regnum,
- uint64_t scale)
+create_feature_aarch64_sve (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
- tdesc_type *element_type, *field_type;
- tdesc_type_with_fields *type_with_fields;
feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.sve");
-
+ tdesc_type *element_type;
element_type = tdesc_named_type (feature, "uint128");
- tdesc_create_vector (feature, "svevqu", element_type, scale);
+ gdb_byte svevq_count_locexpr[5];
+ svevq_count_locexpr[0] = DW_OP_bregx;
+ svevq_count_locexpr[1] = 46;
+ svevq_count_locexpr[2] = 0;
+ svevq_count_locexpr[3] = DW_OP_lit2;
+ svevq_count_locexpr[4] = DW_OP_div;
+ tdesc_create_vector (feature, "svevqu", element_type, svevq_count_locexpr);
element_type = tdesc_named_type (feature, "int128");
- tdesc_create_vector (feature, "svevqs", element_type, scale);
+ tdesc_create_vector (feature, "svevqs", element_type, svevq_count_locexpr);
element_type = tdesc_named_type (feature, "ieee_double");
- tdesc_create_vector (feature, "svevdf", element_type, 2 * scale);
+ gdb_byte svevd_count_locexpr[3];
+ svevd_count_locexpr[0] = DW_OP_bregx;
+ svevd_count_locexpr[1] = 46;
+ svevd_count_locexpr[2] = 0;
+ tdesc_create_vector (feature, "svevdf", element_type, svevd_count_locexpr);
element_type = tdesc_named_type (feature, "uint64");
- tdesc_create_vector (feature, "svevdu", element_type, 2 * scale);
+ tdesc_create_vector (feature, "svevdu", element_type, svevd_count_locexpr);
element_type = tdesc_named_type (feature, "int64");
- tdesc_create_vector (feature, "svevds", element_type, 2 * scale);
+ tdesc_create_vector (feature, "svevds", element_type, svevd_count_locexpr);
element_type = tdesc_named_type (feature, "ieee_single");
- tdesc_create_vector (feature, "svevsf", element_type, 4 * scale);
+ gdb_byte svevs_count_locexpr[5];
+ svevs_count_locexpr[0] = DW_OP_bregx;
+ svevs_count_locexpr[1] = 46;
+ svevs_count_locexpr[2] = 0;
+ svevs_count_locexpr[3] = DW_OP_lit2;
+ svevs_count_locexpr[4] = DW_OP_mul;
+ tdesc_create_vector (feature, "svevsf", element_type, svevs_count_locexpr);
element_type = tdesc_named_type (feature, "uint32");
- tdesc_create_vector (feature, "svevsu", element_type, 4 * scale);
+ tdesc_create_vector (feature, "svevsu", element_type, svevs_count_locexpr);
element_type = tdesc_named_type (feature, "int32");
- tdesc_create_vector (feature, "svevss", element_type, 4 * scale);
+ tdesc_create_vector (feature, "svevss", element_type, svevs_count_locexpr);
element_type = tdesc_named_type (feature, "ieee_half");
- tdesc_create_vector (feature, "svevhf", element_type, 8 * scale);
+ gdb_byte svevh_count_locexpr[5];
+ svevh_count_locexpr[0] = DW_OP_bregx;
+ svevh_count_locexpr[1] = 46;
+ svevh_count_locexpr[2] = 0;
+ svevh_count_locexpr[3] = DW_OP_lit4;
+ svevh_count_locexpr[4] = DW_OP_mul;
+ tdesc_create_vector (feature, "svevhf", element_type, svevh_count_locexpr);
element_type = tdesc_named_type (feature, "uint16");
- tdesc_create_vector (feature, "svevhu", element_type, 8 * scale);
+ tdesc_create_vector (feature, "svevhu", element_type, svevh_count_locexpr);
element_type = tdesc_named_type (feature, "int16");
- tdesc_create_vector (feature, "svevhs", element_type, 8 * scale);
+ tdesc_create_vector (feature, "svevhs", element_type, svevh_count_locexpr);
element_type = tdesc_named_type (feature, "uint8");
- tdesc_create_vector (feature, "svevbu", element_type, 16 * scale);
+ gdb_byte svevb_count_locexpr[5];
+ svevb_count_locexpr[0] = DW_OP_bregx;
+ svevb_count_locexpr[1] = 46;
+ svevb_count_locexpr[2] = 0;
+ svevb_count_locexpr[3] = DW_OP_lit8;
+ svevb_count_locexpr[4] = DW_OP_mul;
+ tdesc_create_vector (feature, "svevbu", element_type, svevb_count_locexpr);
element_type = tdesc_named_type (feature, "int8");
- tdesc_create_vector (feature, "svevbs", element_type, 16 * scale);
+ tdesc_create_vector (feature, "svevbs", element_type, svevb_count_locexpr);
+ tdesc_type_with_fields *type_with_fields;
type_with_fields = tdesc_create_union (feature, "svevnq");
+ tdesc_type *field_type;
field_type = tdesc_named_type (feature, "svevqu");
tdesc_add_field (type_with_fields, "u", field_type);
field_type = tdesc_named_type (feature, "svevqs");
@@ -118,10 +128,15 @@ create_feature_aarch64_sve (struct target_desc *result, long regnum,
field_type = tdesc_named_type (feature, "svevnb");
tdesc_add_field (type_with_fields, "b", field_type);
- field_type = tdesc_named_type (feature, "uint8");
- tdesc_create_vector (feature, "svep", field_type, 2 * scale);
+ element_type = tdesc_named_type (feature, "uint8");
+ gdb_byte svep_locexpr[5];
+ svep_locexpr[0] = DW_OP_bregx;
+ svep_locexpr[1] = 46;
+ svep_locexpr[2] = 0;
+ svep_locexpr[3] = DW_OP_lit4;
+ svep_locexpr[4] = DW_OP_mul;
+ tdesc_create_vector (feature, "svep", element_type, svep_locexpr);
- /* FPSR register type */
type_with_fields = tdesc_create_flags (feature, "fpsr_flags", 4);
tdesc_add_flag (type_with_fields, 0, "IOC");
tdesc_add_flag (type_with_fields, 1, "DZC");
@@ -135,7 +150,6 @@ create_feature_aarch64_sve (struct target_desc *result, long regnum,
tdesc_add_flag (type_with_fields, 30, "Z");
tdesc_add_flag (type_with_fields, 31, "N");
- /* FPCR register type */
type_with_fields = tdesc_create_flags (feature, "fpcr_flags", 4);
tdesc_add_flag (type_with_fields, 0, "FIZ");
tdesc_add_flag (type_with_fields, 1, "AH");
@@ -155,57 +169,58 @@ create_feature_aarch64_sve (struct target_desc *result, long regnum,
tdesc_add_flag (type_with_fields, 25, "DN");
tdesc_add_flag (type_with_fields, 26, "AHP");
- tdesc_create_reg (feature, "z0", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z1", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z2", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z3", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z4", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z5", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z6", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z7", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z8", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z9", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z10", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z11", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z12", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z13", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z14", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z15", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z16", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z17", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z18", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z19", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z20", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z21", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z22", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z23", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z24", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z25", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z26", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z27", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z28", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z29", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z30", regnum++, 1, NULL, 128 * scale, "svev");
- tdesc_create_reg (feature, "z31", regnum++, 1, NULL, 128 * scale, "svev");
+ regnum = 34;
+ tdesc_create_reg (feature, "z0", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z1", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z2", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z3", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z4", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z5", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z6", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z7", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z8", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z9", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z10", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z11", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z12", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z13", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z14", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z15", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z16", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z17", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z18", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z19", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z20", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z21", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z22", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z23", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z24", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z25", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z26", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z27", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z28", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z29", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z30", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
+ tdesc_create_reg (feature, "z31", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev");
tdesc_create_reg (feature, "fpsr", regnum++, 1, NULL, 32, "fpsr_flags");
tdesc_create_reg (feature, "fpcr", regnum++, 1, NULL, 32, "fpcr_flags");
- tdesc_create_reg (feature, "p0", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p1", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p2", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p3", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p4", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p5", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p6", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p7", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p8", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p9", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p10", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p11", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p12", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p13", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p14", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "p15", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "ffr", regnum++, 1, NULL, 16 * scale, "svep");
- tdesc_create_reg (feature, "vg", regnum++, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "p0", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p1", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p2", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p3", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p4", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p5", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p6", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p7", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p8", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p9", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p10", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p11", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p12", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p13", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p14", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "p15", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "ffr", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep");
+ tdesc_create_reg (feature, "vg", regnum++, 1, NULL, 64, "int", true);
return regnum;
}
new file mode 100644
@@ -0,0 +1,217 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2024 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.aarch64.sve">
+ <architecture>aarch64</architecture>
+ <vector id="svevqu" type="uint128">
+ <count id="svevq_count">
+ <!-- How many 128-bit elements there are in a z register: $vg / 2 -->
+ <math>
+ <apply>
+ <divide/>
+ <ci>85</ci>
+ <cn>2</cn>
+ </apply>
+ </math>
+ </count>
+ </vector>
+ <vector id="svevqs" type="int128">
+ <count idref="svevq_count"/>
+ </vector>
+ <vector id="svevdf" type="ieee_double">
+ <count id="svevd_count">
+ <!-- How many 64-bit elements there are in a z register: $vg -->
+ <math>
+ <ci>85</ci>
+ </math>
+ </count>
+ </vector>
+ <vector id="svevdu" type="uint64">
+ <count idref="svevd_count"/>
+ </vector>
+ <vector id="svevds" type="int64">
+ <count idref="svevd_count"/>
+ </vector>
+ <vector id="svevsf" type="ieee_single">
+ <count id="svevs_count">
+ <!-- How many 32-bit elements there are in a z register: $vg * 2 -->
+ <math>
+ <apply>
+ <times/>
+ <ci>85</ci>
+ <cn>2</cn>
+ </apply>
+ </math>
+ </count>
+ </vector>
+ <vector id="svevsu" type="uint32">
+ <count idref="svevs_count"/>
+ </vector>
+ <vector id="svevss" type="int32">
+ <count idref="svevs_count"/>
+ </vector>
+ <vector id="svevhf" type="ieee_half">
+ <count id="svevh_count">
+ <!-- How many 16-bit elements there are in a z register: $vg * 4 -->
+ <math>
+ <apply>
+ <times/>
+ <ci>85</ci>
+ <cn>4</cn>
+ </apply>
+ </math>
+ </count>
+ </vector>
+ <vector id="svevhu" type="uint16">
+ <count idref="svevh_count"/>
+ </vector>
+ <vector id="svevhs" type="int16">
+ <count idref="svevh_count"/>
+ </vector>
+ <vector id="svevbu" type="uint8">
+ <count id="svevb_count">
+ <!-- How many 8-bit elements there are in a z register: $vg * 8 -->
+ <math>
+ <apply>
+ <times/>
+ <ci>85</ci>
+ <cn>8</cn>
+ </apply>
+ </math>
+ </count>
+ </vector>
+ <vector id="svevbs" type="int8">
+ <count idref="svevb_count"/>
+ </vector>
+ <union id="svevnq">
+ <field name="u" type="svevqu"/>
+ <field name="s" type="svevqs"/>
+ </union>
+ <union id="svevnd">
+ <field name="f" type="svevdf"/>
+ <field name="u" type="svevdu"/>
+ <field name="s" type="svevds"/>
+ </union>
+ <union id="svevns">
+ <field name="f" type="svevsf"/>
+ <field name="u" type="svevsu"/>
+ <field name="s" type="svevss"/>
+ </union>
+ <union id="svevnh">
+ <field name="f" type="svevhf"/>
+ <field name="u" type="svevhu"/>
+ <field name="s" type="svevhs"/>
+ </union>
+ <union id="svevnb">
+ <field name="u" type="svevbu"/>
+ <field name="s" type="svevbs"/>
+ </union>
+ <union id="svev">
+ <field name="q" type="svevnq"/>
+ <field name="d" type="svevnd"/>
+ <field name="s" type="svevns"/>
+ <field name="h" type="svevnh"/>
+ <field name="b" type="svevnb"/>
+ </union>
+ <vector id="svep" type="uint8">
+ <count>
+ <!-- How many predicate elements there are in a p register: $vg * 4 -->
+ <math>
+ <apply>
+ <times/>
+ <ci>85</ci>
+ <cn>4</cn>
+ </apply>
+ </math>
+ </count>
+ </vector>
+ <flags id="fpsr_flags" size="4">
+ <field name="IOC" start="0" end="0" type="bool"/>
+ <field name="DZC" start="1" end="1" type="bool"/>
+ <field name="OFC" start="2" end="2" type="bool"/>
+ <field name="UFC" start="3" end="3" type="bool"/>
+ <field name="IXC" start="4" end="4" type="bool"/>
+ <field name="IDC" start="7" end="7" type="bool"/>
+ <field name="QC" start="27" end="27" type="bool"/>
+ <field name="V" start="28" end="28" type="bool"/>
+ <field name="C" start="29" end="29" type="bool"/>
+ <field name="Z" start="30" end="30" type="bool"/>
+ <field name="N" start="31" end="31" type="bool"/>
+ </flags>
+ <flags id="fpcr_flags" size="4">
+ <field name="FIZ" start="0" end="0" type="bool"/>
+ <field name="AH" start="1" end="1" type="bool"/>
+ <field name="NEP" start="2" end="2" type="bool"/>
+ <field name="IOE" start="8" end="8" type="bool"/>
+ <field name="DZE" start="9" end="9" type="bool"/>
+ <field name="OFE" start="10" end="10" type="bool"/>
+ <field name="UFE" start="11" end="11" type="bool"/>
+ <field name="IXE" start="12" end="12" type="bool"/>
+ <field name="EBF" start="13" end="13" type="bool"/>
+ <field name="IDE" start="15" end="15" type="bool"/>
+ <field name="Len" start="16" end="18" type="uint32"/>
+ <field name="FZ16" start="19" end="19" type="bool"/>
+ <field name="Stride" start="20" end="21" type="uint32"/>
+ <field name="RMode" start="22" end="23" type="uint32"/>
+ <field name="FZ" start="24" end="24" type="bool"/>
+ <field name="DN" start="25" end="25" type="bool"/>
+ <field name="AHP" start="26" end="26" type="bool"/>
+ </flags>
+ <reg name="z0" bitsize="-1" type="svev" regnum="34"/>
+ <reg name="z1" bitsize="-1" type="svev" regnum="35"/>
+ <reg name="z2" bitsize="-1" type="svev" regnum="36"/>
+ <reg name="z3" bitsize="-1" type="svev" regnum="37"/>
+ <reg name="z4" bitsize="-1" type="svev" regnum="38"/>
+ <reg name="z5" bitsize="-1" type="svev" regnum="39"/>
+ <reg name="z6" bitsize="-1" type="svev" regnum="40"/>
+ <reg name="z7" bitsize="-1" type="svev" regnum="41"/>
+ <reg name="z8" bitsize="-1" type="svev" regnum="42"/>
+ <reg name="z9" bitsize="-1" type="svev" regnum="43"/>
+ <reg name="z10" bitsize="-1" type="svev" regnum="44"/>
+ <reg name="z11" bitsize="-1" type="svev" regnum="45"/>
+ <reg name="z12" bitsize="-1" type="svev" regnum="46"/>
+ <reg name="z13" bitsize="-1" type="svev" regnum="47"/>
+ <reg name="z14" bitsize="-1" type="svev" regnum="48"/>
+ <reg name="z15" bitsize="-1" type="svev" regnum="49"/>
+ <reg name="z16" bitsize="-1" type="svev" regnum="50"/>
+ <reg name="z17" bitsize="-1" type="svev" regnum="51"/>
+ <reg name="z18" bitsize="-1" type="svev" regnum="52"/>
+ <reg name="z19" bitsize="-1" type="svev" regnum="53"/>
+ <reg name="z20" bitsize="-1" type="svev" regnum="54"/>
+ <reg name="z21" bitsize="-1" type="svev" regnum="55"/>
+ <reg name="z22" bitsize="-1" type="svev" regnum="56"/>
+ <reg name="z23" bitsize="-1" type="svev" regnum="57"/>
+ <reg name="z24" bitsize="-1" type="svev" regnum="58"/>
+ <reg name="z25" bitsize="-1" type="svev" regnum="59"/>
+ <reg name="z26" bitsize="-1" type="svev" regnum="60"/>
+ <reg name="z27" bitsize="-1" type="svev" regnum="61"/>
+ <reg name="z28" bitsize="-1" type="svev" regnum="62"/>
+ <reg name="z29" bitsize="-1" type="svev" regnum="63"/>
+ <reg name="z30" bitsize="-1" type="svev" regnum="64"/>
+ <reg name="z31" bitsize="-1" type="svev" regnum="65"/>
+ <reg name="fpsr" bitsize="32" type="fpsr_flags" regnum="66"/>
+ <reg name="fpcr" bitsize="32" type="fpcr_flags" regnum="67"/>
+ <reg name="p0" bitsize="-1" type="svep" regnum="68"/>
+ <reg name="p1" bitsize="-1" type="svep" regnum="69"/>
+ <reg name="p2" bitsize="-1" type="svep" regnum="70"/>
+ <reg name="p3" bitsize="-1" type="svep" regnum="71"/>
+ <reg name="p4" bitsize="-1" type="svep" regnum="72"/>
+ <reg name="p5" bitsize="-1" type="svep" regnum="73"/>
+ <reg name="p6" bitsize="-1" type="svep" regnum="74"/>
+ <reg name="p7" bitsize="-1" type="svep" regnum="75"/>
+ <reg name="p8" bitsize="-1" type="svep" regnum="76"/>
+ <reg name="p9" bitsize="-1" type="svep" regnum="77"/>
+ <reg name="p10" bitsize="-1" type="svep" regnum="78"/>
+ <reg name="p11" bitsize="-1" type="svep" regnum="79"/>
+ <reg name="p12" bitsize="-1" type="svep" regnum="80"/>
+ <reg name="p13" bitsize="-1" type="svep" regnum="81"/>
+ <reg name="p14" bitsize="-1" type="svep" regnum="82"/>
+ <reg name="p15" bitsize="-1" type="svep" regnum="83"/>
+ <reg name="ffr" bitsize="-1" type="svep" regnum="84"/>
+ <reg name="vg" bitsize="64" type="int" regnum="85"/>
+</feature>
@@ -57,6 +57,7 @@ case "${gdbserver_host}" in
srv_tgtobj="${srv_tgtobj} $srv_linux_obj"
srv_linux_regsets=yes
srv_linux_thread_db=yes
+ srv_dwarf_reg_to_regnum=yes
ipa_obj="linux-aarch64-ipa.o"
ipa_obj="${ipa_obj} linux-aarch64-tdesc-ipa.o"
ipa_obj="${ipa_obj} arch/aarch64-ipa.o"
@@ -884,11 +884,11 @@ aarch64_adjust_register_sets (const struct aarch64_features &features)
break;
case NT_FPREGSET:
/* This is unavailable when SVE is present. */
- if (features.vq == 0)
+ if (!features.sve)
regset->size = sizeof (struct user_fpsimd_state);
break;
case NT_ARM_SVE:
- if (features.vq > 0)
+ if (features.sve)
regset->size = SVE_PT_SIZE (AARCH64_MAX_SVE_VQ, SVE_PT_REGS_SVE);
break;
case NT_ARM_PAC_MASK:
@@ -938,7 +938,7 @@ aarch64_target::low_arch_setup ()
struct aarch64_features features;
int pid = current_thread->id.pid ();
- features.vq = aarch64_sve_get_vq (tid);
+ features.sve = aarch64_sve_get_vq (tid) != 0;
/* A-profile PAC is 64-bit only. */
features.pauth = linux_get_hwcap (pid, 8) & AARCH64_HWCAP_PACA;
/* A-profile MTE is 64-bit only. */
@@ -37,10 +37,6 @@ aarch64_linux_read_description (const aarch64_features &features)
initialised. */
static std::unordered_map<aarch64_features, target_desc *> tdesc_aarch64_map;
- if (features.vq > AARCH64_MAX_SVE_VQ)
- error (_("VQ is %" PRIu64 ", maximum supported value is %d"), features.vq,
- AARCH64_MAX_SVE_VQ);
-
if (features.svq > AARCH64_MAX_SVE_VQ)
error (_("Streaming svq is %" PRIu8 ", maximum supported value is %d"),
features.svq,
@@ -60,8 +56,6 @@ aarch64_linux_read_description (const aarch64_features &features)
expedited_registers.push_back ("sp");
expedited_registers.push_back ("pc");
- if (features.vq > 0)
- expedited_registers.push_back ("vg");
if (features.svq > 0)
expedited_registers.push_back ("svg");
@@ -74,3 +68,14 @@ aarch64_linux_read_description (const aarch64_features &features)
return tdesc;
}
+
+/* See gdbsupport/tdesc.h. */
+
+int
+tdesc_dwarf_reg_to_regnum (const char *arch, int dwarf_reg)
+{
+ if (!strcmp (arch, "aarch64"))
+ return aarch64_dwarf_reg_to_regnum (dwarf_reg);
+
+ return -1;
+}