This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[patch/rfc] Use reggroups to decide which registers to print
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Sat, 02 Nov 2002 22:38:27 -0500
- Subject: [patch/rfc] Use reggroups to decide which registers to print
Hello,
The attached patch revaps the default `info register', `info float' and
`info vector' code so that it uses regroups to determine which registers
should be printed.
This makes it possible for architectures with vector or floating point
registers to have non vector/float registers included in the
vector/float displays.
I'll commit in a few days.
Andrew
2002-11-02 Andrew Cagney <ac131313@redhat.com>
* infcmd.c: Include "reggroups.h" and <ctype.h>.
(print_float_info): Print registers in float_reggroup.
(print_vector_info): Print registers in vector_reggroup.
(default_print_registers_info): When all, print registers in
all_reggroup. Otherwize, print registers in general_reggroup.
(registers_info): Rewrite. Add support for register groups.
Eliminate a goto.
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.59
diff -u -r1.59 infcmd.c
--- infcmd.c 26 Oct 2002 17:19:27 -0000 1.59
+++ infcmd.c 3 Nov 2002 03:34:06 -0000
@@ -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, in inferior.h: */
@@ -1583,11 +1585,14 @@
specific reg. */
if (regnum == -1)
{
- if (!print_all)
+ if (print_all)
{
- if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+ if (!gdbarch_register_reggroup_p (gdbarch, i, all_reggroup))
continue;
- if (TYPE_VECTOR (REGISTER_VIRTUAL_TYPE (i)))
+ }
+ else
+ {
+ if (!gdbarch_register_reggroup_p (gdbarch, i, general_reggroup))
continue;
}
}
@@ -1691,35 +1696,89 @@
return;
}
- do
+ while (*addr_exp != '\0')
{
+ char *start;
+ const char *end;
+
+ /* Keep skipping leading white space. */
+ if (isspace ((*addr_exp)))
+ {
+ addr_exp++;
+ continue;
+ }
+
+ /* Discard any leading ``$''. Check that there is something
+ resembling a register following it. */
if (addr_exp[0] == '$')
addr_exp++;
+ if (isspace ((*addr_exp)) || (*addr_exp) == '\0')
+ error ("Missing register name");
+
+ /* Find the start/end of this register name/num/group. */
+ start = addr_exp;
+ while ((*addr_exp) != '\0' && !isspace ((*addr_exp)))
+ addr_exp++;
end = addr_exp;
- while (*end != '\0' && *end != ' ' && *end != '\t')
- ++end;
- numregs = NUM_REGS + NUM_PSEUDO_REGS;
-
- regnum = frame_map_name_to_regnum (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);
+
+ /* Figure out what we've found and display it. */
- found:
- gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
- selected_frame, regnum, fpregs);
+ /* A register name? */
+ {
+ int regnum = frame_map_name_to_regnum (start, 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++)
+ {
+ /* Don't bother with a length check. Should the user
+ enter a short register group name, go with the first
+ group that matches. */
+ if (strncmp (start, reggroup_name ((*group)), end - start) == 0)
+ break;
+ }
+ if ((*group) != NULL)
+ {
+ 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
@@ -1752,7 +1811,7 @@
for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
{
- if (TYPE_VECTOR (REGISTER_VIRTUAL_TYPE (regnum)))
+ if (gdbarch_register_reggroup_p (gdbarch, regnum, vector_reggroup))
{
printed_something = 1;
gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1);
@@ -1925,7 +1984,7 @@
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);