OSDN Git Service

2002-08-25 Andrew Cagney <ac131313@redhat.com>
authorcagney <cagney>
Sun, 25 Aug 2002 18:47:16 +0000 (18:47 +0000)
committercagney <cagney>
Sun, 25 Aug 2002 18:47:16 +0000 (18:47 +0000)
* 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.

gdb/ChangeLog
gdb/regcache.c
gdb/regcache.h

index 30edafe..3d9bb66 100644 (file)
@@ -1,5 +1,18 @@
 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.
        (init_legacy_regcache_descr): Pass a pre-allocated regcache_descr
        in as a parameter
index 8fd8015..6c86ba9 100644 (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;
index 3c2dbeb..1db42e3 100644 (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.