2007-10-26 Luis Machado * printcmd.c: (printf_command): Add new DFP modifiers %H, %D and %DD. * configure.ac: Add check for DECFLOAT printf support. * configure: Regenerated. Index: git/gdb/printcmd.c =================================================================== --- git.orig/gdb/printcmd.c 2007-10-26 17:43:36.000000000 -0700 +++ git/gdb/printcmd.c 2007-10-26 17:58:07.000000000 -0700 @@ -41,6 +41,7 @@ #include "gdb_assert.h" #include "block.h" #include "disasm.h" +#include "dfp.h" #ifdef TUI #include "tui/tui.h" /* For tui_active et.al. */ @@ -1819,7 +1820,7 @@ enum argclass { int_arg, long_arg, long_long_arg, ptr_arg, string_arg, - double_arg, long_double_arg + double_arg, long_double_arg, decfloat_arg }; enum argclass *argclass; enum argclass this_argclass; @@ -1928,6 +1929,31 @@ bad = 1; break; + /* DFP Decimal32 types. */ + case 'H': + this_argclass = decfloat_arg; + + if (lcount || seen_h || seen_big_l) + bad = 1; + if (seen_prec || seen_zero || seen_space || seen_plus) + bad = 1; + break; + + /* DFP Decimal64 and Decimal128 types. */ + case 'D': + this_argclass = decfloat_arg; + + if (lcount || seen_h || seen_big_l) + bad = 1; + if (seen_prec || seen_zero || seen_space || seen_plus) + bad = 1; + + if (*(++f) == 'D') + printf_unfiltered("\nDecimal 128\n"); + else + printf_unfiltered("\nDecimal 64\n"); + break; + case 'c': this_argclass = int_arg; if (lcount || seen_h || seen_big_l) @@ -2094,6 +2120,55 @@ printf_filtered (current_substring, val); break; } + + /* Handles decimal floating point values. */ + case decfloat_arg: + { + char *eos; + char decstr[128]; + unsigned int dfp_len = TYPE_LENGTH (value_type (val_args[i])); + uint8_t *dfp_value_ptr = (uint8_t *) value_contents_all (val_args[i]) + + value_offset (val_args[i]); + +#if defined (PRINTF_HAS_DECFLOAT) + printf_filtered(current_substring, dfp_value_ptr); +#else + if (TYPE_CODE (value_type (val_args[i])) != TYPE_CODE_DECFLOAT) + error (_("Cannot convert parameter to decfloat.")); + + /* As a workaround until vasprintf has native support for DFP + we convert the DFP values to string and print them using + the %s format specifier. */ + decimal_to_string (dfp_value_ptr, dfp_len, decstr); + + /* Points to the end of the string so that we can go back + and check for DFP format specifiers. */ + eos = current_substring + strlen(current_substring); + + /* Replace %H, %D and %DD for %s's. */ + while(*--eos != '%') + if (*eos == 'D' && *(eos - 1) == 'D') + { + *(eos - 1) = 's'; + + /* If we've found a %DD format specifier we need to go + through the whole string pulling back one character + since this format specifier has two chars. */ + while (eos < last_arg) + { + *eos = *(eos + 1); + eos++; + } + } + else if (*eos == 'D' || *eos == 'H') + *eos = 's'; + + /* Print the DFP value. */ + printf_filtered(current_substring, decstr); + break; +#endif + } + case ptr_arg: { /* We avoid the host's %p because pointers are too Index: git/gdb/configure.ac =================================================================== --- git.orig/gdb/configure.ac 2007-10-26 17:43:36.000000000 -0700 +++ git/gdb/configure.ac 2007-10-26 17:52:25.000000000 -0700 @@ -927,6 +927,25 @@ [Define to 1 if the "%ll" format works to print long longs.]) fi +# Check if the compiler and runtime support printing decfloats. + +AC_CACHE_CHECK([for decfloat support in printf], + gdb_cv_printf_has_decfloat, + [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], +[[char buf[64]; + _Decimal32 d32 = 1.2345df; + _Decimal64 d64 = 1.2345dd; + _Decimal128 d128 = 1.2345dl; + sprintf (buf, "Decimal32: %H\nDecimal64: %D\nDecimal128: %DD", d32, d64, d128); + return (strcmp ("Decimal32: 1.2345\nDecimal64: 1.2345\nDecimal128: 1.2345", buf));]])], + gdb_cv_printf_has_decfloat=yes, + gdb_cv_printf_has_decfloat=no, + gdb_cv_printf_has_decfloat=no)]) +if test $gdb_cv_printf_has_decfloat = yes; then + AC_DEFINE(PRINTF_HAS_DECFLOAT, 1, + [Define to 1 if the "%H, %D and %DD" formats work to print decfloats.]) +fi + # Check if the compiler supports the `long double' type. We can't use # AC_C_LONG_DOUBLE because that one does additional checks on the # constants defined in that fail on some systems, Index: git/gdb/configure =================================================================== --- git.orig/gdb/configure 2007-10-26 17:43:36.000000000 -0700 +++ git/gdb/configure 2007-10-26 17:59:22.000000000 -0700 @@ -21132,6 +21132,69 @@ fi +# Check if the compiler and runtime support printing decfloats. + +echo "$as_me:$LINENO: checking for decfloat support in printf" >&5 +echo $ECHO_N "checking for decfloat support in printf... $ECHO_C" >&6 +if test "${gdb_cv_printf_has_decfloat+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + gdb_cv_printf_has_decfloat=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[64]; + _Decimal32 d32 = 1.2345df; + _Decimal64 d64 = 1.2345dd; + _Decimal128 d128 = 1.2345dl; + sprintf (buf, "Decimal32: %H\nDecimal64: %D\nDecimal128: %DD", d32, d64, d128); + return (strcmp ("Decimal32: 1.2345\nDecimal64: 1.2345\nDecimal128: 1.2345", buf)); + ; + 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_decfloat=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_decfloat=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_decfloat" >&5 +echo "${ECHO_T}$gdb_cv_printf_has_decfloat" >&6 +if test $gdb_cv_printf_has_decfloat = yes; then + +cat >>confdefs.h <<\_ACEOF +#define PRINTF_HAS_DECFLOAT 1 +_ACEOF + +fi + # Check if the compiler supports the `long double' type. We can't use # AC_C_LONG_DOUBLE because that one does additional checks on the # constants defined in that fail on some systems,