This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch/rfc] register_type() for REGISTER_VIRTUAL_TYPE()


Hello,

Following on from max_register_size() this provides a replacement for REGISTER_VIRTUAL_TYPE that uses a pre-computed table. As the comment explains, REGISTER_VIRTUAL_TYPE(r) should equal REGISTER_RAW_TYPE(r) so instead the method is called register_type().

Post 5.3 branch patches can flush out and convert everything. The architecture method will be renamed changed to gdbarch_register_type().

I'll look at committing this in a few days,

enjoy,
Andrew


2002-08-17  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.

Index: regcache.c
===================================================================
RCS file: /cvs/src/src/gdb/regcache.c,v
retrieving revision 1.53
diff -u -r1.53 regcache.c
--- regcache.c	13 Aug 2002 23:06:40 -0000	1.53
+++ regcache.c	18 Aug 2002 02:41:54 -0000
@@ -77,24 +77,22 @@
 
   /* 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;
 
@@ -133,7 +131,6 @@
       if (descr->sizeof_raw_registers < regend)
 	descr->sizeof_raw_registers = regend;
     }
-  return descr;
 }
 
 static void *
@@ -143,21 +140,33 @@
   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;
@@ -173,10 +182,10 @@
      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;
@@ -185,7 +194,7 @@
     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])
@@ -239,6 +248,17 @@
   xfree (descr);
 }
 
+/* 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];
+}
+
 /* The register cache for storing raw register values.  */
 
 struct regcache
@@ -1351,7 +1371,8 @@
 	      || (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)
@@ -1368,7 +1389,8 @@
       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: regcache.h
===================================================================
RCS file: /cvs/src/src/gdb/regcache.h,v
retrieving revision 1.14
diff -u -r1.14 regcache.h
--- regcache.h	13 Aug 2002 14:32:28 -0000	1.14
+++ regcache.h	18 Aug 2002 02:41:54 -0000
@@ -71,6 +71,25 @@
 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 registers
+   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);
+
+
 /* DEPRECATED: Character array containing an image of the inferior
    programs' registers for the most recently referenced thread. */
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]