2002-08-25 Andrew Cagney <ac131313@redhat.com>

* regcache.h (register_offset_hack): Declare.
	(regcache_cooked_read_using_offset_hack): Declare.
	(regcache_cooked_write_using_offset_hack): Declare.

	* regcache.c (register_offset_hack): New function.
	(regcache_cooked_read_using_offset_hack): New function.
	(regcache_cooked_write_using_offset_hack): New function.
	(regcache_dump): Check that the registers, according to their
	offset, are packed hard against each other.
	(cooked_xfer_using_offset_hack): New function.
This commit is contained in:
Andrew Cagney 2002-08-25 18:47:16 +00:00
parent 90949d06a3
commit d3b22ed57c
3 changed files with 135 additions and 1 deletions

View file

@ -1,3 +1,16 @@
2002-08-25 Andrew Cagney <ac131313@redhat.com>
* regcache.h (register_offset_hack): Declare.
(regcache_cooked_read_using_offset_hack): Declare.
(regcache_cooked_write_using_offset_hack): Declare.
* regcache.c (register_offset_hack): New function.
(regcache_cooked_read_using_offset_hack): New function.
(regcache_cooked_write_using_offset_hack): New function.
(regcache_dump): Check that the registers, according to their
offset, are packed hard against each other.
(cooked_xfer_using_offset_hack): New function.
2002-08-25 Andrew Cagney <ac131313@redhat.com>
* regcache.c (struct regcache_descr): Add field register_type.

View file

@ -1029,6 +1029,95 @@ regcache_cooked_write_part (struct regcache *regcache, int regnum,
regcache_cooked_read, regcache_cooked_write);
}
/* Hack to keep code that view the register buffer as raw bytes
working. */
int
register_offset_hack (struct gdbarch *gdbarch, int regnum)
{
struct regcache_descr *descr = regcache_descr (gdbarch);
gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
return descr->register_offset[regnum];
}
static void
cooked_xfer_using_offset_hack (struct regcache *regcache,
int buf_start, int buf_len, void *in_b,
const void *out_b)
{
struct regcache_descr *descr = regcache->descr;
struct gdbarch *gdbarch = descr->gdbarch;
bfd_byte *in_buf = in_b;
const bfd_byte *out_buf = out_b;
int buf_end = buf_start + buf_len;
int regnum;
char *reg_buf = alloca (descr->max_register_size);
/* NOTE: cagney/2002-08-17: This code assumes that the register
offsets are strictly increasing and do not overlap. If this
isn't the case then the bug is in the target architecture and NOT
this code. */
/* NOTE: cagney/2002-08-17: This code assumes that only the
registers covered by BUF_START:BUF_LEN should be transfered. If,
for some reason, there is a gap between two registers, then that
gap isn't transfered. (The gap shouldn't be there but that is
another story.) */
/* Iterate through all registers looking for those that lie within
BUF_START:BUF_LEN. */
for (regnum = 0; regnum < descr->nr_cooked_registers; regnum++)
{
/* The register's location. */
int reg_start = descr->register_offset[regnum];
int reg_len = descr->sizeof_register[regnum];
int reg_end = reg_start + reg_len;
/* The START, END and LEN that falls within the current
register. */
int xfer_start;
int xfer_end;
int xfer_len;
/* start = max (reg_start, buf_start) */
if (reg_start > buf_start)
xfer_start = reg_start;
else
xfer_start = buf_start;
/* end = min (reg_end, buf_end) */
if (reg_end < buf_end)
xfer_end = reg_end;
else
xfer_end = buf_end;
/* The number of bytes to transfer. If there isn't anything to
transfer (the end is before the start) this will be -ve. */
xfer_len = xfer_end - xfer_start;
if (xfer_len > 0)
regcache_xfer_part (regcache, regnum, xfer_start - reg_start,
xfer_len, in_b, out_b, regcache_cooked_read,
regcache_cooked_write);
}
}
void
regcache_cooked_read_using_offset_hack (struct regcache *regcache,
int buf_start, int buf_len, void *b)
{
cooked_xfer_using_offset_hack (regcache, buf_start, buf_len, b, NULL);
}
void
regcache_cooked_write_using_offset_hack (struct regcache *regcache,
int buf_start, int buf_len,
const void *b)
{
cooked_xfer_using_offset_hack (regcache, buf_start, buf_len, NULL, b);
}
/* Return the contents of register REGNUM as an unsigned integer. */
ULONGEST
@ -1439,7 +1528,12 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
fprintf_unfiltered (file, " %6ld",
regcache->descr->register_offset[regnum]);
if (register_offset != regcache->descr->register_offset[regnum]
|| register_offset != REGISTER_BYTE (regnum))
|| register_offset != REGISTER_BYTE (regnum)
|| (regnum > 0
&& (regcache->descr->register_offset[regnum]
!= (regcache->descr->register_offset[regnum - 1]
+ regcache->descr->sizeof_register[regnum - 1])))
)
{
if (!footnote_register_offset)
footnote_register_offset = ++footnote_nr;

View file

@ -88,6 +88,33 @@ extern void supply_register (int regnum, const void *val);
extern void regcache_collect (int regnum, void *buf);
/* The register's ``offset''.
NOTE: cagney/2002-08-17: The ``struct value'' and expression
evaluator treat the register cache as a large liner buffer.
Instead of reading/writing a register using its register number,
the code read/writes registers by specifying their offset into the
buffer and a number of bytes. The code also assumes that these
byte read/writes can cross register boundaries, adjacent registers
treated as a contiguous set of bytes.
The below map that model onto the real register cache. New code
should go out of their way to avoid using these interfaces.
FIXME: cagney/2002-08-17: The ``struct value'' and expression
evaluator should be fixed. Instead of using the { offset, length }
pair to describe a value within one or more registers, the code
should use a chain of { regnum, offset, len } tripples. */
extern int register_offset_hack (struct gdbarch *gdbarch, int regnum);
extern void regcache_cooked_read_using_offset_hack (struct regcache *regcache,
int offset, int len,
void *buf);
extern void regcache_cooked_write_using_offset_hack (struct regcache *regcache,
int offset, int len,
const void *buf);
/* The type of a register. This function is slightly more efficient
then its gdbarch vector counterpart since it returns a precomputed
value stored in a table.