From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6541 invoked by alias); 21 Jun 2006 23:36:24 -0000 Received: (qmail 6528 invoked by uid 22791); 21 Jun 2006 23:36:19 -0000 X-Spam-Check-By: sourceware.org Received: from ausmtp06.au.ibm.com (HELO ausmtp06.au.ibm.com) (202.81.18.155) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 21 Jun 2006 23:36:12 +0000 Received: from sd0208e0.au.ibm.com (d23rh904.au.ibm.com [202.81.18.202]) by ausmtp06.au.ibm.com (8.13.6/8.13.6) with ESMTP id k5LNc7is7753914 for ; Thu, 22 Jun 2006 09:38:07 +1000 Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.250.237]) by sd0208e0.au.ibm.com (8.12.10/NCO/VER6.8) with ESMTP id k5LNdUOp202474 for ; Thu, 22 Jun 2006 09:39:30 +1000 Received: from d23av04.au.ibm.com (loopback [127.0.0.1]) by d23av04.au.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id k5LNa86L021138 for ; Thu, 22 Jun 2006 09:36:08 +1000 Received: from dyn9047022067.beaverton.ibm.com (dyn9047022067.beaverton.ibm.com [9.47.22.67]) by d23av04.au.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id k5LNa5l3021095; Thu, 22 Jun 2006 09:36:06 +1000 Date: Wed, 21 Jun 2006 23:36:00 -0000 From: Wu Zhou To: drow@false.org, gdb-patches@sourceware.org Subject: [RFC] decimal float point patch based on libdecnumber: gdb patch In-Reply-To: Message-ID: References: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-06/txt/msg00315.txt.bz2 Appended is the patch. I had tested it with the latest gcc-4.2 cvs tree on x86, with option "--enable-decimal-float". All the 121 tests passed. Please review and comment. Thanks a lot. 2006-06-21 Wu Zhou * expression.h (enum exp_opcode): Add an opcode (OP_DECDOUBLE) for DFP constants. (union exp_element): Add decdoubleconst to represent DFP elements, which is 16 bytes by default. * parser-defs.h (write_exp_elt_decdblcst): Prototype. * parse.c (write_exp_elt_decdblcst): New function to write a decimal double const into the expression. (operator_length_standard): Set operator length for OP_DECDOUBLE to 4. * c-exp.y (YYSTYPE): Add typed_val_decfloat for decimal floating point in YYSTYPE union. Add token DECFLOAT for typed_val_decfloat. Add expression element handling code for DECFLOAT. (parse_number): Parse DFP constants, which end with suffix 'df', 'dd' or 'dl'. Return DECFLOAT. * c-lang.c (c_create_fundamental_type): Create fundamental types for DFP. * c-valprint.c (c_val_print): Call print_decimal_floating to print DFP values. * dwarf2read.c (read_base_type): Read DW_ATE_decimal_float attribute code and return TYPE_CODE_DECFLT. (dwarf_base_type): Set dwarf2_fundamental_type for DFP values. * eval.c (evaluate_subexp_standard): Call value_from_decdouble to handle OP_DECDOUBLE. * gdbtypes.h: Add three fundamental types for DFP. (enum type_code): Add TYPE_CODE_DECFLT as a type code for DFP. (struct builtin_type): Add builtin_decfloat, builtin_decdouble and builtin_declong. * gdbtypes.c: Add three builtin types for DFP. (build_gdbtypes): Build these three builtin types for DFP. (gdbtypes_post_init): Initialize builtin_decfloat, builtin_decdouble and builtin_declong. * value.h (value_from_decdouble): Prototype. (print_decimal_floating): Prototype. * valprint.c (print_decimal_floating): New function to print DFP values. * value.c (value_from_decdouble): New function to get the value from a decimal double. * valarith.c (value_neg): Add some code to handle the negation operation of DFP values. * dfp.h: New header file for decimal floating point support in GDB. * dfp.c: New source file for decimal floating point support in GDB. Implement decimal_from_string and decimal_to_string based on libdecnumber API. * Makefile.in: Add decimal floating point related entry. Add some macro to specify the libdecnumber directory, cflags and the name of libdecnumber library. Index: expression.h =================================================================== RCS file: /cvs/src/src/gdb/expression.h,v retrieving revision 1.18 diff -u -r1.18 expression.h --- expression.h 17 Dec 2005 22:33:59 -0000 1.18 +++ expression.h 21 Jun 2006 23:08:51 -0000 @@ -327,6 +327,11 @@ /* A F90 array range operator (for "exp:exp", "exp:", ":exp" and ":"). */ OP_F90_RANGE, + /* OP_DECDOUBLE is followed by a type pointer in the next exp_element + and a dec long constant value in the following exp_element. + Then comes another OP_DECDOUBLE. */ + OP_DECDOUBLE, + /* First extension operator. Individual language modules define extra operators they need as constants with values OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate @@ -354,6 +359,7 @@ struct symbol *symbol; LONGEST longconst; DOUBLEST doubleconst; + gdb_byte decdoubleconst[16]; /* Really sizeof (union exp_element) characters (or less for the last element of a string). */ char string; Index: parser-defs.h =================================================================== RCS file: /cvs/src/src/gdb/parser-defs.h,v retrieving revision 1.20 diff -u -r1.20 parser-defs.h --- parser-defs.h 17 Dec 2005 22:34:01 -0000 1.20 +++ parser-defs.h 21 Jun 2006 23:08:51 -0000 @@ -121,6 +121,8 @@ extern void write_exp_elt_dblcst (DOUBLEST); +extern void write_exp_elt_decdblcst (gdb_byte *); + extern void write_exp_elt_type (struct type *); extern void write_exp_elt_intern (struct internalvar *); Index: parse.c =================================================================== RCS file: /cvs/src/src/gdb/parse.c,v retrieving revision 1.52 diff -u -r1.52 parse.c --- parse.c 24 Jan 2006 15:20:10 -0000 1.52 +++ parse.c 21 Jun 2006 23:08:51 -0000 @@ -236,6 +236,18 @@ } void +write_exp_elt_decdblcst (gdb_byte expelt[16]) +{ + union exp_element tmp; + int index; + + for (index = 0; index < 16; index++) + tmp.decdoubleconst[index] = expelt[index]; + + write_exp_elt (tmp); +} + +void write_exp_elt_type (struct type *expelt) { union exp_element tmp; @@ -857,6 +869,7 @@ case OP_LONG: case OP_DOUBLE: + case OP_DECDOUBLE: case OP_VAR_VALUE: oplen = 4; break; Index: c-exp.y =================================================================== RCS file: /cvs/src/src/gdb/c-exp.y,v retrieving revision 1.34 diff -u -r1.34 c-exp.y --- c-exp.y 23 Feb 2006 18:43:41 -0000 1.34 +++ c-exp.y 21 Jun 2006 23:08:51 -0000 @@ -53,6 +53,7 @@ #include "charset.h" #include "block.h" #include "cp-support.h" +#include "dfp.h" /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), as well as gratuitiously global symbol names, so we can have multiple @@ -131,6 +132,10 @@ DOUBLEST dval; struct type *type; } typed_val_float; + struct { + gdb_byte val[16]; + struct type *type; + } typed_val_decfloat; struct symbol *sym; struct type *tval; struct stoken sval; @@ -163,6 +168,7 @@ %token INT %token FLOAT +%token DECFLOAT /* Both NAME and TYPENAME tokens represent symbols in the input, and both convey their data as strings. @@ -497,6 +503,13 @@ write_exp_elt_opcode (OP_DOUBLE); } ; +exp : DECFLOAT + { write_exp_elt_opcode (OP_DECDOUBLE); + write_exp_elt_type ($1.type); + write_exp_elt_decdblcst ($1.val); + write_exp_elt_opcode (OP_DECDOUBLE); } + ; + exp : variable ; @@ -1080,6 +1093,49 @@ char saved_char = p[len]; p[len] = 0; /* null-terminate the token */ + + /* If it ends at "df", "dd" or "dl", take it as type of decimal floating + point. Return DECFLOAT. */ + + if (p[len - 2] == 'd' && p[len - 1] == 'f') + { + gdb_byte *dec_val = (gdb_byte *)malloc (4); + p[len - 2] = '\0'; + putithere->typed_val_decfloat.type = + builtin_type (current_gdbarch)->builtin_decfloat; + decimal_from_string (dec_val, 4, p); + reverse_dfp (dec_val, 4, putithere->typed_val_decfloat.val); + free (dec_val); + p[len] = saved_char; + return (DECFLOAT); + } + + if (p[len - 2] == 'd' && p[len - 1] == 'd') + { + gdb_byte *dec_val = (gdb_byte *)malloc (8); + p[len - 2] = '\0'; + putithere->typed_val_decfloat.type = + builtin_type (current_gdbarch)->builtin_decdouble; + decimal_from_string (dec_val, 8, p); + reverse_dfp (dec_val, 8, putithere->typed_val_decfloat.val); + free (dec_val); + p[len] = saved_char; + return (DECFLOAT); + } + + if (p[len - 2] == 'd' && p[len - 1] == 'l') + { + gdb_byte *dec_val = (gdb_byte *)malloc (16); + p[len - 2] = '\0'; + putithere->typed_val_decfloat.type = + builtin_type (current_gdbarch)->builtin_declong; + decimal_from_string (dec_val, 16, p); + reverse_dfp (dec_val, 16, putithere->typed_val_decfloat.val); + free (dec_val); + p[len] = saved_char; + return (DECFLOAT); + } + num = sscanf (p, DOUBLEST_SCAN_FORMAT "%s", &putithere->typed_val_float.dval, s); p[len] = saved_char; /* restore the input stream */ Index: c-lang.c =================================================================== RCS file: /cvs/src/src/gdb/c-lang.c,v retrieving revision 1.39 diff -u -r1.39 c-lang.c --- c-lang.c 17 Dec 2005 22:33:59 -0000 1.39 +++ c-lang.c 21 Jun 2006 23:08:52 -0000 @@ -322,6 +322,21 @@ TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, 0, "long double", objfile); break; + case FT_DECFLOAT: + type = init_type (TYPE_CODE_DECFLT, + 32 / 8, + 0, "decimal float", objfile); + break; + case FT_DBL_PREC_DECFLOAT: + type = init_type (TYPE_CODE_DECFLT, + 64 / 8, + 0, "decimal double", objfile); + break; + case FT_EXT_PREC_DECFLOAT: + type = init_type (TYPE_CODE_DECFLT, + 128 / 8, + 0, "decimal long double", objfile); + break; case FT_COMPLEX: type = init_type (TYPE_CODE_FLT, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT, Index: c-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-valprint.c,v retrieving revision 1.39 diff -u -r1.39 c-valprint.c --- c-valprint.c 18 Jan 2006 21:24:19 -0000 1.39 +++ c-valprint.c 21 Jun 2006 23:08:52 -0000 @@ -442,6 +442,17 @@ } break; + case TYPE_CODE_DECFLT: + if (format) + { + print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); + } + else + { + print_decimal_floating (valaddr + embedded_offset, type, stream); + } + break; + case TYPE_CODE_METHOD: { struct value *v = value_at (type, address); Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.198 diff -u -r1.198 dwarf2read.c --- dwarf2read.c 9 Jun 2006 00:44:28 -0000 1.198 +++ dwarf2read.c 21 Jun 2006 23:08:52 -0000 @@ -4739,6 +4739,9 @@ case DW_ATE_complex_float: code = TYPE_CODE_COMPLEX; break; + case DW_ATE_decimal_float: + code = TYPE_CODE_DECFLT; + break; case DW_ATE_float: code = TYPE_CODE_FLT; break; @@ -7507,6 +7510,14 @@ type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu); } return type; + case DW_ATE_decimal_float: + if (size == 16) + type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_DECFLOAT, cu); + else if (size == 8) + type = dwarf2_fundamental_type (objfile, FT_EXT_PREC_DECFLOAT, cu); + else + type = dwarf2_fundamental_type (objfile, FT_DECFLOAT, cu); + return type; case DW_ATE_signed: switch (size) { Index: eval.c =================================================================== RCS file: /cvs/src/src/gdb/eval.c,v retrieving revision 1.61 diff -u -r1.61 eval.c --- eval.c 18 Feb 2006 20:47:54 -0000 1.61 +++ eval.c 21 Jun 2006 23:08:52 -0000 @@ -447,6 +447,11 @@ return value_from_double (exp->elts[pc + 1].type, exp->elts[pc + 2].doubleconst); + case OP_DECDOUBLE: + (*pos) += 3; + return value_from_decdouble (expect_type, exp->elts[pc + 1].type, + exp->elts[pc + 2].decdoubleconst); + case OP_VAR_VALUE: (*pos) += 3; if (noside == EVAL_SKIP) Index: gdbtypes.h =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.h,v retrieving revision 1.65 diff -u -r1.65 gdbtypes.h --- gdbtypes.h 1 Feb 2006 23:14:10 -0000 1.65 +++ gdbtypes.h 21 Jun 2006 23:08:52 -0000 @@ -67,7 +67,12 @@ #define FT_UNSIGNED_BYTE 27 #define FT_TEMPLATE_ARG 28 -#define FT_NUM_MEMBERS 29 /* Highest FT_* above, plus one. */ +/* The following three fundamental types are for decimal floating point. */ +#define FT_DECFLOAT 29 +#define FT_DBL_PREC_DECFLOAT 30 +#define FT_EXT_PREC_DECFLOAT 31 + +#define FT_NUM_MEMBERS 32 /* Highest FT_* above, plus one. */ /* Some macros for char-based bitfields. */ @@ -159,7 +164,9 @@ TYPE_CODE_TEMPLATE, /* C++ template */ TYPE_CODE_TEMPLATE_ARG, /* C++ template arg */ - TYPE_CODE_NAMESPACE /* C++ namespace. */ + TYPE_CODE_NAMESPACE, /* C++ namespace. */ + + TYPE_CODE_DECFLT /* Decimal floating point. */ }; /* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an @@ -1005,6 +1012,9 @@ struct type *builtin_bool; struct type *builtin_long_long; struct type *builtin_unsigned_long_long; + struct type *builtin_decfloat; + struct type *builtin_decdouble; + struct type *builtin_declong; }; /* Return the type table for the specified architecture. */ @@ -1028,6 +1038,9 @@ extern struct type *builtin_type_double_complex; extern struct type *builtin_type_string; extern struct type *builtin_type_bool; +extern struct type *builtin_type_decfloat; +extern struct type *builtin_type_decdouble; +extern struct type *builtin_type_declong; /* Address/pointer types: */ /* (C) Language `pointer to data' type. Some target platforms use an Index: gdbtypes.c =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.c,v retrieving revision 1.105 diff -u -r1.105 gdbtypes.c --- gdbtypes.c 1 Mar 2006 19:34:46 -0000 1.105 +++ gdbtypes.c 21 Jun 2006 23:08:52 -0000 @@ -76,6 +76,12 @@ struct type *builtin_type_uint128; struct type *builtin_type_bool; +/* The following three are about decimal floating point types, which are now + considered as potential extension to C99 standard. */ +struct type *builtin_type_decfloat; +struct type *builtin_type_decdouble; +struct type *builtin_type_declong; + /* 128 bit long vector types */ struct type *builtin_type_v2_double; struct type *builtin_type_v4_float; @@ -3379,6 +3385,21 @@ #if 0 TYPE_FLOATFORMAT (builtin_type_long_double) = TARGET_LONG_DOUBLE_FORMAT; #endif + + /* Builtin types for decimal floating point types. */ + builtin_type_decfloat = + init_type (TYPE_CODE_DECFLT, 32 / 8, + 0, + "decimal float", (struct objfile *) NULL); + builtin_type_decdouble = + init_type (TYPE_CODE_DECFLT, 64 / 8, + 0, + "decimal double", (struct objfile *) NULL); + builtin_type_declong = + init_type (TYPE_CODE_DECFLT, 128 / 8, + 0, + "decimal long double", (struct objfile *) NULL); + builtin_type_complex = init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT, 0, @@ -3604,6 +3625,21 @@ 0, "bool", (struct objfile *) NULL); + /* The following three are about decimal floating point types, which are + 32-bits, 64-bits and 128-bits respectively. */ + builtin_type->builtin_decfloat = + init_type (TYPE_CODE_DECFLT, 32 / 8, + 0, + "decimal float", (struct objfile *) NULL); + builtin_type->builtin_decdouble = + init_type (TYPE_CODE_DECFLT, 64 / 8, + 0, + "decimal double", (struct objfile *) NULL); + builtin_type->builtin_declong = + init_type (TYPE_CODE_DECFLT, 128 / 8, + 0, + "decimal long double", (struct objfile *) NULL); + /* Pointer/Address types. */ /* NOTE: on some targets, addresses and pointers are not necessarily @@ -3742,6 +3778,9 @@ DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_void_func_ptr); DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR); DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_bfd_vma); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_decfloat); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_decdouble); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_declong); deprecated_register_gdbarch_swap (NULL, 0, build_gdbtypes); /* Note: These types do not need to be swapped - they are target Index: value.h =================================================================== RCS file: /cvs/src/src/gdb/value.h,v retrieving revision 1.91 diff -u -r1.91 value.h --- value.h 31 Mar 2006 10:36:18 -0000 1.91 +++ value.h 21 Jun 2006 23:08:52 -0000 @@ -274,6 +274,7 @@ extern struct value *value_from_longest (struct type *type, LONGEST num); extern struct value *value_from_pointer (struct type *type, CORE_ADDR addr); extern struct value *value_from_double (struct type *type, DOUBLEST num); +extern struct value *value_from_decdouble (struct type *expect_type, struct type *type, gdb_byte decbytes[16]); extern struct value *value_from_string (char *string); extern struct value *value_at (struct type *type, CORE_ADDR addr); @@ -469,6 +470,9 @@ extern void print_floating (const gdb_byte *valaddr, struct type *type, struct ui_file *stream); +extern void print_decimal_floating (const gdb_byte *valaddr, struct type *type, + struct ui_file *stream); + extern int value_print (struct value *val, struct ui_file *stream, int format, enum val_prettyprint pretty); Index: valprint.c =================================================================== RCS file: /cvs/src/src/gdb/valprint.c,v retrieving revision 1.60 diff -u -r1.60 valprint.c --- valprint.c 15 May 2006 16:53:38 -0000 1.60 +++ valprint.c 21 Jun 2006 23:08:53 -0000 @@ -35,6 +35,7 @@ #include "floatformat.h" #include "doublest.h" #include "exceptions.h" +#include "dfp.h" #include @@ -496,6 +497,21 @@ } void +print_decimal_floating (const gdb_byte *valaddr, struct type *type, + struct ui_file *stream) +{ + char decstr[128]; + unsigned len = TYPE_LENGTH (type); + gdb_byte *dec_val = (gdb_byte *)malloc (len); + + reverse_dfp (valaddr, len, dec_val); + decimal_to_string (dec_val, len, decstr); + fputs_filtered (decstr, stream); + free (dec_val); + return; +} + +void print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, unsigned len) { Index: value.c =================================================================== RCS file: /cvs/src/src/gdb/value.c,v retrieving revision 1.36 diff -u -r1.36 value.c --- value.c 31 Mar 2006 10:36:18 -0000 1.36 +++ value.c 21 Jun 2006 23:08:53 -0000 @@ -37,6 +37,7 @@ #include "gdb_assert.h" #include "regcache.h" #include "block.h" +#include "dfp.h" /* Prototypes for exported functions. */ @@ -1610,6 +1611,30 @@ } struct value * +value_from_decdouble (struct type *expect_type, struct type *type, + gdb_byte decbytes[16]) +{ + struct value *val = allocate_value (type); + int len = TYPE_LENGTH (type); + gdb_byte *dec_val = (gdb_byte *)malloc (16); + + if (expect_type) + { + int expect_len = TYPE_LENGTH (expect_type); + char decstr[128]; + int real_len; + + reverse_dfp (decbytes, expect_len, dec_val); + decimal_to_string (dec_val, len, decstr); + decimal_from_string (dec_val, expect_len, decstr); + reverse_dfp (dec_val, expect_len, decbytes); + } + + memcpy (value_contents_raw (val), decbytes, len); + return val; +} + +struct value * coerce_ref (struct value *arg) { struct type *value_type_arg_tmp = check_typedef (value_type (arg)); Index: valarith.c =================================================================== RCS file: /cvs/src/src/gdb/valarith.c,v retrieving revision 1.45 diff -u -r1.45 valarith.c --- valarith.c 24 Jan 2006 21:21:12 -0000 1.45 +++ valarith.c 21 Jun 2006 23:08:53 -0000 @@ -1378,6 +1378,18 @@ type = check_typedef (value_type (arg1)); + if (TYPE_CODE (type) == TYPE_CODE_DECFLT) + { + struct value *val = allocate_value (result_type); + int len = TYPE_LENGTH (type); + gdb_byte *decbytes = (gdb_byte *) value_contents (arg1); + + /* To change the first bit is ok. */ + decbytes[len-1] = decbytes[len - 1] | 0x80; + memcpy (value_contents_raw (val), decbytes, 16); + return val; + } + if (TYPE_CODE (type) == TYPE_CODE_FLT) return value_from_double (result_type, -value_as_double (arg1)); else if (is_integral_type (type)) Index: dfp.h =================================================================== RCS file: dfp.h diff -N dfp.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dfp.h 21 Jun 2006 23:08:53 -0000 @@ -0,0 +1,45 @@ +/* Decimal floating point support for GDB. + + Copyright 2006 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Decimal floating point is one of the extension to IEEE 754, which is + described in http://grouper.ieee.org/groups/754/revision.html and + http://www2.hursley.ibm.com/decimal/. It completes binary floating + point by representing floating point more exactly. */ + +/* There is a project intended to add DFP support into GCC, described in + http://gcc.gnu.org/wiki/Decimal%20Floating-Point. This file is intended + to add DFP support into GDB. */ + +#ifndef DFP_H +#define DFP_H +#include +#include +#include + +/* The conversion from decimal floating point to string, and reverse. */ +extern void decimal_to_string (const uint8_t *, int, char *); +extern void decimal_from_string (uint8_t *, int, char *); + +/* The value struct of gdb and decimal type of libdecnumber are using + different endian for storing the content. This routine is used to + convert between these two. */ +extern void reverse_dfp (const gdb_byte *, int, gdb_byte *); +#endif Index: dfp.c =================================================================== RCS file: dfp.c diff -N dfp.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dfp.c 21 Jun 2006 23:08:53 -0000 @@ -0,0 +1,104 @@ +/* Decimal floating point support for GDB. + + Copyright 2006 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "dfp.h" +#include + +/* The order of the following headers is important for making sure + decNumber structure is large enough to hold decimal128 digits. */ + +#include "decimal128.h" +#include "decimal64.h" +#include "decimal32.h" +#include "decNumber.h" + +void +reverse_dfp (const gdb_byte *valaddr, int len, gdb_byte *dec_val) +{ + int index; + + for (index = 0; index < len; index++) + dec_val[index] = valaddr[len - index - 1]; + + return; +} + +/* Convert deciaml type to its string representation. LEN is the length + of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and + 16 bytes for decimal128. */ +void +decimal_to_string (const uint8_t *dec, int len, char *s) +{ + switch (len) + { + case 4: + decimal32ToString ((decimal32 *)dec, s); + return; + case 8: + decimal64ToString ((decimal64 *)dec, s); + return; + case 16: + decimal128ToString ((decimal128 *)dec, s); + return; + default: + error ("We don't support decimal number of %d bytes.", len); + } +} + +void +decimal_from_string (uint8_t *dec, int len, char *string) +{ + decNumber dn; + decContext set; + switch (len) + { + case 4: + decContextDefault (&set, DEC_INIT_DECIMAL32); + break; + case 8: + decContextDefault (&set, DEC_INIT_DECIMAL64); + break; + case 16: + decContextDefault (&set, DEC_INIT_DECIMAL128); + break; + default: + error ("We don't support decimal number of %d bytes.", len); + } + + set.traps = 0; + + decNumberFromString (&dn, string, &set); + switch (len) + { + case 4: + decimal32FromNumber ((decimal32 *)dec, &dn, &set); + return; + case 8: + decimal64FromNumber ((decimal64 *)dec, &dn, &set); + return; + case 16: + decimal128FromNumber ((decimal128 *)dec, &dn, &set); + return; + default: + error ("We don't support decimal number of %d bytes.", len); + } +} Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.821 diff -u -r1.821 Makefile.in --- Makefile.in 31 May 2006 15:14:36 -0000 1.821 +++ Makefile.in 21 Jun 2006 23:08:53 -0000 @@ -122,6 +122,12 @@ BFD_SRC = $(srcdir)/$(BFD_DIR) BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC) +# Where is the decnumber library? Typically in ../libdecnumber. +LIBDECNUMBER_DIR = ../libdecnumber +LIBDECNUMBER = $(LIBDECNUMBER_DIR)/libdecnumber.a +LIBDECNUMBER_SRC = $(srcdir)/$(LIBDECNUMBER_DIR) +LIBDECNUMBER_CFLAGS = -I$(LIBDECNUMBER_DIR) -I$(LIBDECNUMBER_SRC) + # Where is the READLINE library? Typically in ../readline. READLINE_DIR = ../readline READLINE = $(READLINE_DIR)/libreadline.a @@ -348,7 +354,7 @@ INTERNAL_CFLAGS_BASE = \ $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \ $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) \ - $(BFD_CFLAGS) $(INCLUDE_CFLAGS) \ + $(BFD_CFLAGS) $(INCLUDE_CFLAGS) $(LIBDECNUMBER_CFLAGS) \ $(INTL_CFLAGS) $(ENABLE_CFLAGS) INTERNAL_WARN_CFLAGS = $(INTERNAL_CFLAGS_BASE) $(GDB_WARN_CFLAGS) INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS) @@ -371,10 +377,10 @@ # LIBIBERTY appears twice on purpose. # If you have the Cygnus libraries installed, # you can use 'CLIBS=$(INSTALLED_LIBS)' 'CDEPS=' -INSTALLED_LIBS=-lbfd -lreadline -lopcodes -liberty \ +INSTALLED_LIBS=-lbfd -lreadline -lopcodes -liberty -ldecnumber \ $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \ -lintl -liberty -CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(INTL) $(LIBIBERTY) \ +CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(INTL) $(LIBIBERTY) $(LIBDECNUMBER) \ $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \ $(LIBICONV) \ $(LIBIBERTY) $(WIN32LIBS) @@ -605,6 +611,10 @@ safe_ctype_h = $(INCLUDE_DIR)/safe-ctype.h hashtab_h = $(INCLUDE_DIR)/hashtab.h +decimal128_h = $(LIBDECNUMBER_DIR)/decimal128.h +decimal64_h = $(LIBDECNUMBER_DIR)/decimal64.h +decimal32_h = $(LIBDECNUMBER_DIR)/decimal32.h + # # $BUILD/ headers # @@ -670,6 +680,7 @@ disasm_h = disasm.h doublest_h = doublest.h $(floatformat_h) dummy_frame_h = dummy-frame.h +dfp_h = dfp.h dwarf2expr_h = dwarf2expr.h dwarf2_frame_h = dwarf2-frame.h dwarf2loc_h = dwarf2loc.h @@ -912,7 +923,7 @@ auxv.o \ bfd-target.o \ blockframe.o breakpoint.o findvar.o regcache.o \ - charset.o disasm.o dummy-frame.o \ + charset.o disasm.o dummy-frame.o dfp.o \ source.o value.o eval.o valops.o valarith.o valprint.o printcmd.o \ block.o symtab.o symfile.o symmisc.o linespec.o dictionary.o \ infcall.o \ @@ -1917,6 +1928,7 @@ dummy-frame.o: dummy-frame.c $(defs_h) $(dummy_frame_h) $(regcache_h) \ $(frame_h) $(inferior_h) $(gdb_assert_h) $(frame_unwind_h) \ $(command_h) $(gdbcmd_h) $(gdb_string_h) +dfp.o: dfp.c $(defs_h) $(dfp_h) $(decimal128_h) $(decimal64_h) $(decimal32_h) dve3900-rom.o: dve3900-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \ $(serial_h) $(inferior_h) $(command_h) $(gdb_string_h) $(regcache_h) \ $(mips_tdep_h) @@ -2790,7 +2802,7 @@ valprint.o: valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \ $(value_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(language_h) \ $(annotate_h) $(valprint_h) $(floatformat_h) $(doublest_h) \ - $(exceptions_h) + $(exceptions_h) $(dfp_h) value.o: value.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \ $(value_h) $(gdbcore_h) $(command_h) $(gdbcmd_h) $(target_h) \ $(language_h) $(scm_lang_h) $(demangle_h) $(doublest_h) \ Here is the patch to add libdecnumber code into gdb top-level repository. I didn't figure out how to add a whole new directory into the cvs. Anyone can help me on this? I only attach the makefile change here: Index: Makefile.in =================================================================== RCS file: /cvs/src/src/Makefile.in,v retrieving revision 1.244 diff -r1.244 Makefile.in 396a397,401 > @if libdecnumber > HOST_LIB_PATH_libdecnumber = \ > $$r/$(HOST_SUBDIR)/libdecnumber/.libs:$$r/$(HOST_SUBDIR)/prev-libdecnumber/.libs: > @endif libdecnumber > Regards - Wu Zhou On Thu, 22 Jun 2006, Wu Zhou wrote: > Hello Daniel/all, > > About one week ago, I said that I will rework my dfp patch based on libdecnumber. > OK. Here it is. This post is about what it can support right now. The > testcase can tell easily about this. The gdb patch will be posted in > another email. > > The functions this patch provides are much the same as before. But it is > more exensible because it is based on libdecnumber. I list here what is > available now. If you think any functionality is desirable, please tell > me. I will try to add them in. > > - for dfp constants, this patch supports two kind of representation: > scientific one and non-scientific one. To input any dfp constants, you > need to add suffix to differentiate it from binary float: "df" for deciaml > float (32 bits), "dd" for deciaml double (64 bits), and "dl" for deciaml > long (128 bits). When printing dfp constants, it will strip the suffix. > > - it supports the displaying of dfp values in variables, struct, function > argument and also back trace. Any more is needed? > > - it support the negation operation (-dfp), assign operation (d1 = d2 or > d1 = -d2), > > - it can handle finite dfp numbers, infinity (positive and negative), and > NaN (not a number). > > - it can also support the max, normalized min and subnormalized min well. > > - we can't do conversion between binary float and decimal float right, or > between two different dfp types right now > > Here goes the testcase. Please review. Any comment or suggestion is > highly appreciated. > > P.S: I am trying to make it self explanatory. But if you think more > comment is needed in some place, feel free to tell me. > > 2006-06-21 Wu Zhou > > * gdb.base/dfp-exprs.exp: New testcase to verify that gdb can > handle dfp constants correctly. > * gdb.base/dfp-test.c: New test file, used for dfp-test.exp. > * gdb.base/dfp-test.exp: New testcase toverify that gdb can handle > dfp related operation. > > Index: gdb.base/dfp-exprs.exp > =================================================================== > RCS file: gdb.base/dfp-exprs.exp > diff -N gdb.base/dfp-exprs.exp > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb.base/dfp-exprs.exp 21 Jun 2006 21:00:23 -0000 > @@ -0,0 +1,88 @@ > +# Copyright (C) 2005 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program; if not, write to the Free Software > +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + > +# This file was written by Wu Zhou. (woodzltc@cn.ibm.com) > + > +# This file is part of the gdb testsuite. It contains test for evaluating > +# simple decimal floating point (DFP) expression. > + > +if $tracelevel then { > + strace $tracelevel > +} > + > +proc test_dfp_literals_accepted {} { > + > + # Test various dfp values, covering 32-bit, 64-bit and 128-bit ones > + > + # _Decimal32 constants, which can support up to 7 digits > + gdb_test "p 1.2df" " = 1.2" > + gdb_test "p -1.2df" " = -1.2" > + gdb_test "p 1.234567df" " = 1.234567" > + gdb_test "p -1.234567df" " = -1.234567" > + gdb_test "p 1234567.df" " = 1234567" > + gdb_test "p -1234567.df" " = -1234567" > + > + gdb_test "p 1.2E1df" " = 12" > + gdb_test "p 1.2E10df" " = 1.2E\\+10" > + gdb_test "p 1.2E-10df" " = 1.2E-10" > + > + # The largest exponent for 32-bit dfp value is 96. > + gdb_test "p 1.2E96df" " = 1.200000E\\+96" > + > + # _Decimal64 constants, which can support up to 16 digits > + gdb_test "p 1.2dd" " = 1.2" > + gdb_test "p -1.2dd" " = -1.2" > + gdb_test "p 1.234567890123456dd" " = 1.234567890123456" > + gdb_test "p -1.234567890123456dd" " = -1.234567890123456" > + gdb_test "p 1234567890123456.dd" " = 1234567890123456" > + gdb_test "p -1234567890123456.dd" " = -1234567890123456" > + > + gdb_test "p 1.2E1dd" " = 12" > + gdb_test "p 1.2E10dd" " = 1.2E\\+10" > + gdb_test "p 1.2E-10dd" " = 1.2E-10" > + > + # The largest exponent for 64-bit dfp value is 384. > + gdb_test "p 1.2E384dd" " = 1.200000000000000E\\+384" > + > + # _Decimal128 constants, which can support up to 34 digits > + gdb_test "p 1.2dl" " = 1.2" > + gdb_test "p -1.2dl" " = -1.2" > + gdb_test "p 1.234567890123456789012345678901234dl" " = 1.234567890123456789012345678901234" > + gdb_test "p -1.234567890123456789012345678901234dl" " = -1.234567890123456789012345678901234" > + gdb_test "p 1234567890123456789012345678901234.dl" " = 1234567890123456789012345678901234" > + gdb_test "p -1234567890123456789012345678901234.dl" " = -1234567890123456789012345678901234" > + > + gdb_test "p 1.2E1dl" " = 12" > + gdb_test "p 1.2E10dl" " = 1.2E\\+10" > + gdb_test "p 1.2E-10dl" " = 1.2E-10" > + > + # The largest exponent for 128-bit dfp value is 6144. > + gdb_test "p 1.2E6144dl" " = 1.200000000000000000000000000000000E\\+6144" > +} > + > +proc test_arithmetic_expressions {} { > + > +# Arithmetic operations for DFP types are not yet implemented in GDB. > + > +} > + > +# Start with a fresh gdb. > + > +gdb_exit > +gdb_start > +gdb_reinitialize_dir $srcdir/$subdir > + > +test_dfp_literals_accepted > Index: gdb.base/dfp-test.c > =================================================================== > RCS file: gdb.base/dfp-test.c > diff -N gdb.base/dfp-test.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb.base/dfp-test.c 21 Jun 2006 21:00:23 -0000 > @@ -0,0 +1,95 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2006 Free Software Foundation, Inc. > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 2 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + 02111-1307, USA. */ > + > +#include > +#include > + > +volatile _Decimal32 d32; > +volatile _Decimal64 d64; > +volatile _Decimal128 d128; > + > +struct decstruct > +{ > + int int4; > + long long8; > + _Decimal32 dec32; > + _Decimal64 dec64; > + _Decimal128 dec128; > +} ds; > + > +static _Decimal32 > +arg0_32 (_Decimal32 arg0, _Decimal32 arg1, _Decimal32 arg2, > + _Decimal32 arg3, _Decimal32 arg4, _Decimal32 arg5) > +{ > + return arg0; > +} > + > +static _Decimal64 > +arg0_64 (_Decimal64 arg0, _Decimal64 arg1, _Decimal64 arg2, > + _Decimal64 arg3, _Decimal64 arg4, _Decimal64 arg5) > +{ > + return arg0; > +} > + > +static _Decimal128 > +arg0_128 (_Decimal128 arg0, _Decimal128 arg1, _Decimal128 arg2, > + _Decimal128 arg3, _Decimal128 arg4, _Decimal128 arg5) > +{ > + return arg0; > +} > + > +int main() > +{ > + /* An finite 32-bits decimal floating point. */ > + d32 = 1.2345df; /* Initialize d32. */ > + > + /* Non-finite 32-bits decimal floating point: infinity and NaN. */ > + d32 = __builtin_infd32(); /* Positive infd32. */ > + d32 = -__builtin_infd32(); /* Negative infd32. */ > + d32 = __builtin_nand32(""); > + > + /* An finite 64-bits decimal floating point. */ > + d64 = 1.2345dd; /* Initialize d64. */ > + > + /* Non-finite 64-bits decimal floating point: infinity and NaN. */ > + d64 = __builtin_infd64(); /* Positive infd64. */ > + d64 = -__builtin_infd64(); /* Negative infd64. */ > + d64 = __builtin_nand64(""); > + > + /* An finite 128-bits decimal floating point. */ > + d128 = 1.2345dl; /* Initialize d128. */ > + > + /* Non-finite 128-bits decimal floating point: infinity and NaN. */ > + d128 = __builtin_infd128(); /* Positive infd128. */ > + d128 = -__builtin_infd128(); /* Negative infd128. */ > + d128 = __builtin_nand128(""); > + > + /* Functions with decimal floating point as parameter and return value. */ > + d32 = arg0_32 (0.1df, 1.0df, 2.0df, 3.0df, 4.0df, 5.0df); > + d64 = arg0_64 (0.1dd, 1.0dd, 2.0dd, 3.0dd, 4.0dd, 5.0dd); > + d128 = arg0_128 (0.1dl, 1.0dl, 2.0dl, 3.0dl, 4.0dl, 5.0dl); > + > + ds.int4 = 1; > + ds.long8 = 2; > + ds.dec32 = 1.2345df; > + ds.dec64 = 1.2345dd; > + ds.dec128 = 1.2345dl; > + > + return 0; /* Exit point. */ > +} > Index: gdb.base/dfp-test.exp > =================================================================== > RCS file: gdb.base/dfp-test.exp > diff -N gdb.base/dfp-test.exp > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb.base/dfp-test.exp 21 Jun 2006 21:00:23 -0000 > @@ -0,0 +1,247 @@ > +# Copyright 2005 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program; if not, write to the Free Software > +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + > +# This file was written by Wu Zhou. (woodzltc@cn.ibm.com) > + > +# This file is part of the gdb testsuite. It is intended to test that > +# gdb could correctly hane decimal floating point introduced in IEEE 754R. > + > +proc d32_set_tests {} { > + > + gdb_test "p d32=123.45df" " = 123.45" > + gdb_test "p d32=12345.df" " = 12345" > + gdb_test "p d32=12345.67df" " = 12345.67" > + gdb_test "p d32=1234567.df" " = 1234567" > + > + gdb_test "p d32=1.234567E0df" " = 1.234567" > + gdb_test "p d32=1.234567E10df" " = 1.234567E\\+10" > + gdb_test "p d32=1.234567E+96df" " = 1.234567E\\+96" > + > + # Test that gdb could handle the max, normalized min and subnormalized min. > + gdb_test "p d32=9.999999E96df" " = 9.999999E\\+96" > + gdb_test "p d32=1.0E-95df" " = 1.0E\\-95" > + gdb_test "p d32=1.E-101df" " = 1E\\-101" > + gdb_test "p d32=0.000001E-95df" " = 1E\\-101" > + > + # Test that gdb could detect coefficient/exponent out of range. > + # The coefficient out of range will be rounded to its nearest value. > + # And the exponent out of range will be handled as infinity. > + gdb_test "p d32=1.2345678df" " = 1.234568" "1.2345678 is rounded to 1.234568" > + gdb_test "p d32=1.0E-101df" " = 1E-101" "1.0E-101 is rounded to 1E-101" > + gdb_test "p d32=1.234567E+97df" " = Infinity" "1.234567E+97 is Infinity" > + > + # Test that gdb could detect the errors in the string representation of _Decimal32 > + gdb_test "p d32=12345.df" " = 12345" "12345. is an valid number" > + gdb_test "p d32=12345df" ".*Invalid number.*" "12345 is an invalid number" > + gdb_test "p d32=1.23Edf" " = NaN" "1.23E is NaN (not a number)" > + gdb_test "p d32=1.23E45Adf" " = NaN" "1.23E45A is NaN (not a number)" > +} > + > +proc d64_set_tests {} { > + > + gdb_test "p d64=123.45dd" " = 123.45" > + gdb_test "p d64=12345.dd" " = 12345" > + gdb_test "p d64=12345.67dd" " = 12345.67" > + gdb_test "p d64=1.234567890123456dd" " = 1.234567890123456" > + > + gdb_test "p d64=1.234567890123456E10dd" " = 12345678901.23456" > + gdb_test "p d64=1.234567890123456E100dd" " = 1.234567890123456E\\+100" > + gdb_test "p d64=1.234567890123456E384dd" " = 1.234567890123456E\\+384" > + > + # Test that gdb could handle the max, normalized min and subnormalized min. > + gdb_test "p d64=9.999999999999999E384dd" " = 9.999999999999999E\\+384" > + gdb_test "p d64=1.E-383dd" " = 1E\\-383" > + gdb_test "p d64=1.E-398dd" " = 1E\\-398" > + gdb_test "p d64=0.000000000000001E-383dd" " = 1E\\-398" > + > + # Test that gdb could detect coefficient/exponent out of range. > + # The coefficient out of range will be rounded to its nearest value. > + # And the exponent out of range will be handled as infinity. > + gdb_test "p d64=1.2345678901234567dd" " = 1.234567890123457" "1.2345678901234567 is rounded to 1.234567890123457" > + gdb_test "p d64=9.9999999999999999E384dd" " = Infinity" "d64=9.9999999999999999E384 is Infinity" > + gdb_test "p d64=1.234567890123456E385dd" " = Infinity" "d64=1.234567890123456E385 is Infinity" > + > + # Test that gdb could detect the errors in the string representation of _Decimal64 > + gdb_test "p d64=12345dd" ".*Invalid number.*" "12345dd is an invalid number" > + gdb_test "p d64=1.23Edd" " = NaN" "1.23E is NaN (not a number)" > + gdb_test "p d64=1.23E45Add" "= NaN" "1.23E45A is NaN (not a number)" > +} > + > +proc d128_set_tests {} { > + > + gdb_test "p d128=123.45dl" " = 123.45" > + gdb_test "p d128=12345.dl" " = 12345" > + gdb_test "p d128=12345.67dl" " = 12345.67" > + gdb_test "p d128=1.234567890123456789012345678901234dl" " = 1.234567890123456789012345678901234" > + > + gdb_test "p d128=1.234567890123456E10dl" " = 12345678901.23456" > + gdb_test "p d128=1.234567890123456E100dl" " = 1.234567890123456E\\+100" > + gdb_test "p d128=1.234567890123456E1000dl" " = 1.234567890123456E\\+1000" > + > + # Test that gdb could handle the max, normalized min and subnormalized min. > + gdb_test "p d128=9.999999999999999999999999999999999E6144dl" " = 9.999999999999999999999999999999999E\\+6144" > + gdb_test "p d128=1.E-6143dl" " = 1E\\-6143" > + gdb_test "p d128=1.E-6176dl" " = 1E\\-6176" > + gdb_test "p d128=0.000000000000000000000000000000001E-6143dl" " = 1E\\-6176" > + > + # Test that gdb could detect coefficient/exponent out of range. > + # The coefficient out of range will be rounded to its nearest value. > + # And the exponent out of range will be handled as infinity. > + gdb_test "p d128=1.2345678901234567890123456789012345dl" "1.234567890123456789012345678901234" "1.2345678901234567890123456789012345 is rounded to 1.234567890123456789012345678901234" > + gdb_test "p d128=1.234567890123456E6145dl" "Infinity" "d128=1.234567890123456E6145 is Infinity" > + > + # Test that gdb could detect the errors in the string representation of _Decimal128 > + gdb_test "p d128=12345dl" ".*Invalid number.*" "12345dl is an invalid number" > + gdb_test "p d128=1.23Edl" " = NaN" "1.23E is NaN (not a number)" > + gdb_test "p d128=1.23E45Adl" "= NaN" "1.23E45A is NaN (not a number)" > +} > + > + > +if $tracelevel { > + strace $tracelevel > +} > + > +set testfile "dfp-test" > +set srcfile ${testfile}.c > +set binfile ${objdir}/${subdir}/${testfile} > +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { > + untested "Couldn't compile ${srcfile}" > + return -1 > +} > + > +gdb_exit > +gdb_start > +gdb_reinitialize_dir $srcdir/$subdir > +gdb_load ${binfile} > + > +if ![runto_main] then { > + perror "couldn't run to breakpoint" > + continue > +} > + > +# Different tests on 32-bits decimal floating point, including the printing > +# of finite numbers, infinite and NaN, and also the setting of different > +# decimal value. > + > +if [gdb_test "next" \ > + ".*Positive infd32.*" \ > + "next after initializing d32"] then { gdb_suppress_tests } > +gdb_test "print d32" "1.2345" "d32 is initialized to 1.2345" > + > +if [gdb_test "next" \ > + ".*Negative infd32.*" \ > + "next after assigning builtin infinity to d32"] then { gdb_suppress_tests } > +gdb_test "print d32" "Infinity" "d32 is positive Infinity" > + > +if [gdb_test "next" \ > + ".*__builtin_nand32.*" \ > + "next after assigning negative builtin infinity to d32"] then { gdb_suppress_tests } > +gdb_test "print d32" "-Infinity" "d32 is negative Infinity" > + > +if [gdb_test "next" \ > + ".*d64 = 1.2345.*" \ > + "next after assigning builtin NaN to d32"] then { gdb_suppress_tests } > +gdb_test "print d32" "NaN" "d32 is NaN" > + > +d32_set_tests > + > + > +# Different tests on 64-bits decimal floating point, including the display > +# of finite number, infinite and NaN, and also the setting of different > +# decimal value. > + > +if [gdb_test "next" \ > + ".*Positive infd64.*" \ > + "next after initializing d64"] then { gdb_suppress_tests } > +gdb_test "print d64" "1.2345" "d64 is initialized to 1.2345" > + > +if [gdb_test "next" \ > + ".*Negative infd64.*" \ > + "next after assigning builtin infinity to d64"] then { gdb_suppress_tests } > +gdb_test "print d64" "Infinity" "d64 is positive Infinity" > + > +if [gdb_test "next" \ > + ".*__builtin_nand64.*" \ > + "next after assigning negative builtin infinity to d64"] then { gdb_suppress_tests } > +gdb_test "print d64" "-Infinity" "d64 is negative Infinity" > + > +if [gdb_test "next" \ > + ".*d128 = 1.2345.*" \ > + "next after assigning builtin NaN to d64"] then { gdb_suppress_tests } > +gdb_test "print d64" "NaN" "d64 is NaN" > + > +d64_set_tests > + > + > +# Different tests on 128-bits decimal floating point, including the display > +# of finite number, infinite and NaN, and also the setting of different > +# decimal value. > + > +if [gdb_test "next" \ > + ".*Positive infd128.*" \ > + "next after initializing d128"] then { gdb_suppress_tests } > +gdb_test "print d128" "1.2345" "d128 is initialized to 1.2345" > + > +d128_set_tests > + > +if [gdb_test "next" \ > + ".*Negative infd128.*" \ > + "next after assigning builtin infinity to d128"] then { gdb_suppress_tests } > +gdb_test "print d128" "Infinity" "d128 is positive Infinity" > + > +if [gdb_test "next" \ > + ".*__builtin_nand128.*" \ > + "next after assigning negative builtin infinity to d128"] then { gdb_suppress_tests } > +gdb_test "print d128" "-Infinity" "d128 is negative Infinity" > + > +if [gdb_test "next" \ > + ".*arg0_32.*" \ > + "next after assigning builtin NaN to d128"] then { gdb_suppress_tests } > +gdb_test "print d128" "NaN" "d128 is NaN" > + > +# The following tests are intended to verify that gdb can correctly handle > +# DFP types in function arguments. > + > +gdb_breakpoint arg0_32 > +gdb_continue_to_breakpoint "entry to arg0_32" > +gdb_test "backtrace" ".*arg0_32 \\(arg0=0.1, arg1=1.0, arg2=2.0, arg3=3.0, arg4=4.0, arg5=5.0\\).*" "backtrace at arg0_32" > + > +gdb_breakpoint arg0_64 > +gdb_continue_to_breakpoint "entry to arg0_64" > +gdb_test "backtrace" ".*arg0_64 \\(arg0=0.1, arg1=1.0, arg2=2.0, arg3=3.0, arg4=4.0, arg5=5.0\\).*" "backtrace at arg0_64" > + > +gdb_breakpoint arg0_128 > +gdb_continue_to_breakpoint "entry to arg0_128" > +gdb_test "backtrace" ".*arg0_128 \\(arg0=0.1, arg1=1.0, arg2=2.0, arg3=3.0, arg4=4.0, arg5=5.0\\).*" "backtrace at arg0_128" > + > +# The following tests are intended to verify that gdb can handle DFP types > +# correctly in struct. > + > +gdb_breakpoint [gdb_get_line_number "Exit point"] > +gdb_continue_to_breakpoint "Setting a decimal struct" > +gdb_test "print ds.dec32" " = 1.2345" > +gdb_test "print ds.dec64" " = 1.2345" > +gdb_test "print ds.dec128" " = 1.2345" > + > +# The following tests are intended to verify that gdb can handle "d1=d2" > +# and "d1=-d2" correctly. > + > +gdb_test "print ds.dec32=d32" " = 0.1" > +gdb_test "print ds.dec64=d64" " = 0.1" > +gdb_test "print ds.dec128=d128" " = 0.1" > +gdb_test "print ds.dec32 = -d32" " = -0.1" > +gdb_test "print ds.dec64 = -d64" " = -0.1" > +gdb_test "print ds.dec128 = -d128" " = -0.1" > > > Regards > - Wu Zhou >