Add the cooked register interface.
[deliverable/binutils-gdb.git] / gdb / regcache.c
index 11ed8c4f70d71fcfd51e54626592c2273ba9d32d..70af8f093bdaa2a21db2c30e96c0bc0da1ad5e89 100644 (file)
@@ -1,6 +1,7 @@
 /* Cache and manage the values of registers for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001
-   Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000,
+   2001, 2002 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
  * Here is the actual register cache.
  */
 
+/* Per-architecture object describing the layout of a register cache.
+   Computed once when the architecture is created */
+
+struct gdbarch_data *regcache_descr_handle;
+
+struct regcache_descr
+{
+  /* The architecture this descriptor belongs to.  */
+  struct gdbarch *gdbarch;
+
+  /* Is this a ``legacy'' register cache?  Such caches reserve space
+     for raw and pseudo registers and allow access to both.  */
+  int legacy_p;
+
+  /* The raw register cache.  This should contain just [0
+     .. NUM_RAW_REGISTERS).  However, for older targets, it contains
+     space for the full [0 .. NUM_RAW_REGISTERS +
+     NUM_PSEUDO_REGISTERS).  */
+  int nr_raw_registers;
+  long sizeof_raw_registers;
+  long sizeof_raw_register_valid_p;
+
+  /* The cooked register space.  Each cooked register in the range
+     [0..NR_RAW_REGISTERS) is direct-mapped onto the corresponding raw
+     register.  The remaining [NR_RAW_REGISTERS
+     .. NR_COOKED_REGISTERS) (a.k.a. pseudo regiters) are mapped onto
+     both raw registers and memory by the architecture methods
+     gdbarch_register_read and gdbarch_register_write.  */
+  int nr_cooked_registers;
+
+  /* Offset and size (in 8 bit bytes), of reach register in the
+     register cache.  All registers (including those in the range
+     [NR_RAW_REGISTERS .. NR_COOKED_REGISTERS) are given an offset.
+     Assigning all registers an offset makes it possible to keep
+     legacy code, such as that found in read_register_bytes() and
+     write_register_bytes() working.  */
+  long *register_offset;
+  long *sizeof_register;
+
+  /* Useful constant.  Largest of all the registers.  */
+  long max_register_size;
+};
+
+static void *
+init_legacy_regcache_descr (struct gdbarch *gdbarch)
+{
+  int i;
+  struct regcache_descr *descr;
+  /* FIXME: cagney/2002-05-11: gdbarch_data() should take that
+     ``gdbarch'' as a parameter.  */
+  gdb_assert (gdbarch != NULL);
+
+  descr = XMALLOC (struct regcache_descr);
+  descr->gdbarch = gdbarch;
+  descr->legacy_p = 1;
+
+  /* FIXME: cagney/2002-05-11: Shouldn't be including pseudo-registers
+     in the register buffer.  Unfortunatly some architectures do.  */
+  descr->nr_cooked_registers = NUM_REGS + NUM_PSEUDO_REGS;
+  descr->nr_raw_registers = descr->nr_cooked_registers;
+  descr->sizeof_raw_register_valid_p = descr->nr_cooked_registers;
+
+  /* FIXME: cagney/2002-05-11: Instead of using REGISTER_BYTE() this
+     code should compute the offets et.al. at runtime.  This currently
+     isn't possible because some targets overlap register locations -
+     see the mess in read_register_bytes() and write_register_bytes()
+     registers.  */
+  descr->sizeof_register = XCALLOC (descr->nr_cooked_registers, long);
+  descr->register_offset = XCALLOC (descr->nr_cooked_registers, long);
+  descr->max_register_size = 0;
+  for (i = 0; i < descr->nr_cooked_registers; i++)
+    {
+      descr->register_offset[i] = REGISTER_BYTE (i);
+      descr->sizeof_register[i] = REGISTER_RAW_SIZE (i);
+      if (descr->max_register_size < REGISTER_RAW_SIZE (i))
+       descr->max_register_size = REGISTER_RAW_SIZE (i);
+    }
+
+  /* Come up with the real size of the registers buffer.  */
+  descr->sizeof_raw_registers = REGISTER_BYTES; /* OK use.  */
+  for (i = 0; i < descr->nr_cooked_registers; i++)
+    {
+      long regend;
+      /* Keep extending the buffer so that there is always enough
+         space for all registers.  The comparison is necessary since
+         legacy code is free to put registers in random places in the
+         buffer separated by holes.  Once REGISTER_BYTE() is killed
+         this can be greatly simplified.  */
+      /* FIXME: cagney/2001-12-04: This code shouldn't need to use
+         REGISTER_BYTE().  Unfortunatly, legacy code likes to lay the
+         buffer out so that certain registers just happen to overlap.
+         Ulgh!  New targets use gdbarch's register read/write and
+         entirely avoid this uglyness.  */
+      regend = descr->register_offset[i] + descr->sizeof_register[i];
+      if (descr->sizeof_raw_registers < regend)
+       descr->sizeof_raw_registers = regend;
+    }
+  return descr;
+}
+
+static void *
+init_regcache_descr (struct gdbarch *gdbarch)
+{
+  int i;
+  struct regcache_descr *descr;
+  gdb_assert (gdbarch != NULL);
+
+  /* If an old style architecture, construct the register cache
+     description using all the register macros.  */
+  if (!gdbarch_pseudo_register_read_p (gdbarch)
+      && !gdbarch_pseudo_register_write_p (gdbarch))
+    return init_legacy_regcache_descr (gdbarch);
+
+  descr = XMALLOC (struct regcache_descr);
+  descr->gdbarch = gdbarch;
+  descr->legacy_p = 0;
+
+  /* Total size of the register space.  The raw registers are mapped
+     directly onto the raw register cache while the pseudo's are
+     either mapped onto raw-registers or memory.  */
+  descr->nr_cooked_registers = NUM_REGS + NUM_PSEUDO_REGS;
+
+  /* Construct a strictly RAW register cache.  Don't allow pseudo's
+     into the register cache.  */
+  descr->nr_raw_registers = NUM_REGS;
+  descr->sizeof_raw_register_valid_p = NUM_REGS;
+
+  /* Lay out the register cache.  The pseud-registers are included in
+     the layout even though their value isn't stored in the register
+     cache.  Some code, via read_register_bytes() access a register
+     using an offset/length rather than a register number.
+
+     NOTE: cagney/2002-05-22: Only REGISTER_VIRTUAL_TYPE() needs to be
+     used when constructing the register cache.  It is assumed that
+     register raw size, virtual size and type length of the type are
+     all the same.  */
+
+  {
+    long offset = 0;
+    descr->sizeof_register = XCALLOC (descr->nr_cooked_registers, long);
+    descr->register_offset = XCALLOC (descr->nr_cooked_registers, long);
+    descr->max_register_size = 0;
+    for (i = 0; i < descr->nr_cooked_registers; i++)
+      {
+       descr->sizeof_register[i] = TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (i));
+       descr->register_offset[i] = offset;
+       offset += descr->sizeof_register[i];
+       if (descr->max_register_size < descr->sizeof_register[i])
+         descr->max_register_size = descr->sizeof_register[i];
+      }
+    /* Set the real size of the register cache buffer.  */
+    /* FIXME: cagney/2002-05-22: Should only need to allocate space
+       for the raw registers.  Unfortunatly some code still accesses
+       the register array directly using the global registers[].
+       Until that code has been purged, play safe and over allocating
+       the register buffer.  Ulgh!  */
+    descr->sizeof_raw_registers = offset;
+    /* = descr->register_offset[descr->nr_raw_registers]; */
+  }
+
+#if 0
+  /* Sanity check.  Confirm that the assumptions about gdbarch are
+     true.  The REGCACHE_DESCR_HANDLE is set before doing the checks
+     so that targets using the generic methods supplied by regcache
+     don't go into infinite recursion trying to, again, create the
+     regcache.  */
+  set_gdbarch_data (gdbarch, regcache_descr_handle, descr);
+  for (i = 0; i < descr->nr_cooked_registers; i++)
+    {
+      gdb_assert (descr->sizeof_register[i] == REGISTER_RAW_SIZE (i));
+      gdb_assert (descr->sizeof_register[i] == REGISTER_VIRTUAL_SIZE (i));
+      gdb_assert (descr->register_offset[i] == REGISTER_BYTE (i));
+    }
+  /* gdb_assert (descr->sizeof_raw_registers == REGISTER_BYTES (i));  */
+#endif
+
+  return descr;
+}
+
+static struct regcache_descr *
+regcache_descr (struct gdbarch *gdbarch)
+{
+  return gdbarch_data (gdbarch, regcache_descr_handle);
+}
+
+static void
+xfree_regcache_descr (struct gdbarch *gdbarch, void *ptr)
+{
+  struct regcache_descr *descr = ptr;
+  if (descr == NULL)
+    return;
+  xfree (descr->register_offset);
+  xfree (descr->sizeof_register);
+  descr->register_offset = NULL;
+  descr->sizeof_register = NULL;
+  xfree (descr);
+}
+
+/* The register cache for storing raw register values.  */
+
+struct regcache
+{
+  struct regcache_descr *descr;
+  char *raw_registers;
+  char *raw_register_valid_p;
+  /* If a value isn't in the cache should the corresponding target be
+     queried for a value.  */
+  int passthrough_p;
+};
+
+struct regcache *
+regcache_xmalloc (struct gdbarch *gdbarch)
+{
+  struct regcache_descr *descr;
+  struct regcache *regcache;
+  gdb_assert (gdbarch != NULL);
+  descr = regcache_descr (gdbarch);
+  regcache = XMALLOC (struct regcache);
+  regcache->descr = descr;
+  regcache->raw_registers
+    = XCALLOC (descr->sizeof_raw_registers, char);
+  regcache->raw_register_valid_p
+    = XCALLOC (descr->sizeof_raw_register_valid_p, char);
+  regcache->passthrough_p = 0;
+  return regcache;
+}
+
+void
+regcache_xfree (struct regcache *regcache)
+{
+  if (regcache == NULL)
+    return;
+  xfree (regcache->raw_registers);
+  xfree (regcache->raw_register_valid_p);
+  xfree (regcache);
+}
+
+void
+do_regcache_xfree (void *data)
+{
+  regcache_xfree (data);
+}
+
+struct cleanup *
+make_cleanup_regcache_xfree (struct regcache *regcache)
+{
+  return make_cleanup (do_regcache_xfree, regcache);
+}
+
+void
+regcache_cpy (struct regcache *dst, struct regcache *src)
+{
+  int i;
+  char *buf;
+  gdb_assert (src != NULL && dst != NULL);
+  gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
+  gdb_assert (src != dst);
+  /* FIXME: cagney/2002-05-17: To say this bit is bad is being polite.
+     It keeps the existing code working where things rely on going
+     through to the register cache.  */
+  if (src == current_regcache && src->descr->legacy_p)
+    {
+      /* ULGH!!!!  Old way.  Use REGISTER bytes and let code below
+        untangle fetch.  */
+      read_register_bytes (0, dst->raw_registers, REGISTER_BYTES);
+      return;
+    }
+  /* FIXME: cagney/2002-05-17: To say this bit is bad is being polite.
+     It keeps the existing code working where things rely on going
+     through to the register cache.  */
+  if (dst == current_regcache && dst->descr->legacy_p)
+    {
+      /* ULGH!!!!  Old way.  Use REGISTER bytes and let code below
+        untangle fetch.  */
+      write_register_bytes (0, src->raw_registers, REGISTER_BYTES);
+      return;
+    }
+  buf = alloca (src->descr->max_register_size);
+  for (i = 0; i < src->descr->nr_raw_registers; i++)
+    {
+      /* Should we worry about the valid bit here?  */
+      regcache_raw_read (src, i, buf);
+      regcache_raw_write (dst, i, buf);
+    }
+}
+
+void
+regcache_cpy_no_passthrough (struct regcache *dst, struct regcache *src)
+{
+  int i;
+  gdb_assert (src != NULL && dst != NULL);
+  gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
+  /* NOTE: cagney/2002-05-17: Don't let the caller do a no-passthrough
+     move of data into the current_regcache().  Doing this would be
+     silly - it would mean that valid_p would be completly invalid.  */
+  gdb_assert (dst != current_regcache);
+  memcpy (dst->raw_registers, src->raw_registers,
+         dst->descr->sizeof_raw_registers);
+  memcpy (dst->raw_register_valid_p, src->raw_register_valid_p,
+         dst->descr->sizeof_raw_register_valid_p);
+}
+
+struct regcache *
+regcache_dup (struct regcache *src)
+{
+  struct regcache *newbuf;
+  gdb_assert (current_regcache != NULL);
+  newbuf = regcache_xmalloc (src->descr->gdbarch);
+  regcache_cpy (newbuf, src);
+  return newbuf;
+}
+
+struct regcache *
+regcache_dup_no_passthrough (struct regcache *src)
+{
+  struct regcache *newbuf;
+  gdb_assert (current_regcache != NULL);
+  newbuf = regcache_xmalloc (src->descr->gdbarch);
+  regcache_cpy_no_passthrough (newbuf, src);
+  return newbuf;
+}
+
+int
+regcache_valid_p (struct regcache *regcache, int regnum)
+{
+  gdb_assert (regcache != NULL);
+  gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
+  return regcache->raw_register_valid_p[regnum];
+}
+
+CORE_ADDR
+regcache_raw_read_as_address (struct regcache *regcache, int regnum)
+{
+  char *buf;
+  gdb_assert (regcache != NULL);
+  gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
+  buf = alloca (regcache->descr->sizeof_register[regnum]);
+  regcache_raw_read (regcache, regnum, buf);
+  return extract_address (buf, regcache->descr->sizeof_register[regnum]);
+}
+
+char *
+deprecated_grub_regcache_for_registers (struct regcache *regcache)
+{
+  return regcache->raw_registers;
+}
+
+char *
+deprecated_grub_regcache_for_register_valid (struct regcache *regcache)
+{
+  return regcache->raw_register_valid_p;
+}
+
+/* Global structure containing the current regcache.  */
+/* FIXME: cagney/2002-05-11: The two global arrays registers[] and
+   register_valid[] currently point into this structure.  */
+struct regcache *current_regcache;
+
 /* NOTE: this is a write-through cache.  There is no "dirty" bit for
    recording if the register values have been changed (eg. by the
    user).  Therefore all registers must be written back to the
@@ -97,10 +456,9 @@ register_changed (int regnum)
    else return a pointer to the start of the cache buffer.  */
 
 static char *
