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] MIPS: Consolidate printing of floating point registers


mips-tdep.c contains two different chunks of code for printing floating
point registers.  This causes the floating point registers to be printed
differently by "info float" and "info all-registers".

Also, for some MIPS parts, floating point registers may contain values
which are not really floating point numbers, so a hex display of these
registers is useful.  (Thanks to Chris Demetriou for telling me about
this.)

The patch below consolidates the printing of floating point registers
into one routine.  In addition to displaying a floating point register
as float and double, the raw hex value of the register is also displayed.

Here are some before and after "pictures"...

Before:
(gdb) info float
f0:  (float) -1.58818715e-23, (double) -1.1000000000000005
f1:  (float) 2.72008302e+23, (double) 3.2999999999999998
f2:  (float) 2.7200832e+23, (double) 3.3000000000000003
f3:  (float) -nan(0x7fffff), (double) -nan(0xfffffffffffff)
...
(gdb) info all-registers 
                  zero               at               v0               v1
 R0   0000000000000000 00000000001082f4 0000000000000006 0000000000000000 
                    a0               a1               a2               a3
...
                 cause               pc
      0000000000000000 0000000010000750 
 f0   : flt: -1.58818715e-23   dbl: -1.1000000000000005     
 f1   : flt: 2.72008302e+23    dbl: 3.2999999999999998      
 f2   : flt: 2.7200832e+23     dbl: 3.3000000000000003      
 f3   : flt: -5.78960377e+76   dbl: -inf                    
...


After:
(gdb) info float
f0:  0xbff199999999999c flt: -1.58818715e-23   dbl: -1.1000000000000005     
f1:  0x400a666666666666 flt: 2.72008302e+23    dbl: 3.2999999999999998      
f2:  0x400a666666666667 flt: 2.7200832e+23     dbl: 3.3000000000000003      
f3:  0xffffffffffffffff flt: -5.78960377e+76   dbl: -inf     
...
(gdb) info all-registers
                  zero               at               v0               v1
 R0   0000000000000000 00000000001082f4 0000000000000006 0000000000000000 
...
                 cause               pc
      0000000000800024 0000000010000750 
 f0:  0xbff199999999999c flt: -1.58818715e-23   dbl: -1.1000000000000005     
 f1:  0x400a666666666666 flt: 2.72008302e+23    dbl: 3.2999999999999998      
 f2:  0x400a666666666667 flt: 2.7200832e+23     dbl: 3.3000000000000003      
 f3:  0xffffffffffffffff flt: -5.78960377e+76   dbl: -inf          
...

Okay?

	* mips-tdep.c (mips_print_fp_register): New function, created from
	do_fp_register_row().  Registers are now also printed as hex.
	Only one register is printed per row.
	(mips_print_register, do_fp_register_row): Print floating point
	registers with mips_print_fp_register().

Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.184
diff -u -p -r1.184 mips-tdep.c
--- mips-tdep.c	2 Apr 2003 05:12:25 -0000	1.184
+++ mips-tdep.c	4 Apr 2003 23:28:27 -0000
@@ -4049,153 +4049,126 @@ mips_read_fp_register_double (int regno,
 }
 
 static void
-mips_print_register (int regnum, int all)
-{
-  char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
-
-  /* Get the data in raw format.  */
-  if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
-    {
-      printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum));
-      return;
-    }
-
-  /* If we have a actual 32-bit floating point register (or we are in
-     32-bit compatibility mode), and the register is even-numbered,
-     also print it as a double (spanning two registers).  */
-  if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
-      && (REGISTER_RAW_SIZE (regnum) == 4
-	  || mips2_fp_compat ())
-      && !((regnum - FP0_REGNUM) & 1))
-    {
-      char *dbuffer = alloca (2 * MAX_REGISTER_RAW_SIZE);
-
-      mips_read_fp_register_double (regnum, dbuffer);
-
-      printf_filtered ("(d%d: ", regnum - FP0_REGNUM);
-      val_print (mips_double_register_type (), dbuffer, 0, 0,
-		 gdb_stdout, 0, 1, 0, Val_pretty_default);
-      printf_filtered ("); ");
-    }
-  fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
-
-  /* The problem with printing numeric register names (r26, etc.) is that
-     the user can't use them on input.  Probably the best solution is to
-     fix it so that either the numeric or the funky (a2, etc.) names
-     are accepted on input.  */
-  if (regnum < MIPS_NUMREGS)
-    printf_filtered ("(r%d): ", regnum);
-  else
-    printf_filtered (": ");
-
-  /* If virtual format is floating, print it that way.  */
-  if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
-    if (REGISTER_RAW_SIZE (regnum) == 8 && !mips2_fp_compat ())
-      {
-	/* We have a meaningful 64-bit value in this register.  Show
-	   it as a 32-bit float and a 64-bit double.  */
-	int offset = 4 * (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG);
-
-	printf_filtered (" (float) ");
-	val_print (mips_float_register_type (), raw_buffer + offset, 0, 0,
-		   gdb_stdout, 0, 1, 0, Val_pretty_default);
-	printf_filtered (", (double) ");
-	val_print (mips_double_register_type (), raw_buffer, 0, 0,
-		   gdb_stdout, 0, 1, 0, Val_pretty_default);
-      }
-    else
-      val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0, 0,
-		 gdb_stdout, 0, 1, 0, Val_pretty_default);
-  /* Else print as integer in hex.  */
-  else
-    {
-      int offset;
-
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-        offset = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
-      else
-	offset = 0;
-
-      print_scalar_formatted (raw_buffer + offset,
-			      REGISTER_VIRTUAL_TYPE (regnum),
-			      'x', 0, gdb_stdout);
-    }
-}
-
-/* Replacement for generic do_registers_info.
-   Print regs in pretty columns.  */
-
-static int
-do_fp_register_row (int regnum)
+mips_print_fp_register (int regnum)
 {				/* do values for FP (float) regs */
   char *raw_buffer;
   double doub, flt1, flt2;	/* doubles extracted from raw hex data */
-  int inv1, inv2, inv3;
+  int inv1, inv2, namelen;
 
   raw_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
 
+  printf_filtered ("%s:", REGISTER_NAME (regnum));
+  printf_filtered ("%*s", 4 - (int) strlen (REGISTER_NAME (regnum)), "");
+
   if (REGISTER_RAW_SIZE (regnum) == 4 || mips2_fp_compat ())
     {
-      /* 4-byte registers: we can fit two registers per row.  */
-      /* Also print every pair of 4-byte regs as an 8-byte double.  */
+      /* 4-byte registers: Print hex and floating.  Also print even
+         numbered registers as doubles.  */
       mips_read_fp_register_single (regnum, raw_buffer);
       flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1);
 
-      mips_read_fp_register_single (regnum + 1, raw_buffer);
-      flt2 = unpack_double (mips_float_register_type (), raw_buffer, &inv2);
-
-      mips_read_fp_register_double (regnum, raw_buffer);
-      doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3);
+      print_scalar_formatted (raw_buffer, builtin_type_uint32, 'x', 'w',
+                              gdb_stdout);
 
