This is the mail archive of the gdb-patches@sourceware.cygnus.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]

[RFA] Large and small long doubles in "info float"


"info float" cannot display very large or very small long double
values:

$ cat ldn.c
#include <stdio.h>

int main (void)
{
  long double ldbl = 1e+4893L;

  if (ldbl > 2 * ldbl)
    printf ("Inf\n");
  return 0;
}
$ gdb ldn
(gdb) b main
Breakpoint 1 at 0x157b: file ldn.c, line 5.
(gdb) r
Starting program: g:/gdbsnap/gdb-0222/gdb/ldn 

Breakpoint 1, main () at ldn.c:5
5	  long double ldbl = 1e+4893L;
(gdb) n
7	  if (ldbl > 2 * ldbl)
(gdb) si
0x1593	7	  if (ldbl > 2 * ldbl)
(gdb) info float
=>R7: Valid   0x7f7d9270b3e84450455e +Inf
  R6: Empty   0xffff8000000000000000
  R5: Empty   0x00000000000000000000
  R4: Empty   0x3ffbcccccccccccccccd
  R3: Empty   0x00000000000000000000
  R2: Empty   0x00000000000000000000
  R1: Empty   0x00000000000000000000
  R0: Empty   0x00000000000000000000

That "+Inf" happens because print_i387_value calls floatformat_to_doublest,
which in turn calls ldexp.  However, ldexp only supports doubles, not long
doubles, so the number winds up being an Inf.

I need approval for the following patch which fixes this.  I would
like to check it in both for the branch and the trunk, which is why I
took care to make it as cautious as I possibly could...

Okay to commit?


2000-04-11  Eli Zaretskii  <eliz@is.elta.co.il>

	* i387-tdep.c (print_i387_value): If the target long double type
	is supported and is wider than REGISTER_RAW_SIZE, widen the
	argument to the full size of the long double.  Call
	extract_floating instead of floatformat_to_doublest, to avoid
	losing precision or printing Inf for numbers that cannot be
	adequately represented by a double.

--- gdb/i387-tdep.c~0	Sat Apr  1 19:06:54 2000
+++ gdb/i387-tdep.c	Tue Apr 11 22:56:46 2000
@@ -161,14 +161,22 @@ print_387_status_word (status)
 /* Implement the `info float' layout based on the register definitions
    in `tm-i386.h'.  */
 
+#if defined(TARGET_LONG_DOUBLE_BIT) && (TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT) > REGISTER_RAW_SIZE
+# define TARGET_RAW_SIZE (TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT)
+#else
+# define TARGET_RAW_SIZE REGISTER_RAW_SIZE
+#endif
+
 /* Print the floating point number specified by RAW.  */
 static void
-print_i387_value (char *raw)
+print_i387_value (unsigned char *raw)
 {
   DOUBLEST value;
-  
-  floatformat_to_doublest (&floatformat_i387_ext, raw, &value);
+  unsigned char target_raw[TARGET_RAW_SIZE];
 
+  memcpy (target_raw, raw, TARGET_RAW_SIZE);
+  value = extract_floating (target_raw, TARGET_RAW_SIZE);
+  
   /* We try to print 19 digits.  The last digit may or may not contain
      garbage, but we'd better print one too many.  We need enough room
      to print the value, 1 position for the sign, 1 for the decimal

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