-register_buffer (int regnum)
+register_buffer (struct regcache *regcache, int regnum)
 {
-  gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS));
-  return &registers[REGISTER_BYTE (regnum)];
+  return regcache->raw_registers + regcache->descr->register_offset[regnum];
 }
 
 /* Return whether register REGNUM is a real register.  */
@@ -311,35 +669,76 @@ legacy_read_register_gen (int regnum, char *myaddr)
   if (!register_cached (regnum))
     fetch_register (regnum);
 
-  memcpy (myaddr, register_buffer (regnum),
+  memcpy (myaddr, register_buffer (current_regcache, regnum),
          REGISTER_RAW_SIZE (regnum));
 }
 
 void
-regcache_read (int rawnum, char *buf)
+regcache_raw_read (struct regcache *regcache, int regnum, void *buf)
 {
-  gdb_assert (rawnum >= 0 && rawnum < (NUM_REGS + NUM_PSEUDO_REGS));
-  /* For moment, just use underlying legacy code. Ulgh!!! */
-  legacy_read_register_gen (rawnum, buf);
+  gdb_assert (regcache != NULL && buf != NULL);
+  gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
+  if (regcache->descr->legacy_p
+      && regcache->passthrough_p)
+    {
+      gdb_assert (regcache == current_regcache);
+      /* For moment, just use underlying legacy code.  Ulgh!!! This
+        silently and very indirectly updates the regcache's regcache
+        via the global register_valid[].  */
+      legacy_read_register_gen (regnum, buf);
+      return;
+    }
+  /* Make certain that the register cache is up-to-date with respect
+     to the current thread.  This switching shouldn't be necessary
+     only there is still only one target side register cache.  Sigh!
+     On the bright side, at least there is a regcache object.  */
+  if (regcache->passthrough_p)
+    {
+      gdb_assert (regcache == current_regcache);
+      if (! ptid_equal (registers_ptid, inferior_ptid))
+       {
+         registers_changed ();
+         registers_ptid = inferior_ptid;
+       }
+      if (!register_cached (regnum))
+       fetch_register (regnum);
+    }
+  /* Copy the value directly into the register cache.  */
+  memcpy (buf, (regcache->raw_registers
+               + regcache->descr->register_offset[regnum]),
+         regcache->descr->sizeof_register[regnum]);
 }
 
 void
 read_register_gen (int regnum, char *buf)
 {
-  if (! gdbarch_register_read_p (current_gdbarch))
+  gdb_assert (current_regcache != NULL);
+  gdb_assert (current_regcache->descr->gdbarch == current_gdbarch);
+  if (current_regcache->descr->legacy_p)
     {
       legacy_read_register_gen (regnum, buf);
       return;
     }
-  gdbarch_register_read (current_gdbarch, regnum, buf);
+  regcache_cooked_read (current_regcache, regnum, buf);
 }
 
