long *register_offset;
long *sizeof_register;
+ /* Offset (in 8 bit bytes), of each register's tag in the register
+ cache. All registers (including those in the range
+ [NR_RAW_REGISTERS .. NR_COOKED_REGISTERS) are given an
+ offset. */
+ long *register_tag_offset;
+
/* Cached table containing the type of each register. */
struct type **register_type;
};
= GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
descr->register_offset
= GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
+ descr->register_tag_offset
+ = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
{
descr->sizeof_register[i] = TYPE_LENGTH (descr->register_type[i]);
descr->register_offset[i] = offset;
offset += descr->sizeof_register[i];
+ if (descr->register_type[i]->is_tagged ())
+ {
+ descr->register_tag_offset[i] = offset;
+ offset++;
+ }
}
/* Set the real size of the raw register cache buffer. */
descr->sizeof_raw_registers = offset;
descr->sizeof_register[i] = TYPE_LENGTH (descr->register_type[i]);
descr->register_offset[i] = offset;
offset += descr->sizeof_register[i];
+ if (descr->register_type[i]->is_tagged ())
+ {
+ descr->register_tag_offset[i] = offset;
+ offset++;
+ }
}
/* Set the real size of the readonly register cache buffer. */
descr->sizeof_cooked_registers = offset;
return size;
}
+bool
+register_has_tag (struct gdbarch *gdbarch, int regnum)
+{
+ return register_type (gdbarch, regnum)->is_tagged ();
+}
+
/* See gdbsupport/common-regcache.h. */
int
return m_registers.get () + m_descr->register_offset[regnum];
}
+/* Return a pointer to register REGNUM's tag buffer. */
+
+gdb_byte *
+reg_buffer::register_tag (int regnum) const
+{
+ return m_registers.get () + m_descr->register_tag_offset[regnum];
+}
+
void
reg_buffer::save (register_read_ftype cooked_read)
{
gdb_assert (regnum < gdbarch_num_regs (arch ()));
}
+void
+reg_buffer::assert_tagged (int regnum) const
+{
+ assert_regnum (regnum);
+ gdb_assert (m_descr->register_type[regnum]->is_tagged ());
+}
+
/* Type to map a ptid to a list of regcaches (one thread may have multiple
regcaches, associated to different gdbarches). */
mark_value_bytes_unavailable (result, 0,
TYPE_LENGTH (value_type (result)));
- if (gdbarch_register_has_tag (m_descr->gdbarch, this, regnum))
+ if (register_has_tag (m_descr->gdbarch, regnum))
{
set_value_tagged (result, 1);
- bool tag = gdbarch_register_tag (m_descr->gdbarch, this, regnum);
+ bool tag = raw_collect_tag (regnum);
set_value_tag (result, tag);
}
}
}
+/* See gdbsupport/common-regcache.h. */
+
+void
+reg_buffer::raw_supply_tag (int regnum, bool tag)
+{
+ gdb_byte *tagbuf;
+
+ assert_tagged (regnum);
+
+ tagbuf = register_tag (regnum);
+ *tagbuf = tag;
+}
+
/* See regcache.h. */
void
memcpy (buf, regbuf, size);
}
+/* See gdbsupport/common-regcache.h. */
+
+bool
+reg_buffer::raw_collect_tag (int regnum) const
+{
+ const gdb_byte *tagbuf;
+
+ assert_tagged (regnum);
+
+ tagbuf = register_tag (regnum);
+ return (*tagbuf != 0);
+}
+
/* See regcache.h. */
void
extern int register_size (struct gdbarch *gdbarch, int regnum);
+/* Return true if register REGNUM is tagged. */
+
+extern bool register_has_tag (struct gdbarch *gdbarch, int regnum);
+
typedef gdb::function_view<register_status (int regnum, gdb_byte *buf)>
register_read_ftype;
/* See gdbsupport/common-regcache.h. */
void raw_collect (int regnum, void *buf) const override;
+ /* See gdbsupport/common-regcache.h. */
+ bool raw_collect_tag (int regnum) const override;
+
/* Collect register REGNUM from REGCACHE. Store collected value as an integer
at address ADDR, in target endian, with length ADDR_LEN and sign IS_SIGNED.
If ADDR_LEN is greater than the register size, then the integer will be
raw_supply (regnum, src.register_buffer (regnum));
}
+ /* See gdbsupport/common-regcache.h. */
+ void raw_supply_tag (int regnum, bool tag) override;
+
/* Supply register REGNUM to REGCACHE. Value to supply is an integer stored
at address ADDR, in target endian, with length ADDR_LEN and sign IS_SIGNED.
If the register size is greater than ADDR_LEN, then the integer will be
/* Assert on the range of REGNUM. */
void assert_regnum (int regnum) const;
+ /* Assert that register REGNUM is tagged. */
+ void assert_tagged (int regnum) const;
+
int num_raw_registers () const;
gdb_byte *register_buffer (int regnum) const;
+ gdb_byte *register_tag (int regnum) const;
+
/* Save a register cache. The set of registers saved into the
regcache determined by the save_reggroup. COOKED_READ returns
zero iff the register's value can't be returned. */
/* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE. */
virtual void raw_supply (int regnum, const void *buf) = 0;
+ /* Supply tag for register REGNUM. Only valid for tagged registers. */
+ virtual void raw_supply_tag (int regnum, bool tag) = 0;
+
/* Collect register REGNUM from REGCACHE and store its contents in BUF. */
virtual void raw_collect (int regnum, void *buf) const = 0;
+ /* Return tag for register REGNUM. Only valid for tagged registers. */
+ virtual bool raw_collect_tag (int regnum) const = 0;
+
/* Compare the contents of the register stored in the regcache (ignoring the
first OFFSET bytes) to the contents of BUF (without any offset). Returns
true if the same. */