From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14104 invoked by alias); 29 Oct 2007 14:47:24 -0000 Received: (qmail 14087 invoked by uid 22791); 29 Oct 2007 14:47:22 -0000 X-Spam-Check-By: sourceware.org Received: from igw2.br.ibm.com (HELO igw2.br.ibm.com) (32.104.18.25) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 29 Oct 2007 14:47:16 +0000 Received: from mailhub3.br.ibm.com (mailhub3 [9.18.232.110]) by igw2.br.ibm.com (Postfix) with ESMTP id E885E17F654 for ; Mon, 29 Oct 2007 12:44:25 -0200 (BRDT) Received: from d24av01.br.ibm.com (d24av01.br.ibm.com [9.18.232.46]) by mailhub3.br.ibm.com (8.13.8/8.13.8/NCO v8.5) with ESMTP id l9TElAsZ2154600 for ; Mon, 29 Oct 2007 12:47:12 -0200 Received: from d24av01.br.ibm.com (loopback [127.0.0.1]) by d24av01.br.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id l9TEl6fC016118 for ; Mon, 29 Oct 2007 11:47:09 -0300 Received: from [9.18.238.24] ([9.18.238.24]) by d24av01.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id l9TEl2In015983; Mon, 29 Oct 2007 11:47:04 -0300 Subject: Re: [PATCH] printf support for DFP values From: Luis Machado Reply-To: luisgpm@linux.vnet.ibm.com To: Eli Zaretskii Cc: gdb-patches@sourceware.org In-Reply-To: References: <1193449497.6950.22.camel@localhost> Content-Type: multipart/mixed; boundary="=-Ta8XqTEAIecWL25uOHtn" Date: Mon, 29 Oct 2007 15:03:00 -0000 Message-Id: <1193669215.4800.10.camel@localhost> Mime-Version: 1.0 X-Mailer: Evolution 2.6.1 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-10/txt/msg00753.txt.bz2 --=-Ta8XqTEAIecWL25uOHtn Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 1305 Thanks for reviewing Eli. > If we can implement DFP printing in GDB, why should we also check for > native DFP support and use that if available? Are there any > advantages in the native DFP printing, and if so, what are they? Yes. With native DFP support we would have access to all the modifiers (precision, width etc) available for printf, whereas, in the string conversion solution we would just have a straight value-to-string conversion mechanism without any additional capability. > Also, if this patch is accepted, please submit also a suitable patch > for the manual (doc/gdb.texinfo), where we describe the format > conversions supported by the `printf' command (node "Output"). No problem. I'll supply that patch. > A few questions/comments to the patch itself: > > > - double_arg, long_double_arg > > + double_arg, long_double_arg, decfloat_arg > > You are using decfloat_arg unconditionally, but I don't see it defined > anywhere in today's CVS. Am I missing something? decfloat_arg is being defined in an "enum" structure together with the other values (double_arg, long_double_arg, int_arg etc). Is there a different place you think it needs to be defined as well? > + /* Replace %H, %D and %DD for %s's. */ > Did you mean "Replace ... _with_ %s's"? Fixed. Regards, Luis --=-Ta8XqTEAIecWL25uOHtn Content-Disposition: attachment; filename=printf-dfp.diff Content-Type: text/x-patch; name=printf-dfp.diff; charset=utf-8 Content-Transfer-Encoding: 7bit Content-length: 7168 2007-10-29 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-29 04:41:23.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 with %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, --=-Ta8XqTEAIecWL25uOHtn--