+void
+regcache_cooked_read (struct regcache *regcache, int rawnum, void *buf)
+{
+  gdb_assert (regnum >= 0);
+  gdb_assert (regnum < regcache->descr->nr_cooked_registers);
+  if (regnum < regcache->descr->nr_raw_registers)
+    regcache_raw_read (regcache, regnum, buf);
+  else
+    gdbarch_pseudo_register_read (regcache->descr->gdbarch, regcache,
+                                 regnum, buf);
+}
 
 /* Write register REGNUM at MYADDR to the target.  MYADDR points at
    REGISTER_RAW_BYTES(REGNUM), which must be in target byte-order.  */
 
 static void
-legacy_write_register_gen (int regnum, char *myaddr)
+legacy_write_register_gen (int regnum, const void *myaddr)
 {
   int size;
   gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS));
@@ -362,35 +761,98 @@ legacy_write_register_gen (int regnum, char *myaddr)
       /* If we have a valid copy of the register, and new value == old
         value, then don't bother doing the actual store. */
       if (register_cached (regnum)
-         && memcmp (register_buffer (regnum), myaddr, size) == 0)
+         && (memcmp (register_buffer (current_regcache, regnum), myaddr, size)
+             == 0))
        return;
       else
        target_prepare_to_store ();
     }
 
