... if register-based parameter changes.
}
}
+static bool
+aarch64_invalidate_tdesc_parameters (struct gdbarch *gdbarch, int regno,
+ reg_buffer *regcache)
+{
+ /* All current AArch64 parameters depend on VG. */
+ if (tdesc_num_parameters (gdbarch) == 0 || regno != AARCH64_SVE_VG_REGNUM)
+ return false;
+
+ aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch);
+
+ regcache->invalidate_tdesc_parameter (tdep->param_sve_vector_length);
+ regcache->invalidate_tdesc_parameter (tdep->param_sve_predicate_length);
+
+ return true;
+}
+
/* Given NAMES, a vector of strings, initialize it with all the SME
pseudo-register names for the current streaming vector length. */
tdep->param_sve_predicate_length = *param_id;
set_gdbarch_fetch_tdesc_parameter (gdbarch, aarch64_fetch_tdesc_parameter);
+ set_gdbarch_invalidate_tdesc_parameters (gdbarch,
+ aarch64_invalidate_tdesc_parameters);
return gdbarch;
}
return false;
}
+static bool
+default_invalidate_tdesc_parameters (struct gdbarch *gdbarch, int regno,
+ reg_buffer *regcache)
+{
+ return false;
+}
+
/* Non-zero if we want to trace architecture code. */
#ifndef GDBARCH_DEBUG
gdbarch_core_parse_exec_context_ftype *core_parse_exec_context = default_core_parse_exec_context;
gdbarch_fetch_tdesc_parameter_ftype *fetch_tdesc_parameter = default_fetch_tdesc_parameter;
gdbarch_register_is_variable_size_ftype *register_is_variable_size = default_register_is_variable_size;
+ gdbarch_invalidate_tdesc_parameters_ftype *invalidate_tdesc_parameters = default_invalidate_tdesc_parameters;
};
/* Create a new ``struct gdbarch'' based on information provided by
/* Skip verify of core_parse_exec_context, invalid_p == 0. */
/* Skip verify of fetch_tdesc_parameter, invalid_p == 0. */
/* Skip verify of register_is_variable_size, invalid_p == 0. */
+ /* Skip verify of invalidate_tdesc_parameters, invalid_p == 0. */
if (!log.empty ())
internal_error (_("verify_gdbarch: the following are invalid ...%s"),
log.c_str ());
gdb_printf (file,
"gdbarch_dump: register_is_variable_size = <%s>\n",
host_address_to_string (gdbarch->register_is_variable_size));
+ gdb_printf (file,
+ "gdbarch_dump: invalidate_tdesc_parameters = <%s>\n",
+ host_address_to_string (gdbarch->invalidate_tdesc_parameters));
if (gdbarch->dump_tdep != NULL)
gdbarch->dump_tdep (gdbarch, file);
}
{
gdbarch->register_is_variable_size = register_is_variable_size;
}
+
+bool
+gdbarch_invalidate_tdesc_parameters (struct gdbarch *gdbarch, int regno, reg_buffer *regcache)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->invalidate_tdesc_parameters != NULL);
+ if (gdbarch_debug >= 2)
+ gdb_printf (gdb_stdlog, "gdbarch_invalidate_tdesc_parameters called\n");
+ return gdbarch->invalidate_tdesc_parameters (gdbarch, regno, regcache);
+}
+
+void
+set_gdbarch_invalidate_tdesc_parameters (struct gdbarch *gdbarch,
+ gdbarch_invalidate_tdesc_parameters_ftype invalidate_tdesc_parameters)
+{
+ gdbarch->invalidate_tdesc_parameters = invalidate_tdesc_parameters;
+}
typedef bool (gdbarch_register_is_variable_size_ftype) (struct gdbarch *gdbarch, int regno);
extern bool gdbarch_register_is_variable_size (struct gdbarch *gdbarch, int regno);
extern void set_gdbarch_register_is_variable_size (struct gdbarch *gdbarch, gdbarch_register_is_variable_size_ftype *register_is_variable_size);
+
+/* Invalidate all target description parameters in REGCACHE which depend on the
+ value of REGNO. Returns true if any parameter was invalidated, false
+ otherwise. */
+
+typedef bool (gdbarch_invalidate_tdesc_parameters_ftype) (struct gdbarch *gdbarch, int regno, reg_buffer *regcache);
+extern bool gdbarch_invalidate_tdesc_parameters (struct gdbarch *gdbarch, int regno, reg_buffer *regcache);
+extern void set_gdbarch_invalidate_tdesc_parameters (struct gdbarch *gdbarch, gdbarch_invalidate_tdesc_parameters_ftype *invalidate_tdesc_parameters);
predefault="default_register_is_variable_size",
invalid=False,
)
+
+Method(
+ comment="""
+Invalidate all target description parameters in REGCACHE which depend on the
+value of REGNO. Returns true if any parameter was invalidated, false
+otherwise.
+""",
+ type="bool",
+ name="invalidate_tdesc_parameters",
+ params=[("int", "regno"), ("reg_buffer *", "regcache")],
+ predefault="default_invalidate_tdesc_parameters",
+ invalid=False,
+)
/* See regcache.h. */
+void
+reg_buffer::invalidate_variable_size_registers ()
+{
+ /* There's nothing to do if there are already no variable-size register
+ contents. */
+ if (m_variable_size_registers == nullptr)
+ return;
+
+ for (unsigned int i = 0; i < m_descr->nr_cooked_registers; i++)
+ if (m_descr->register_is_variable_size[i])
+ invalidate (i);
+
+ m_variable_size_registers = nullptr;
+ m_variable_size_register_type.clear ();
+ m_variable_size_register_sizeof.clear ();
+ m_variable_size_register_offset.clear ();
+}
+
+/* See regcache.h. */
+
bool
reg_buffer::has_variable_size_registers ()
{
if (src.data () != nullptr)
{
+ if (memcmp (src.data (), dst.data (), dst.size ())
+ && gdbarch_invalidate_tdesc_parameters (m_descr->gdbarch, regnum,
+ this))
+ /* Invalidate variable-size registers. */
+ this->invalidate_variable_size_registers ();
+
copy (src, dst);
m_register_status[regnum] = REG_VALID;
}
gdb::array_view<gdb_byte> dst = register_buffer (regnum);
bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch);
+ if (memcmp (addr, dst.data (), dst.size ())
+ && gdbarch_invalidate_tdesc_parameters (m_descr->gdbarch, regnum, this))
+ /* Invalidate variable-size registers. */
+ this->invalidate_variable_size_registers ();
+
copy_integer_to_size (dst.data (), dst.size (), addr, addr_len, is_signed,
byte_order);
m_register_status[regnum] = REG_VALID;
reg_buffer. */
void initialize_variable_size_registers ();
+ /* Reset information about variable-size registers in this reg_buffer. */
+ void invalidate_variable_size_registers ();
+
/* Return a view on register REGNUM's buffer cache. */
template <typename ElemType>
gdb::array_view<ElemType> register_buffer (int regnum) const;