-      printf_filtered (" %-5s", REGISTER_NAME (regnum));
+      printf_filtered (" flt: ");
       if (inv1)
-	printf_filtered (": <invalid float>");
+	printf_filtered (" <invalid float> ");
       else
 	printf_filtered ("%-17.9g", flt1);
 
-      printf_filtered (" %-5s", REGISTER_NAME (regnum + 1));
-      if (inv2)
-	printf_filtered (": <invalid float>");
-      else
-	printf_filtered ("%-17.9g", flt2);
-
-      printf_filtered (" dbl: ");
-      if (inv3)
-	printf_filtered ("<invalid double>");
-      else
-	printf_filtered ("%-24.17g", doub);
-      printf_filtered ("\n");
-
-      /* may want to do hex display here (future enhancement) */
-      regnum += 2;
+      if (regnum % 2 == 0)
+	{
+	  mips_read_fp_register_double (regnum, raw_buffer);
+	  doub = unpack_double (mips_double_register_type (), raw_buffer,
+	                        &inv2);
+
+	  printf_filtered (" dbl: ");
+	  if (inv2)
+	    printf_filtered ("<invalid double>");
+	  else
+	    printf_filtered ("%-24.17g", doub);
+	}
     }
   else
     {
-      /* Eight byte registers: print each one as float AND as double.  */
+      /* Eight byte registers: print each one as hex, float and double.  */
       mips_read_fp_register_single (regnum, raw_buffer);
       flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1);
 
       mips_read_fp_register_double (regnum, raw_buffer);
-      doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3);
+      doub = unpack_double (mips_double_register_type (), raw_buffer, &inv2);
 
-      printf_filtered (" %-5s: ", REGISTER_NAME (regnum));
+
+      print_scalar_formatted (raw_buffer, builtin_type_uint64, 'x', 'g',
+                              gdb_stdout);
+
+      printf_filtered (" flt: ");
       if (inv1)
 	printf_filtered ("<invalid float>");
       else
-	printf_filtered ("flt: %-17.9g", flt1);
+	printf_filtered ("%-17.9g", flt1);
 
       printf_filtered (" dbl: ");
-      if (inv3)
+      if (inv2)
 	printf_filtered ("<invalid double>");
       else
 	printf_filtered ("%-24.17g", doub);
-
-      printf_filtered ("\n");
-      /* may want to do hex display here (future enhancement) */
-      regnum++;
     }
   return regnum;
 }
+
+static void
+mips_print_register (int regnum, int all)
+{
+  char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+  int offset;
+
+  if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+    {
+      mips_print_fp_register (regnum);
+      return;
+    }
+
+  /* Get the data in raw format.  */
+  if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
+    {
+      printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum));
+      return;
+    }
+
+  fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
+
+  /* The problem with printing numeric register names (r26, etc.) is that
+     the user can't use them on input.  Probably the best solution is to
+     fix it so that either the numeric or the funky (a2, etc.) names
+     are accepted on input.  */
+  if (regnum < MIPS_NUMREGS)
+    printf_filtered ("(r%d): ", regnum);
+  else
+    printf_filtered (": ");
+
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    offset = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
+  else
+    offset = 0;
+
+  print_scalar_formatted (raw_buffer + offset,
+			  REGISTER_VIRTUAL_TYPE (regnum),
+			  'x', 0, gdb_stdout);
+}
+
+/* Replacement for generic do_registers_info.
+   Print regs in pretty columns.  */
+
+static int
+do_fp_register_row (int regnum)
+{
+  printf_filtered (" ");
+  mips_print_fp_register (regnum);
+  printf_filtered ("\n");
+  return regnum + 1;
+}
+
 
 /* Print a row's worth of GP (int) registers, with name labels above */
 


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