From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6770 invoked by alias); 27 Oct 2007 01:45:24 -0000 Received: (qmail 6761 invoked by uid 22791); 27 Oct 2007 01:45:23 -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; Sat, 27 Oct 2007 01:45:14 +0000 Received: from mailhub1.br.ibm.com (mailhub1 [9.18.232.109]) by igw2.br.ibm.com (Postfix) with ESMTP id 5687817F54F for ; Fri, 26 Oct 2007 23:42:30 -0200 (BRDT) Received: from d24av01.br.ibm.com (d24av01.br.ibm.com [9.18.232.46]) by mailhub1.br.ibm.com (8.13.8/8.13.8/NCO v8.5) with ESMTP id l9R1jB4A3141840 for ; Fri, 26 Oct 2007 23:45:11 -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 l9R1jADm013386 for ; Fri, 26 Oct 2007 22:45:10 -0300 Received: from [9.8.13.249] ([9.8.13.249]) by d24av01.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id l9R1j8ZW013325 for ; Fri, 26 Oct 2007 22:45:10 -0300 Subject: [PATCH] printf support for DFP values From: Luis Machado Reply-To: luisgpm@linux.vnet.ibm.com To: gdb-patches@sourceware.org Content-Type: multipart/mixed; boundary="=-sMz4QPXRr4QPb+CcuEqW" Date: Sat, 27 Oct 2007 06:25:00 -0000 Message-Id: <1193449497.6950.22.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/msg00733.txt.bz2 --=-sMz4QPXRr4QPb+CcuEqW Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 1167 Hi folks, Libdecnumber has been already integrated into GDB, but there are still some missing features that must be addressed for DFP types. GDB's printf command currently does not support printing of DFP values (Decimal32, Decimal64 and Decimal128). The following patch proposes to fix that by allowing GDB's printf command to deal with those numbers. Native DFP printing support with printf is not yet ready, but it should be in some time eventually. Due to this, i'm testing for native printf support for DFP in the configure script and setting a constant to reflect the result (PRINTF_HAS_DECFLOAT). Based on that GDB has two ways of dealing with the problem: 1 - If we have native support (and thus PRINTF_HAS_DECFLOAT is set), we just send the DFP value straight to the standard printing routine with its format specifiers (printf_filtered). 2 - If there's currently no support, we stick with converting the DFP values to strings and using string format specifiers to print them. This should make things flexible enough for both systems, one that has native printf support for DFP and one that doesn't. I'd appreciate comments on this one. Regards, Luis --=-sMz4QPXRr4QPb+CcuEqW 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: 7166 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, --=-sMz4QPXRr4QPb+CcuEqW--