2002-08-25 Andrew Cagney <ac131313@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Sun, 25 Aug 2002 15:36:11 +0000 (15:36 +0000)
committerAndrew Cagney <cagney@redhat.com>
Sun, 25 Aug 2002 15:36:11 +0000 (15:36 +0000)
* regcache.c (struct regcache_descr): Add field register_type.
(init_legacy_regcache_descr): Pass a pre-allocated regcache_descr
in as a parameter
(init_regcache_descr): Initialize register_type.  Pass the descr
to init_legacy_regcache_descr.  Use register_type instead of
REGISTER_VIRTUAL_TYPE.
(register_type): New function.
(regcache_dump): Replace REGISTER_VIRTUAL_TYPE with register_type.
* regcache.h (register_type): Declare.

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

index 49a0a75..30edafe 100644 (file)
@@ -1,5 +1,17 @@
 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
+       (init_regcache_descr): Initialize register_type.  Pass the descr
+       to init_legacy_regcache_descr.  Use register_type instead of
+       REGISTER_VIRTUAL_TYPE.
+       (register_type): New function.
+       (regcache_dump): Replace REGISTER_VIRTUAL_TYPE with register_type.
+       * regcache.h (register_type): Declare.
+
+2002-08-25  Andrew Cagney  <ac131313@redhat.com>
+
        * rs6000-tdep.c (rs6000_gdbarch_init): Set store_struct_return
        instead of deprecated_store_return_value.  Fix fallout from
        2002-08-23 Andrew Cagney <cagney@redhat.com>.
index 384df40..8fd8015 100644 (file)
@@ -77,24 +77,22 @@ struct regcache_descr
 
   /* Useful constant.  Largest of all the registers.  */
   long max_register_size;
+
+  /* Cached table containing the type of each register.  */
+  struct type **register_type;
 };
 
-static void *
-init_legacy_regcache_descr (struct gdbarch *gdbarch)
+void
+init_legacy_regcache_descr (struct gdbarch *gdbarch,
+                           struct regcache_descr *descr)
 {
   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;
 
@@ -135,7 +133,6 @@ init_legacy_regcache_descr (struct gdbarch *gdbarch)
       if (descr->sizeof_raw_registers < regend)
        descr->sizeof_raw_registers = regend;
     }
-  return descr;
 }
 
 static void *
@@ -145,21 +142,33 @@ init_regcache_descr (struct gdbarch *gdbarch)
   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);
+  /* Create an initial, zero filled, table.  */
+  descr = XCALLOC (1, 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;
 
+  /* Fill in a table of register types.  */
+  descr->register_type = XCALLOC (descr->nr_cooked_registers,
+                                 struct type *);
+  for (i = 0; i < descr->nr_cooked_registers; i++)
+    {
+      descr->register_type[i] = REGISTER_VIRTUAL_TYPE (i);
+    }
+
+  /* If an old style architecture, fill in the remainder of the
+     register cache descriptor using the register macros.  */
+  if (!gdbarch_pseudo_register_read_p (gdbarch)
+      && !gdbarch_pseudo_register_write_p (gdbarch))
+    {
+      descr->legacy_p = 1;
+      init_legacy_regcache_descr (gdbarch, descr);
+      return descr;
+    }
+
   /* Construct a strictly RAW register cache.  Don't allow pseudo's
      into the register cache.  */
   descr->nr_raw_registers = NUM_REGS;
@@ -175,10 +184,10 @@ init_regcache_descr (struct gdbarch *gdbarch)
      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.  */
+     NOTE: cagney/2002-05-22: Only register_type() is used when
+     constructing the register cache.  It is assumed that the
+     register's raw size, virtual size and type length are all the
+     same.  */
 
   {
     long offset = 0;
@@ -187,7 +196,7 @@ init_regcache_descr (struct gdbarch *gdbarch)
     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->sizeof_register[i] = TYPE_LENGTH (descr->register_type[i]);
        descr->register_offset[i] = offset;
        offset += descr->sizeof_register[i];
        if (descr->max_register_size < descr->sizeof_register[i])
@@ -244,6 +253,17 @@ xfree_regcache_descr (struct gdbarch *gdbarch, void *ptr)
 /* Utility functions returning useful register attributes stored in
    the regcache descr.  */
 
+struct type *
+register_type (struct gdbarch *gdbarch, int regnum)
+{
+  struct regcache_descr *descr = regcache_descr (gdbarch);
+  gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
+  return descr->register_type[regnum];
+}
+
+/* Utility functions returning useful register attributes stored in
+   the regcache descr.  */
+
 int
 max_register_size (struct gdbarch *gdbarch)
 {
@@ -1443,7 +1463,8 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
              || (regcache->descr->sizeof_register[regnum]
                  != REGISTER_VIRTUAL_SIZE (regnum))
              || (regcache->descr->sizeof_register[regnum]
-                 != TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (regnum)))
+                 != TYPE_LENGTH (register_type (regcache->descr->gdbarch,
+                                                regnum)))
              )
            {
              if (!footnote_register_size)
@@ -1460,7 +1481,8 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
       else
        {
          static const char blt[] = "builtin_type";
-         const char *t = TYPE_NAME (REGISTER_VIRTUAL_TYPE (regnum));
+         const char *t = TYPE_NAME (register_type (regcache->descr->gdbarch,
+                                                   regnum));
          if (t == NULL)
            {
              char *n;
index 6af729a..3c2dbeb 100644 (file)
@@ -88,6 +88,25 @@ extern void supply_register (int regnum, const void *val);
 extern void regcache_collect (int regnum, 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.
+
+   NOTE: cagney/2002-08-17: The original macro was called
+   REGISTER_VIRTUAL_TYPE.  This was because the register could have
+   different raw and cooked (nee virtual) representations.  The
+   CONVERTABLE methods being used to convert between the two
+   representations.  Current code does not do this.  Instead, the
+   first [0..NUM_REGS) registers are 1:1 raw:cooked, and the type
+   exactly describes the register's representation.  Consequently, the
+   ``virtual'' has been dropped.
+
+   FIXME: cagney/2002-08-17: A number of architectures, including the
+   MIPS, are currently broken in this regard.  */
+
+extern struct type *register_type (struct gdbarch *gdbarch, int regnum);
+
+
 /* Return the size of the largest register.  Used when allocating
    space for an aribtrary register value.  */