-  memcpy (register_buffer (regnum), myaddr, size);
+  memcpy (register_buffer (current_regcache, regnum), myaddr, size);
 
   set_register_cached (regnum, 1);
   store_register (regnum);
 }
 
 void
-regcache_write (int rawnum, char *buf)
+regcache_raw_write (struct regcache *regcache, int regnum, const void *buf)
 {
-  gdb_assert (rawnum >= 0 && rawnum < (NUM_REGS + NUM_PSEUDO_REGS));
-  /* For moment, just use underlying legacy code. Ulgh!!! */
-  legacy_write_register_gen (rawnum, buf);
+  gdb_assert (regcache != NULL && buf != NULL);
+  gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
+
+  if (regcache->passthrough_p
+      && regcache->descr->legacy_p)
+    {
+      /* For moment, just use underlying legacy code.  Ulgh!!! This
+        silently and very indirectly updates the regcache's buffers
+        via the globals register_valid[] and registers[].  */
+      gdb_assert (regcache == current_regcache);
+      legacy_write_register_gen (regnum, buf);
+      return;
+    }
+
+  /* On the sparc, writing %g0 is a no-op, so we don't even want to
+     change the registers array if something writes to this register.  */
+  if (CANNOT_STORE_REGISTER (regnum))
+    return;
+
+  /* Handle the simple case first -> not write through so just store
+     value in cache.  */
+  if (!regcache->passthrough_p)
+    {
+      memcpy ((regcache->raw_registers
+              + regcache->descr->register_offset[regnum]), buf,
+             regcache->descr->sizeof_register[regnum]);
+      regcache->raw_register_valid_p[regnum] = 1;
+      return;
+    }
+
+  /* Make certain that the correct cache is selected.  */
+  gdb_assert (regcache == current_regcache);
+  if (! ptid_equal (registers_ptid, inferior_ptid))
+    {
+      registers_changed ();
+      registers_ptid = inferior_ptid;
+    }
+
+  /* If we have a valid copy of the register, and new value == old
+     value, then don't bother doing the actual store. */
+  if (regcache_valid_p (regcache, regnum)
+      && (memcmp (register_buffer (regcache, regnum), buf,
+                 regcache->descr->sizeof_register[regnum]) == 0))
+    return;
+
+  target_prepare_to_store ();
+  memcpy (register_buffer (regcache, regnum), buf,
+         regcache->descr->sizeof_register[regnum]);
+  regcache->raw_register_valid_p[regnum] = 1;
+  store_register (regnum);
 }
 
 void
 write_register_gen (int regnum, char *buf)
 {
-  if (! gdbarch_register_write_p (current_gdbarch))
+  gdb_assert (current_regcache != NULL);
+  gdb_assert (current_regcache->descr->gdbarch == current_gdbarch);
+  if (current_regcache->descr->legacy_p)
     {
       legacy_write_register_gen (regnum, buf);
       return;
     }
-  gdbarch_register_write (current_gdbarch, regnum, buf);
+  regcache_cooked_write (current_regcache, regnum, buf);
+}
+
+void
+regcache_cooked_write (struct regcache *regcache, int rawnum,
+                      const void *buf)
+{
+  gdb_assert (regnum >= 0);
+  gdb_assert (regnum < regcache->descr->nr_cooked_registers);
+  if (regnum < regcache->descr->nr_raw_registers)
+    regcache_raw_write (regcache, regnum, buf);
+  else
+    gdbarch_pseudo_register_write (regcache->descr->gdbarch, regcache,
+                                  regnum, buf);
 }
 
 /* Copy INLEN bytes of consecutive data from memory at MYADDR
@@ -552,7 +1014,7 @@ write_register_pid (int regnum, CORE_ADDR val, ptid_t ptid)
    fact, and report it to the users of read_register and friends.  */
 
 void
