2002-08-17 Andrew Cagney * 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. */