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] 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);

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