summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2002-08-25 15:36:11 +0000
committerAndrew Cagney <cagney@redhat.com>2002-08-25 15:36:11 +0000
commit0f9aeff6a6e4e5f2dd88e50f2cf5ed1712ebba40 (patch)
treeb6c892a9497026f0954a357bed759d068252ece0
parent99ac314fc1fc975ddad4208a9355abde8131adde (diff)
downloadgdb-0f9aeff6a6e4e5f2dd88e50f2cf5ed1712ebba40.tar.gz
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.
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/regcache.c70
-rw-r--r--gdb/regcache.h19
3 files changed, 77 insertions, 24 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 49a0a7510c1..30edafee53f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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>.
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 384df40ed05..8fd801581ab 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -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;
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 6af729a40ff..3c2dbebecb1 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -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. */