-supply_register (int regnum, char *val)
+supply_register (int regnum, const void *val)
 {
 #if 1
   if (! ptid_equal (registers_ptid, inferior_ptid))
@@ -564,10 +1026,10 @@ supply_register (int regnum, char *val)
 
   set_register_cached (regnum, 1);
   if (val)
-    memcpy (register_buffer (regnum), val, 
+    memcpy (register_buffer (current_regcache, regnum), val, 
            REGISTER_RAW_SIZE (regnum));
   else
-    memset (register_buffer (regnum), '\000', 
+    memset (register_buffer (current_regcache, regnum), '\000', 
            REGISTER_RAW_SIZE (regnum));
 
   /* On some architectures, e.g. HPPA, there are a few stray bits in
@@ -576,18 +1038,20 @@ supply_register (int regnum, char *val)
   /* NOTE: cagney/2001-03-16: The macro CLEAN_UP_REGISTER_VALUE is
      going to be deprecated.  Instead architectures will leave the raw
      register value as is and instead clean things up as they pass
-     through the method gdbarch_register_read() clean up the
+     through the method gdbarch_pseudo_register_read() clean up the
      values. */
 
 #ifdef DEPRECATED_CLEAN_UP_REGISTER_VALUE
-  DEPRECATED_CLEAN_UP_REGISTER_VALUE (regnum, register_buffer (regnum));
+  DEPRECATED_CLEAN_UP_REGISTER_VALUE \
+    (regnum, register_buffer (current_regcache, regnum));
 #endif
 }
 
 void
 regcache_collect (int regnum, void *buf)
 {
-  memcpy (buf, register_buffer (regnum), REGISTER_RAW_SIZE (regnum));
+  memcpy (buf, register_buffer (current_regcache, regnum),
+         REGISTER_RAW_SIZE (regnum));
 }
 
 
@@ -755,37 +1219,18 @@ reg_flush_command (char *command, int from_tty)
 static void
 build_regcache (void)
 {
-  int i;
-  int sizeof_register_valid;
-  /* Come up with the real size of the registers buffer.  */
-  int sizeof_registers = REGISTER_BYTES; /* OK use.  */
-  for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
-    {
-      long regend;
-      /* Keep extending the buffer so that there is always enough
-         space for all registers.  The comparison is necessary since
-         legacy code is free to put registers in random places in the
-         buffer separated by holes.  Once REGISTER_BYTE() is killed
-         this can be greatly simplified.  */
-      /* FIXME: cagney/2001-12-04: This code shouldn't need to use
-         REGISTER_BYTE().  Unfortunatly, legacy code likes to lay the
-         buffer out so that certain registers just happen to overlap.
-         Ulgh!  New targets use gdbarch's register read/write and
-         entirely avoid this uglyness.  */
-      regend = REGISTER_BYTE (i) + REGISTER_RAW_SIZE (i);
-      if (sizeof_registers < regend)
-       sizeof_registers = regend;
-    }
-  registers = xmalloc (sizeof_registers);
-  sizeof_register_valid = ((NUM_REGS + NUM_PSEUDO_REGS)
-                          * sizeof (*register_valid));
-  register_valid = xmalloc (sizeof_register_valid);
-  memset (register_valid, 0, sizeof_register_valid);
+  current_regcache = regcache_xmalloc (current_gdbarch);
+  current_regcache->passthrough_p = 1;
+  registers = deprecated_grub_regcache_for_registers (current_regcache);
+  register_valid = deprecated_grub_regcache_for_register_valid (current_regcache);
 }
 
 void
 _initialize_regcache (void)
 {
+  regcache_descr_handle = register_gdbarch_data (init_regcache_descr,
+                                                xfree_regcache_descr);
+  REGISTER_GDBARCH_SWAP (current_regcache);
   register_gdbarch_swap (&registers, sizeof (registers), NULL);
   register_gdbarch_swap (&register_valid, sizeof (register_valid), NULL);
   register_gdbarch_swap (NULL, 0, build_regcache);
This page took 0.029384 seconds and 4 git commands to generate.