2007-02-23 Jan Kratochvil * configure.ac (PRINTF_HAS_HEX_DOUBLE): Test for printf ("%a"). * configure, config.in: Regenerate. * printcmd.c (printf_command): Support "%a"/"%A" formatting. (print_scalar_formatted): Print TYPE_CODE_FLT/x by print_floating (format='x'). * valprint.c (print_floating): Add FORMAT parameter. * value.h (print_floating): Update prototype. * ada-valprint.c (ada_print_floating): Callers changed. * c-valprint.c (c_val_print): Likewise. * f-valprint.c (f_val_print): Likewise. * m2-valprint.c (m2_val_print): Likewise. * p-valprint.c (pascal_val_print): Likewise. 2007-02-23 Jan Kratochvil * gdb.texinfo (Output formats): Described hexadecimal floats printing. 2007-02-18 Jan Kratochvil * gdb.arch/i386-sse.exp: Check $xmm.v4_float and $xmm.v2_double printing in hexadecimal format. * gdb.base/gdb1821.exp: Update the DOUBLE/x print check. Index: gdb/configure.ac =================================================================== RCS file: /cvs/src/src/gdb/configure.ac,v retrieving revision 1.42 diff -u -p -r1.42 configure.ac --- gdb/configure.ac 2 Feb 2007 22:54:09 -0000 1.42 +++ gdb/configure.ac 18 Feb 2007 04:35:38 -0000 @@ -955,6 +955,23 @@ aix*) ;; esac +# Check if the compiler and runtime support printing doubles in hex. + +AC_CACHE_CHECK([for hex double support in printf], + gdb_cv_printf_has_hex_double, + [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], +[[char buf[16]; + double f = 3.141592653; + sprintf (buf, "%a", f); + return (strncmp ("0x1.921fb", buf, 9));]])], + gdb_cv_printf_has_hex_double=yes, + gdb_cv_printf_has_hex_double=no, + gdb_cv_printf_has_hex_double=no)]) +if test $gdb_cv_printf_has_hex_double = yes; then + AC_DEFINE(PRINTF_HAS_HEX_DOUBLE, 1, + [Define to 1 if the "%a" format works to print doubles in hex.]) +fi + dnl For certain native configurations, we need to check whether thread dnl support can be built in or not. Index: gdb/ada-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/ada-valprint.c,v retrieving revision 1.30 diff -u -p -r1.30 ada-valprint.c --- gdb/ada-valprint.c 9 Jan 2007 17:58:49 -0000 1.30 +++ gdb/ada-valprint.c 18 Feb 2007 04:35:32 -0000 @@ -308,7 +308,7 @@ ada_print_floating (const gdb_byte *vala struct ui_file *tmp_stream = mem_fileopen (); struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_stream); - print_floating (valaddr, type, tmp_stream); + print_floating (valaddr, type, tmp_stream, 0); ui_file_put (tmp_stream, ui_memcpy, buffer); do_cleanups (cleanups); Index: gdb/c-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-valprint.c,v retrieving revision 1.42 diff -u -p -r1.42 c-valprint.c --- gdb/c-valprint.c 26 Jan 2007 20:54:16 -0000 1.42 +++ gdb/c-valprint.c 18 Feb 2007 04:35:32 -0000 @@ -432,7 +432,7 @@ c_val_print (struct type *type, const gd } else { - print_floating (valaddr + embedded_offset, type, stream); + print_floating (valaddr + embedded_offset, type, stream, 0); } break; @@ -458,7 +458,7 @@ c_val_print (struct type *type, const gd format, 0, stream); else print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), - stream); + stream, 0); fprintf_filtered (stream, " + "); if (format) print_scalar_formatted (valaddr + embedded_offset @@ -469,7 +469,7 @@ c_val_print (struct type *type, const gd print_floating (valaddr + embedded_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), TYPE_TARGET_TYPE (type), - stream); + stream, 0); fprintf_filtered (stream, " * I"); break; Index: gdb/f-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/f-valprint.c,v retrieving revision 1.34 diff -u -p -r1.34 f-valprint.c --- gdb/f-valprint.c 9 Jan 2007 17:58:50 -0000 1.34 +++ gdb/f-valprint.c 18 Feb 2007 04:35:38 -0000 @@ -495,7 +495,7 @@ f_val_print (struct type *type, const gd if (format) print_scalar_formatted (valaddr, type, format, 0, stream); else - print_floating (valaddr, type, stream); + print_floating (valaddr, type, stream, 0); break; case TYPE_CODE_VOID: @@ -571,9 +571,9 @@ f_val_print (struct type *type, const gd error (_("Cannot print out complex*%d variables"), TYPE_LENGTH (type)); } fputs_filtered ("(", stream); - print_floating (valaddr, type, stream); + print_floating (valaddr, type, stream, 0); fputs_filtered (",", stream); - print_floating (valaddr + TYPE_LENGTH (type), type, stream); + print_floating (valaddr + TYPE_LENGTH (type), type, stream, 0); fputs_filtered (")", stream); break; Index: gdb/m2-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/m2-valprint.c,v retrieving revision 1.12 diff -u -p -r1.12 m2-valprint.c --- gdb/m2-valprint.c 9 Jan 2007 17:58:51 -0000 1.12 +++ gdb/m2-valprint.c 18 Feb 2007 04:35:38 -0000 @@ -479,7 +479,7 @@ m2_val_print (struct type *type, const g print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else - print_floating (valaddr + embedded_offset, type, stream); + print_floating (valaddr + embedded_offset, type, stream, 0); break; case TYPE_CODE_METHOD: Index: gdb/p-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/p-valprint.c,v retrieving revision 1.47 diff -u -p -r1.47 p-valprint.c --- gdb/p-valprint.c 8 Feb 2007 14:20:56 -0000 1.47 +++ gdb/p-valprint.c 18 Feb 2007 04:35:38 -0000 @@ -426,7 +426,7 @@ pascal_val_print (struct type *type, con } else { - print_floating (valaddr + embedded_offset, type, stream); + print_floating (valaddr + embedded_offset, type, stream, 0); } break; Index: gdb/printcmd.c =================================================================== RCS file: /cvs/src/src/gdb/printcmd.c,v retrieving revision 1.100 diff -u -p -r1.100 printcmd.c --- gdb/printcmd.c 9 Jan 2007 17:58:56 -0000 1.100 +++ gdb/printcmd.c 18 Feb 2007 04:35:38 -0000 @@ -362,23 +362,36 @@ print_scalar_formatted (const void *vala switch (format) { case 'x': - if (!size) - { - /* No size specified, like in print. Print varying # of digits. */ - print_longest (stream, 'x', 1, val_long); - } - else - switch (size) - { - case 'b': - case 'h': - case 'w': - case 'g': - print_longest (stream, size, 1, val_long); - break; - default: - error (_("Undefined output size \"%c\"."), size); - } + /* TYPE_CODE_FLT gets printed in hex by print_floating() below. */ + if (TYPE_CODE (type) != TYPE_CODE_FLT) + { + if (!size) + { + /* No size specified, like in print. Print varying # of digits. */ + print_longest (stream, 'x', 1, val_long); + } + else + switch (size) + { + case 'b': + case 'h': + case 'w': + case 'g': + print_longest (stream, size, 1, val_long); + break; + default: + error (_("Undefined output size \"%c\"."), size); + } + break; + } + case 'f': + if (len == TYPE_LENGTH (builtin_type_float)) + type = builtin_type_float; + else if (len == TYPE_LENGTH (builtin_type_double)) + type = builtin_type_double; + else if (len == TYPE_LENGTH (builtin_type_long_double)) + type = builtin_type_long_double; + print_floating (valaddr, type, stream, format); break; case 'd': @@ -408,16 +421,6 @@ print_scalar_formatted (const void *vala stream, 0, Val_pretty_default); break; - case 'f': - if (len == TYPE_LENGTH (builtin_type_float)) - type = builtin_type_float; - else if (len == TYPE_LENGTH (builtin_type_double)) - type = builtin_type_double; - else if (len == TYPE_LENGTH (builtin_type_long_double)) - type = builtin_type_long_double; - print_floating (valaddr, type, stream); - break; - case 0: internal_error (__FILE__, __LINE__, _("failed internal consistency check")); @@ -1940,6 +1943,10 @@ printf_command (char *arg, int from_tty) bad = 1; break; +#ifdef PRINTF_HAS_HEX_DOUBLE + case 'a': + case 'A': +#endif case 'e': case 'f': case 'g': Index: gdb/valprint.c =================================================================== RCS file: /cvs/src/src/gdb/valprint.c,v retrieving revision 1.64 diff -u -p -r1.64 valprint.c --- gdb/valprint.c 9 Jan 2007 17:58:59 -0000 1.64 +++ gdb/valprint.c 18 Feb 2007 04:35:45 -0000 @@ -432,16 +432,18 @@ longest_to_int (LONGEST arg) } /* Print a floating point value of type TYPE (not always a - TYPE_CODE_FLT), pointed to in GDB by VALADDR, on STREAM. */ + TYPE_CODE_FLT), pointed to in GDB by VALADDR, on STREAM. + Print in hex if supported on host and requested by FORMAT 'x'. */ void print_floating (const gdb_byte *valaddr, struct type *type, - struct ui_file *stream) + struct ui_file *stream, int format) { DOUBLEST doub; int inv; const struct floatformat *fmt = NULL; unsigned len = TYPE_LENGTH (type); + const char *format_string; /* If it is a floating-point, check for obvious problems. */ if (TYPE_CODE (type) == TYPE_CODE_FLT) @@ -481,17 +483,32 @@ print_floating (const gdb_byte *valaddr, instead uses the type's length to determine the precision of the floating-point value being printed. */ + /* Do not use a format string variable to permit arguments checking. */ +#define FORMAT_PREFIX "%.*" +#ifdef PRINTF_HAS_LONG_DOUBLE +# define FORMAT_LONG FORMAT_PREFIX "L" +#else +# define FORMAT_LONG FORMAT_PREFIX +#endif +#ifdef PRINTF_HAS_HEX_DOUBLE +# define FORMAT_MAY_HEX (format == 'x' ? FORMAT_PREFIX "a" : FORMAT_PREFIX "g") +# define FORMAT_LONG_MAY_HEX (format == 'x' ? FORMAT_LONG "a" : FORMAT_LONG "g") +#else +# define FORMAT_MAY_HEX FORMAT_PREFIX "g" +# define FORMAT_LONG_MAY_HEX FORMAT_LONG "g" +#endif + if (len < sizeof (double)) - fprintf_filtered (stream, "%.9g", (double) doub); + fprintf_filtered (stream, FORMAT_MAY_HEX, 9, (double) doub); else if (len == sizeof (double)) - fprintf_filtered (stream, "%.17g", (double) doub); + fprintf_filtered (stream, FORMAT_MAY_HEX, 17, (double) doub); else #ifdef PRINTF_HAS_LONG_DOUBLE - fprintf_filtered (stream, "%.35Lg", doub); + fprintf_filtered (stream, FORMAT_LONG_MAY_HEX, 35, doub); #else /* This at least wins with values that are representable as doubles. */ - fprintf_filtered (stream, "%.17g", (double) doub); + fprintf_filtered (stream, FORMAT_MAY_HEX, 17, (double) doub); #endif } Index: gdb/value.h =================================================================== RCS file: /cvs/src/src/gdb/value.h,v retrieving revision 1.96 diff -u -p -r1.96 value.h --- gdb/value.h 9 Jan 2007 17:58:59 -0000 1.96 +++ gdb/value.h 18 Feb 2007 04:35:45 -0000 @@ -480,7 +480,7 @@ extern void print_longest (struct ui_fil int use_local, LONGEST val); extern void print_floating (const gdb_byte *valaddr, struct type *type, - struct ui_file *stream); + struct ui_file *stream, int format); extern int value_print (struct value *val, struct ui_file *stream, int format, enum val_prettyprint pretty); Index: gdb/testsuite/gdb.arch/i386-sse.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.arch/i386-sse.exp,v retrieving revision 1.6 diff -u -p -r1.6 i386-sse.exp --- gdb/testsuite/gdb.arch/i386-sse.exp 26 Jan 2007 20:53:15 -0000 1.6 +++ gdb/testsuite/gdb.arch/i386-sse.exp 18 Feb 2007 04:35:45 -0000 @@ -87,6 +87,12 @@ foreach r {0 1 2 3 4 5 6 7} { gdb_test "print \$xmm$r.v16_int8" \ ".. = \\{(-?\[0-9\]+ '.*', ){15}-?\[0-9\]+ '.*'\\}.*" \ "check int8 contents of %xmm$r" + gdb_test "print/x \$xmm$r.v4_float" \ + ".. = \\{(-?0x\[0-9a-f\]+\[.\]\[0-9a-f\]+p\[+-\]\[0-9\]+, ){3}-?0x\[0-9a-f\]+\[.\]\[0-9a-f\]+p\[+-\]\[0-9\]+\\}.*" \ + "check hex float contents of %xmm$r" + gdb_test "print/x \$xmm$r.v2_double" \ + ".. = \\{-?0x\[0-9a-f\]+\[.\]\[0-9a-f\]+p\[+-\]\[0-9\]+, -?0x\[0-9a-f\]+\[.\]\[0-9a-f\]+p\[+-\]\[0-9\]+\\}.*" \ + "check hex double contents of %xmm$r" } foreach r {0 1 2 3 4 5 6 7} { Index: gdb/testsuite/gdb.base/gdb1821.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gdb1821.exp,v retrieving revision 1.2 diff -u -p -r1.2 gdb1821.exp --- gdb/testsuite/gdb.base/gdb1821.exp 9 Jan 2007 17:59:11 -0000 1.2 +++ gdb/testsuite/gdb.base/gdb1821.exp 18 Feb 2007 13:04:13 -0000 @@ -39,5 +39,4 @@ if ![runto_main] then { perror "couldn't run to breakpoint" continue } -gdb_test "print /x bar" "{x__0 = 0x0, y__0 = 0x0, z__1 = 0x0}" - +gdb_test "print /x bar" "{x__0 = 0x0.0+p\\+0, y__0 = 0x0.0+p\\+0, z__1 = 0x0.0+p\\+0}" Index: gdb/configure =================================================================== RCS file: /cvs/src/src/gdb/configure,v retrieving revision 1.221 diff -u -p -r1.221 configure --- gdb/configure 2 Feb 2007 22:55:54 -0000 1.221 +++ gdb/configure 18 Feb 2007 12:52:56 -0000 @@ -20858,6 +20858,67 @@ echo "${ECHO_T}$gdb_cv_bigtoc" >&6 ;; esac +# Check if the compiler and runtime support printing doubles in hex. + +echo "$as_me:$LINENO: checking for hex double support in printf" >&5 +echo $ECHO_N "checking for hex double support in printf... $ECHO_C" >&6 +if test "${gdb_cv_printf_has_hex_double+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + gdb_cv_printf_has_hex_double=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +char buf[16]; + double f = 3.141592653; + sprintf (buf, "%a", f); + return (strncmp ("0x1.921fb", buf, 9)); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + gdb_cv_printf_has_hex_double=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +gdb_cv_printf_has_hex_double=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $gdb_cv_printf_has_hex_double" >&5 +echo "${ECHO_T}$gdb_cv_printf_has_hex_double" >&6 +if test $gdb_cv_printf_has_hex_double = yes; then + +cat >>confdefs.h <<\_ACEOF +#define PRINTF_HAS_HEX_DOUBLE 1 +_ACEOF + +fi + if test ${build} = ${host} -a ${host} = ${target} ; then Index: gdb/config.in =================================================================== RCS file: /cvs/src/src/gdb/config.in,v retrieving revision 1.88 diff -u -p -r1.88 config.in --- gdb/config.in 2 Feb 2007 22:54:46 -0000 1.88 +++ gdb/config.in 18 Feb 2007 04:35:33 -0000 @@ -497,6 +497,9 @@ /* Define if the prfpregset_t type is broken. */ #undef PRFPREGSET_T_BROKEN +/* Define to 1 if the "%a" format works to print doubles in hex. */ +#undef PRINTF_HAS_HEX_DOUBLE + /* Define to 1 if the "%Lg" format works to print long doubles. */ #undef PRINTF_HAS_LONG_DOUBLE Index: gdb/doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.387 diff -u -p -r1.387 gdb.texinfo --- gdb/doc/gdb.texinfo 18 Feb 2007 08:04:35 -0000 1.387 +++ gdb/doc/gdb.texinfo 23 Feb 2007 15:59:22 -0000 @@ -5744,7 +5744,8 @@ letters supported are: @table @code @item x Regard the bits of the value as an integer, and print the integer in -hexadecimal. +hexadecimal. Floating point numbers get printed in floating point hexadecimal +format. @item d Print as integer in signed decimal. @@ -5798,6 +5799,22 @@ p/x $pc Note that no space is required before the slash; this is because command names in @value{GDBN} cannot contain a slash. +Structured content gets printed recursively, applying the specified format to +each of its elements as during + +@smallexample +struct s + { + int i; + float fl; + double dbl; + }; +(gdb) p s +$1 = {i = 4, fl = 5.5999999, dbl = 7.7999999999999998} +(gdb) p/x s +$2 = {i = 0x4, fl = 0x1.666666000p+2, dbl = 0x1.f3333333333330000p+2} +@end smallexample + To reprint the last value in the value history with a different format, you can use the @code{print} command with just a format and no expression. For example, @samp{p/x} reprints the last value in hex.