summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2002-08-26 19:57:39 +0000
committerAndrew Cagney <cagney@redhat.com>2002-08-26 19:57:39 +0000
commit7061c019a24b3bf6a947698e12e79ffd858c5e7e (patch)
treef728801726b4a1288d94dd917b6e57828087c8f4
parente6e99dbbfca273e55167783dd37ed771ac7268cb (diff)
downloadgdb-7061c019a24b3bf6a947698e12e79ffd858c5e7e.tar.gz
2002-08-26 Andrew Cagney <ac131313@redhat.com>
* i386-tdep.c: Include "reggroups.h". (i386_register_reggroup_p): New function. (i386_add_reggroups, i386_init_reggroups): New function. (i386_gdbarch_init): Call i386_add_reggroups. Set register_reggroup_p. (_initialize_i386_tdep): Call i386_init_reggroups. * infcmd.c: Include <ctype.h>. (registers_info): Rewrite. Handle reggroups. (default_print_registers_info): Use gdbarch_register_reggroup_p. (print_float_info): Use gdbarch_register_reggroup_p. * regcache.c: Include "reggroups.h". (regcache_dump): Include the register groups in the ``maint print registers'' command. * infcmd.c: Include "regroup.h". (default_print_registers_info): Use gdbarch_register_reggroup_p. (print_float_info): Ditto. * gdbarch.sh: Include "reggroups.h". (register_reggroup_p): New method. (struct reggroup): Add opaque declaration. * gdbarch.h, gdbarch.c: Regenerate. * Makefile.in (SFILES): Add reggroups.c. (reggroups_h): Define. (COMMON_OBS): Add reggroups.o. (reggroups.o): Specify dependencies. (gdbarch.o, infcmd.o, i386-tdep.o): Update dependencies. * reggroups.c: New file. * reggroups.h: New file.
-rw-r--r--gdb/ChangeLog36
-rw-r--r--gdb/Makefile.in17
-rw-r--r--gdb/gdbarch.c30
-rw-r--r--gdb/gdbarch.h7
-rwxr-xr-xgdb/gdbarch.sh4
-rw-r--r--gdb/i386-tdep.c51
-rw-r--r--gdb/infcmd.c108
-rw-r--r--gdb/regcache.c25
-rw-r--r--gdb/reggroups.c187
-rw-r--r--gdb/reggroups.h53
10 files changed, 487 insertions, 31 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c2d481ed880..03ff1fd823a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,39 @@
+2002-08-26 Andrew Cagney <ac131313@redhat.com>
+
+ * i386-tdep.c: Include "reggroups.h".
+ (i386_register_reggroup_p): New function.
+ (i386_add_reggroups, i386_init_reggroups): New function.
+ (i386_gdbarch_init): Call i386_add_reggroups. Set
+ register_reggroup_p.
+ (_initialize_i386_tdep): Call i386_init_reggroups.
+
+ * infcmd.c: Include <ctype.h>.
+ (registers_info): Rewrite. Handle reggroups.
+ (default_print_registers_info): Use gdbarch_register_reggroup_p.
+ (print_float_info): Use gdbarch_register_reggroup_p.
+
+ * regcache.c: Include "reggroups.h".
+ (regcache_dump): Include the register groups in the ``maint print
+ registers'' command.
+
+ * infcmd.c: Include "regroup.h".
+ (default_print_registers_info): Use gdbarch_register_reggroup_p.
+ (print_float_info): Ditto.
+
+ * gdbarch.sh: Include "reggroups.h".
+ (register_reggroup_p): New method.
+ (struct reggroup): Add opaque declaration.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+ * Makefile.in (SFILES): Add reggroups.c.
+ (reggroups_h): Define.
+ (COMMON_OBS): Add reggroups.o.
+ (reggroups.o): Specify dependencies.
+ (gdbarch.o, infcmd.o, i386-tdep.o): Update dependencies.
+
+ * reggroups.c: New file.
+ * reggroups.h: New file.
+
2002-08-25 Andrew Cagney <ac131313@redhat.com>
* arch-utils.h (default_next_cooked_register_to_save): Declare.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 756ffdf4074..f8d2c9843eb 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -533,6 +533,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
event-loop.c event-top.c \
expprint.c f-exp.y f-lang.c f-typeprint.c f-valprint.c \
findvar.c regcache.c gdbarch.c arch-utils.c gdbtypes.c osabi.c \
+ reggroups.c \
inf-loop.c infcmd.c inflow.c infrun.c language.c \
kod.c kod-cisco.c \
ui-out.c cli-out.c \
@@ -689,6 +690,7 @@ ppc_tdep_h = ppc-tdep.h $(osabi_h)
ppcnbsd_tdep_h = ppcnbsd-tdep.h
proc_utils_h = proc-utils.h
regcache_h = regcache.h
+reggroups_h = reggroups.h
remote_utils_h = remote-utils.h $(target_h)
remote_h = remote.h
scm_lang_h = scm-lang.h $(scm_tags_h)
@@ -842,7 +844,8 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
nlmread.o serial.o mdebugread.o top.o utils.o \
ui-file.o \
frame.o doublest.o \
- gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o
+ gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o \
+ reggroups.o
OBS = $(COMMON_OBS) $(ANNOTATE_OBS)
@@ -1674,7 +1677,11 @@ frv-tdep.o: frv-tdep.c $(defs_h) $(inferior_h) $(symfile_h) $(gdbcore_h) \
$(arch_utils_h) $(regcache_h)
regcache.o: regcache.c $(defs_h) $(inferior_h) $(target_h) $(gdbarch_h) \
- $(gdbcmd_h) $(regcache_h) $(gdb_assert_h) $(gdb_string_h) $(gdbcmd_h)
+ $(gdbcmd_h) $(regcache_h) $(gdb_assert_h) $(gdb_string_h) $(gdbcmd_h) \
+ $(reggroups_h)
+
+reggroups.o: reggroups.c $(defs_h) $(reggroups_h) $(gdbtypes_h) \
+ $(gdb_assert_h) $(regcache_h)
fork-child.o: fork-child.c $(gdb_wait_h) $(defs_h) $(gdbcore_h) \
$(inferior_h) $(target_h) $(terminal_h) $(gdbthread_h) $(gdb_string_h)
@@ -1696,7 +1703,7 @@ gdbarch.o: gdbarch.c $(defs_h) $(arch_utils_h) $(gdbcmd_h) $(inferior_h) \
$(gdb_string_h) $(symtab_h) $(frame_h) $(inferior_h) $(breakpoint_h) \
$(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(gdbthread_h) \
$(annotate_h) $(symfile_h) $(value_h) $(symcat_h) $(floatformat_h) \
- $(gdb_assert_h) $(gdb_string_h) $(gdb_events_h)
+ $(gdb_assert_h) $(gdb_string_h) $(gdb_events_h) $(reggroups_h)
arch-utils.o: arch-utils.c $(defs_h) $(bfd_h) $(gdbcmd_h) \
$(arch_utils_h) $(gdb_assert_h) $(inferior_h) \
@@ -1751,7 +1758,7 @@ i386gnu-nat.o: gnu-nat.h
i386-tdep.o: i386-tdep.c $(defs_h) $(gdb_string_h) $(frame_h) \
$(inferior_h) $(gdbcore_h) $(target_h) $(floatformat_h) \
$(symtab_h) $(gdbcmd_h) $(command_h) $(arch_utils_h) $(regcache_h) \
- $(doublest_h) $(value_h)
+ $(doublest_h) $(value_h) $(reggroups_h)
i386-nat.o: i386-nat.c $(defs_h) $(breakpoint_h) $(command_h) $(gdbcmd_h)
@@ -1807,7 +1814,7 @@ ia64-tdep.o: ia64-tdep.c $(defs_h) $(inferior_h) $(symfile_h) $(gdbcore_h) \
infcmd.o: infcmd.c $(defs_h) environ.h $(gdbcmd_h) $(gdbcore_h) \
$(inferior_h) $(target_h) $(language_h) $(symfile_h) $(gdb_string_h) \
- $(ui_out_h) $(completer_h) $(regcache_h)
+ $(ui_out_h) $(completer_h) $(regcache_h) $(reggroups_h)
inflow.o: inflow.c $(bfd_h) $(command_h) $(defs_h) $(inferior_h) \
$(target_h) $(terminal_h) $(gdbthread_h) $(gdb_string_h)
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 2835ee16fba..af58497cc19 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -64,6 +64,7 @@
#include "gdb_assert.h"
#include "gdb_string.h"
#include "gdb-events.h"
+#include "reggroup.h"
/* Static function declarations */
@@ -267,6 +268,7 @@ struct gdbarch
gdbarch_coff_make_msymbol_special_ftype *coff_make_msymbol_special;
gdbarch_next_cooked_register_to_save_ftype *next_cooked_register_to_save;
gdbarch_next_cooked_register_to_restore_ftype *next_cooked_register_to_restore;
+ gdbarch_register_reggroup_p_ftype *register_reggroup_p;
};
@@ -423,6 +425,7 @@ struct gdbarch startup_gdbarch =
0,
default_next_cooked_register_to_save,
default_next_cooked_register_to_restore,
+ default_register_reggroup_p,
/* startup_gdbarch() */
};
@@ -555,6 +558,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
current_gdbarch->coff_make_msymbol_special = default_coff_make_msymbol_special;
current_gdbarch->next_cooked_register_to_save = default_next_cooked_register_to_save;
current_gdbarch->next_cooked_register_to_restore = default_next_cooked_register_to_restore;
+ current_gdbarch->register_reggroup_p = default_register_reggroup_p;
/* gdbarch_alloc() */
return current_gdbarch;
@@ -803,6 +807,9 @@ verify_gdbarch (struct gdbarch *gdbarch)
if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
&& (gdbarch->next_cooked_register_to_restore == default_next_cooked_register_to_restore))
fprintf_unfiltered (log, "\n\tnext_cooked_register_to_restore");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->register_reggroup_p == default_register_reggroup_p))
+ fprintf_unfiltered (log, "\n\tregister_reggroup_p");
buf = ui_file_xstrdup (log, &dummy);
make_cleanup (xfree, buf);
if (strlen (buf) > 0)
@@ -841,6 +848,10 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
(long) current_gdbarch->next_cooked_register_to_save);
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
+ "gdbarch_dump: register_reggroup_p = 0x%08lx\n",
+ (long) current_gdbarch->register_reggroup_p);
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
"gdbarch_dump: pseudo_register_read = 0x%08lx\n",
(long) current_gdbarch->pseudo_register_read);
if (GDB_MULTI_ARCH)
@@ -4940,6 +4951,25 @@ set_gdbarch_next_cooked_register_to_restore (struct gdbarch *gdbarch,
gdbarch->next_cooked_register_to_restore = next_cooked_register_to_restore;
}
+int
+gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_reggroup_p == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_reggroup_p invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_reggroup_p called\n");
+ return gdbarch->register_reggroup_p (gdbarch, regnum, reggroup);
+}
+
+void
+set_gdbarch_register_reggroup_p (struct gdbarch *gdbarch,
+ gdbarch_register_reggroup_p_ftype register_reggroup_p)
+{
+ gdbarch->register_reggroup_p = register_reggroup_p;
+}
+
/* Keep a registry of per-architecture data-pointers required by GDB
modules. */
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 1534d7936f2..25365f99023 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -47,6 +47,7 @@ struct value;
struct objfile;
struct minimal_symbol;
struct regcache;
+struct reggroup;
extern struct gdbarch *current_gdbarch;
@@ -2493,6 +2494,12 @@ typedef int (gdbarch_next_cooked_register_to_restore_ftype) (struct gdbarch *gdb
extern int gdbarch_next_cooked_register_to_restore (struct gdbarch *gdbarch, int last_regnum);
extern void set_gdbarch_next_cooked_register_to_restore (struct gdbarch *gdbarch, gdbarch_next_cooked_register_to_restore_ftype *next_cooked_register_to_restore);
+/* Is a register in a group */
+
+typedef int (gdbarch_register_reggroup_p_ftype) (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup);
+extern int gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup);
+extern void set_gdbarch_register_reggroup_p (struct gdbarch *gdbarch, gdbarch_register_reggroup_p_ftype *register_reggroup_p);
+
extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index ac0aa761616..8648407b058 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -661,6 +661,8 @@ f:2:COFF_MAKE_MSYMBOL_SPECIAL:void:coff_make_msymbol_special:int val, struct min
# Iterators for the cooked registers to save or restore.
m:::int:next_cooked_register_to_save:int last_regnum:last_regnum:::default_next_cooked_register_to_save
m:::int:next_cooked_register_to_restore:int last_regnum:last_regnum:::default_next_cooked_register_to_restore
+# Is a register in a group
+m:::int:register_reggroup_p:int regnum, struct reggroup *reggroup:regnum, reggroup:::default_register_reggroup_p
EOF
}
@@ -772,6 +774,7 @@ struct value;
struct objfile;
struct minimal_symbol;
struct regcache;
+struct reggroup;
extern struct gdbarch *current_gdbarch;
@@ -1247,6 +1250,7 @@ cat <<EOF
#include "gdb_assert.h"
#include "gdb_string.h"
#include "gdb-events.h"
+#include "reggroups.h"
/* Static function declarations */
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 8684fce684d..d7778cbb0d1 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -37,6 +37,7 @@
#include "doublest.h"
#include "value.h"
#include "gdb_assert.h"
+#include "reggroups.h"
#include "i386-tdep.h"
#include "i387-tdep.h"
@@ -1413,6 +1414,49 @@ i386_nw_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
}
+/* i386 register groups. In addition to the normal groups, add "mmx"
+ and "sse". */
+
+struct reggroup *i368_sse_reggroup;
+struct reggroup *i368_mmx_reggroup;
+
+static void
+i386_init_reggroups (void)
+{
+ i368_sse_reggroup = reggroup_new ("sse");
+ i368_mmx_reggroup = reggroup_new ("mmx");
+}
+
+static void
+i386_add_reggroups (struct gdbarch *gdbarch)
+{
+ reggroup_add (gdbarch, i368_sse_reggroup);
+ reggroup_add (gdbarch, i368_mmx_reggroup);
+ reggroup_add (gdbarch, general_reggroup);
+ reggroup_add (gdbarch, float_reggroup);
+ reggroup_add (gdbarch, all_reggroup);
+ reggroup_add (gdbarch, vector_reggroup);
+ reggroup_add (gdbarch, system_reggroup);
+}
+
+static int
+i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+ struct reggroup *group)
+{
+ if (group == all_reggroup)
+ return 1;
+ if (mmx_regnum_p (regnum) || regnum == MXCSR_REGNUM)
+ return (group == i368_mmx_reggroup || group == vector_reggroup);
+ if (FP_REGNUM_P (regnum) || FPC_REGNUM_P (regnum))
+ return (group == float_reggroup || group == all_reggroup);
+ if (SSE_REGNUM_P (regnum))
+ return (group == i368_sse_reggroup || group == vector_reggroup);
+ if (group == general_reggroup)
+ return 1;
+ return 0;
+}
+
+
static struct gdbarch *
i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
@@ -1570,6 +1614,10 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
+ /* Add the i386 register groups. */
+ i386_add_reggroups (gdbarch);
+ set_gdbarch_register_reggroup_p (gdbarch, i386_register_reggroup_p);
+
/* Hook in ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch, osabi);
@@ -1643,4 +1691,7 @@ are \"default\", \"pcc\" and \"reg\", and the default value is \"default\".",
i386_go32_init_abi);
gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_NETWARE,
i386_nw_init_abi);
+
+ /* Define the i386 specific register groups. */
+ i386_init_reggroups ();
}
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 433332555e8..84e295ba349 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -41,6 +41,8 @@
#include "event-top.h"
#include "parser-defs.h"
#include "regcache.h"
+#include "reggroups.h"
+#include <ctype.h>
/* Functions exported for general use: */
@@ -1586,9 +1588,9 @@ default_print_registers_info (struct gdbarch *gdbarch,
{
if (!print_all)
{
- if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+ if (gdbarch_register_reggroup_p (gdbarch, i, float_reggroup))
continue;
- if (TYPE_VECTOR (REGISTER_VIRTUAL_TYPE (i)))
+ if (gdbarch_register_reggroup_p (gdbarch, i, vector_reggroup))
continue;
}
}
@@ -1692,35 +1694,89 @@ registers_info (char *addr_exp, int fpregs)
return;
}
- do
+ while (*addr_exp != '\0')
{
+ const char *start;
+ const char *end;
+ /* Keep skipping leading white space until something interesting
+ is found. */
+ if (isspace ((*addr_exp)))
+ {
+ addr_exp++;
+ continue;
+ }
+
+ /* Discard any ``$''. There had better be something after it. */
if (addr_exp[0] == '$')
addr_exp++;
- end = addr_exp;
- while (*end != '\0' && *end != ' ' && *end != '\t')
- ++end;
- numregs = NUM_REGS + NUM_PSEUDO_REGS;
-
- regnum = target_map_name_to_register (addr_exp, end - addr_exp);
- if (regnum >= 0)
- goto found;
-
- regnum = numregs;
-
- if (*addr_exp >= '0' && *addr_exp <= '9')
- regnum = atoi (addr_exp); /* Take a number */
- if (regnum >= numregs) /* Bad name, or bad number */
- error ("%.*s: invalid register", (int) (end - addr_exp), addr_exp);
+ if (isspace ((*addr_exp)) || (*addr_exp) == '\0')
+ error ("Missing register name");
- found:
- gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
- selected_frame, regnum, fpregs);
+ /* Find the start/end of this register name/group. */
+ start = addr_exp;
+ while ((*addr_exp) != '\0' && !isspace ((*addr_exp)))
+ addr_exp++;
+ end = addr_exp;
+
+ /* Figure out what we've found, display it. */
+
+ /* A register name? */
+ {
+ int regnum = target_map_name_to_register (addr_exp, end - start);
+ if (regnum >= 0)
+ {
+ gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
+ selected_frame, regnum, fpregs);
+ continue;
+ }
+ }
+
+ /* A register number? (how portable is this one?). */
+ {
+ char *endptr;
+ int regnum = strtol (start, &endptr, 0);
+ if (endptr == end
+ && regnum >= 0
+ && regnum < NUM_REGS + NUM_PSEUDO_REGS)
+ {
+ gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
+ selected_frame, regnum, fpregs);
+ continue;
+ }
+ }
+
+ /* A register group? */
+ {
+ struct reggroup *const *group;
+ for (group = reggroups (current_gdbarch);
+ (*group) != NULL;
+ group++)
+ {
+ if (strncmp (start, reggroup_name ((*group)), end - start) == 0)
+ break;
+ }
+ if ((*group) != NULL)
+ {
+ /* Don't bother with a length check. If the user enters
+ just part of a register group's name, go with the first
+ matching one. */
+ int regnum;
+ for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+ {
+ if (gdbarch_register_reggroup_p (current_gdbarch, regnum,
+ (*group)))
+ gdbarch_print_registers_info (current_gdbarch,
+ gdb_stdout, selected_frame,
+ regnum, fpregs);
+ }
+ continue;
+ }
+ }
- addr_exp = end;
- while (*addr_exp == ' ' || *addr_exp == '\t')
- ++addr_exp;
+ /* Nothing matched. */
+ error ("Invalid register `%.*s'", (int) (end - start), start);
}
- while (*addr_exp != '\0');
+
}
void
@@ -1933,7 +1989,7 @@ print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
{
- if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+ if (gdbarch_register_reggroup_p (gdbarch, regnum, float_reggroup))
{
printed_something = 1;
gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1);
diff --git a/gdb/regcache.c b/gdb/regcache.c
index f60dbbe01ac..3c1e5f176a3 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -29,6 +29,7 @@
#include "gdb_assert.h"
#include "gdb_string.h"
#include "gdbcmd.h" /* For maintenanceprintlist. */
+#include "reggroups.h"
/*
* DATA STRUCTURE
@@ -1641,6 +1642,30 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
}
}
+ /* The registers groups. */
+ if (what_to_dump == regcache_dump_none)
+ {
+ if (regnum < 0)
+ fprintf_unfiltered (file, "Groups");
+ else
+ {
+ struct reggroup *const *group;
+ const char *prefix = "";
+ for (group = reggroups (regcache->descr->gdbarch);
+ *group != NULL;
+ group++)
+ {
+ if (gdbarch_register_reggroup_p (regcache->descr->gdbarch,
+ regnum, *group))
+ {
+ fprintf_unfiltered (file, "%s%s", prefix,
+ reggroup_name (*group));
+ prefix = ",";
+ }
+ }
+ }
+ }
+
fprintf_unfiltered (file, "\n");
}
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
new file mode 100644
index 00000000000..09b0c930c82
--- /dev/null
+++ b/gdb/reggroups.c
@@ -0,0 +1,187 @@
+/* Register groupings for GDB, the GNU debugger.
+
+ Copyright 2002 Free Software Foundation, Inc.
+
+ Contributed by Red Hat.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "reggroups.h"
+#include "gdbtypes.h"
+#include "gdb_assert.h"
+#include "regcache.h"
+
+/* Individual register groups. */
+
+struct reggroup
+{
+ const char *name;
+};
+
+struct reggroup *
+reggroup_new (const char *name)
+{
+ struct reggroup *group = XMALLOC (struct reggroup);
+ group->name = name;
+ return group;
+}
+
+/* Register group attributes. */
+
+const char *
+reggroup_name (struct reggroup *group)
+{
+ return group->name;
+}
+
+/* All the groups for a given architecture. */
+
+struct reggroups
+{
+ int nr_group;
+ struct reggroup **group;
+};
+
+static struct gdbarch_data *reggroups_data;
+
+static void *
+reggroups_init (struct gdbarch *gdbarch)
+{
+ struct reggroups *groups = XMALLOC (struct reggroups);
+ groups->nr_group = 0;
+ groups->group = NULL;
+ return groups;
+}
+
+static void
+reggroups_free (struct gdbarch *gdbarch, void *data)
+{
+ struct reggroups *groups = data;
+ xfree (groups->group);
+ xfree (groups);
+}
+
+/* Add a register group (with attribute values) to the pre-defined
+ list. This function can be called during architecture
+ initialization and hence needs to handle NULL architecture groups. */
+
+static void
+add_group (struct reggroups *groups, struct reggroup *group)
+{
+ gdb_assert (group != NULL);
+ groups->nr_group++;
+ groups->group = xrealloc (groups->group, (sizeof (struct reggroup *)
+ * (groups->nr_group + 1)));
+ groups->group[groups->nr_group - 1] = group;
+ groups->group[groups->nr_group] = NULL;
+}
+
+void
+reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
+{
+ struct reggroups *groups = gdbarch_data (gdbarch, reggroups_data);
+ if (groups == NULL)
+ {
+ /* ULGH, called during architecture initialization. Patch
+ things up. */
+ groups = reggroups_init (gdbarch);
+ set_gdbarch_data (gdbarch, reggroups_data, groups);
+ }
+ add_group (groups, group);
+}
+
+/* The register groups for the current architecture. Mumble something
+ about the lifetime of the buffer.... */
+
+static struct reggroups *default_groups;
+
+struct reggroup * const*
+reggroups (struct gdbarch *gdbarch)
+{
+ struct reggroups *groups = gdbarch_data (gdbarch, reggroups_data);
+ /* Don't allow this function to be called during architecture
+ creation. */
+ gdb_assert (groups != NULL);
+ if (groups->group == NULL)
+ return default_groups->group;
+ else
+ return groups->group;
+}
+
+/* Is REGNUM a member of REGGROUP? */
+int
+default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+ struct reggroup *group)
+{
+ int vector_p;
+ int float_p;
+ if (REGISTER_NAME (regnum) == NULL
+ || *REGISTER_NAME (regnum) == '\0')
+ return 0;
+ if (group == all_reggroup)
+ return 1;
+ vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
+ float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
+ if (group == float_reggroup)
+ return float_p;
+ if (group == vector_reggroup)
+ return vector_p;
+ if (group == general_reggroup)
+ return (!vector_p && !float_p);
+ return 0;
+}
+
+
+
+
+/* Pre-defined register groups. */
+struct reggroup general_group = { "general" };
+struct reggroup float_group = { "float" };
+struct reggroup system_group = { "system" };
+struct reggroup vector_group = { "vector" };
+struct reggroup all_group = { "all" };
+
+struct reggroup *const general_reggroup = &general_group;
+struct reggroup *const float_reggroup = &float_group;
+struct reggroup *const system_reggroup = &system_group;
+struct reggroup *const vector_reggroup = &vector_group;
+struct reggroup *const all_reggroup = &all_group;
+
+void
+_initialize_reggroup (void)
+{
+ reggroups_data = register_gdbarch_data (reggroups_init, reggroups_free);
+
+#if 0
+ /* The pre-defined groups. */
+ general_reggroup = reggroup_new ("general");
+ float_reggroup = reggroup_new ("float");
+ system_reggroup = reggroup_new ("system");
+ vector_reggroup = reggroup_new ("vector");
+ all_reggroup = reggroup_new ("all");
+#endif
+
+ /* The pre-defined list of groups. */
+ default_groups = reggroups_init (NULL);
+ add_group (default_groups, general_reggroup);
+ add_group (default_groups, float_reggroup);
+ add_group (default_groups, system_reggroup);
+ add_group (default_groups, vector_reggroup);
+ add_group (default_groups, all_reggroup);
+}
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
new file mode 100644
index 00000000000..cae851ca51f
--- /dev/null
+++ b/gdb/reggroups.h
@@ -0,0 +1,53 @@
+/* Register groupings for GDB, the GNU debugger.
+
+ Copyright 2002 Free Software Foundation, Inc.
+
+ Contributed by Red Hat.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef REGGROUPS_H
+#define REGGROUPS_H
+
+struct gdbarch;
+struct reggroup;
+
+/* Pre-defined register groups. */
+extern struct reggroup *const general_reggroup;
+extern struct reggroup *const float_reggroup;
+extern struct reggroup *const system_reggroup;
+extern struct reggroup *const vector_reggroup;
+extern struct reggroup *const all_reggroup;
+
+/* Create a new local register group. */
+extern struct reggroup *reggroup_new (const char *name);
+
+/* Add a register group (with attribute values) to the pre-defined list. */
+extern void reggroup_add (struct gdbarch *gdbarch, struct reggroup *group);
+
+/* Register group attributes. */
+extern const char *reggroup_name (struct reggroup *reggroup);
+
+/* The register groups for the current architecture. */
+extern struct reggroup *const *reggroups (struct gdbarch *gdbarch);
+
+/* Is REGNUM a member of REGGROUP? */
+extern int default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+ struct reggroup *reggroup);
+
+#endif