This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Decimal Floating Point support for GDB (Part 1: patch -Rewrited)


Hi Daniel,

I had rewrited the dfp patch using the method we discussed in this thread.  
Most the problems you mentioned is gone with this new patch now, (you can 
see that in the following testcase patch). It can work with DFP constants 
without a running program, won't print DFP constant as string any more.  
It can handle assigning statement "dfp1=dfp2" besides normal DFP value 
setting.  It could also handle negative operation on DFP values.  

However, it can't handle any other arithmetic operation at this time.  It 
can't handle DFP conversion (explicitly or implicitly) either.  I am now 
reluctant to do that.  But I think the current code is more extensible 
than before if we need to add these feature.

Appended is the patch.  It is tested with the latest dfp-branch gcc on x86 
with "-msse" option.  All the dfp testcases (will post in another mail) 
passed.  And don't see any regression failure on other testcases.  Please 
review and comment.  Thanks a lot.

2005-10-18  Wu Zhou  <woodzltc@cn.ibm.com>

	* 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.
	* parse.c (write_exp_elt_decdblcst): New function.  Called by
	c-exp.y.
	(operator_length_standard): Set operator length for OP_DECDOUBLE.
	* 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.
	(_initialize_gdbtypes): FIXME.  Don't know what it does for.  
	Maybe it is not needed?
	* 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.
	* Makefile.in: Add dfp.h and dfp.c.
	
Index: c-exp.y
===================================================================
RCS file: /cvs/src/src/gdb/c-exp.y,v
retrieving revision 1.30
diff -c -3 -p -r1.30 c-exp.y
*** c-exp.y	20 Sep 2005 08:55:55 -0000	1.30
--- c-exp.y	18 Oct 2005 08:18:32 -0000
*************** Foundation, Inc., 59 Temple Place - Suit
*** 52,57 ****
--- 52,58 ----
  #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
*************** void yyerror (char *);
*** 130,135 ****
--- 131,140 ----
        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;
*************** static int parse_number (char *, int, in
*** 162,167 ****
--- 167,173 ----
  
  %token <typed_val_int> INT
  %token <typed_val_float> FLOAT
+ %token <typed_val_decfloat> DECFLOAT
  
  /* Both NAME and TYPENAME tokens represent symbols in the input,
     and both convey their data as strings.
*************** exp	:	FLOAT
*** 496,501 ****
--- 502,514 ----
  			  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
  	;
  
*************** parse_number (p, len, parsed_float, puti
*** 1080,1085 ****
--- 1093,1131 ----
  
        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')
+ 	{
+ 	  p[len - 2] = '\0';
+ 	  putithere->typed_val_decfloat.type = 
+ 	    builtin_type (current_gdbarch)->builtin_decfloat;
+ 	  decimal_from_string (putithere->typed_val_decfloat.val, 4, p);
+ 	  p[len] = saved_char;
+ 	  return (DECFLOAT);
+ 	}
+ 
+       if (p[len - 2] == 'd' && p[len - 1] == 'd')
+ 	{
+ 	  p[len - 2] = '\0';
+ 	  putithere->typed_val_decfloat.type = 
+ 	    builtin_type (current_gdbarch)->builtin_decdouble;
+ 	  decimal_from_string (putithere->typed_val_decfloat.val, 8, p);
+ 	  p[len] = saved_char;
+ 	  return (DECFLOAT);
+ 	}
+ 
+       if (p[len - 2] == 'd' && p[len - 1] == 'l')
+ 	{
+ 	  p[len - 2] = '\0';
+ 	  putithere->typed_val_decfloat.type = 
+ 	    builtin_type (current_gdbarch)->builtin_declong;
+ 	  decimal_from_string (putithere->typed_val_decfloat.val, 16, p);
+ 	  p[len] = saved_char;
+ 	  return (DECFLOAT);
+ 	}
+ 
        if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
  	num = sscanf (p, "%g%s", (float *) &putithere->typed_val_float.dval,s);
        else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
Index: c-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/c-lang.c,v
retrieving revision 1.38
diff -c -3 -p -r1.38 c-lang.c
*** c-lang.c	3 Oct 2005 21:21:20 -0000	1.38
--- c-lang.c	18 Oct 2005 08:18:35 -0000
*************** c_create_fundamental_type (struct objfil
*** 322,327 ****
--- 322,342 ----
  			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.37
diff -c -3 -p -r1.37 c-valprint.c
*** c-valprint.c	9 May 2005 21:20:30 -0000	1.37
--- c-valprint.c	18 Oct 2005 08:18:37 -0000
*************** c_val_print (struct type *type, const gd
*** 435,440 ****
--- 435,451 ----
  	}
        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.183
diff -c -3 -p -r1.183 dwarf2read.c
*** dwarf2read.c	1 Aug 2005 04:06:27 -0000	1.183
--- dwarf2read.c	18 Oct 2005 08:19:27 -0000
*************** read_base_type (struct die_info *die, st
*** 4704,4709 ****
--- 4704,4712 ----
  	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;
*************** dwarf_base_type (int encoding, int size,
*** 7408,7413 ****
--- 7411,7424 ----
  	  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.59
diff -c -3 -p -r1.59 eval.c
*** eval.c	20 Sep 2005 06:25:34 -0000	1.59
--- eval.c	18 Oct 2005 08:19:43 -0000
*************** evaluate_subexp_standard (struct type *e
*** 447,452 ****
--- 447,457 ----
        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: expression.h
===================================================================
RCS file: /cvs/src/src/gdb/expression.h,v
retrieving revision 1.17
diff -c -3 -p -r1.17 expression.h
*** expression.h	20 Sep 2005 06:31:59 -0000	1.17
--- expression.h	18 Oct 2005 08:19:45 -0000
*************** enum exp_opcode
*** 327,332 ****
--- 327,337 ----
      /* 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 
*************** union exp_element
*** 354,359 ****
--- 359,365 ----
      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: gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.101
diff -c -3 -p -r1.101 gdbtypes.c
*** gdbtypes.c	27 Jun 2005 08:38:13 -0000	1.101
--- gdbtypes.c	18 Oct 2005 08:20:03 -0000
*************** struct type *builtin_type_int128;
*** 73,78 ****
--- 73,84 ----
  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;
*************** build_gdbtypes (void)
*** 3197,3202 ****
--- 3203,3223 ----
  #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,
*************** gdbtypes_post_init (struct gdbarch *gdba
*** 3422,3427 ****
--- 3443,3463 ----
  	       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
*************** _initialize_gdbtypes (void)
*** 3560,3565 ****
--- 3596,3604 ----
    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: gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.62
diff -c -3 -p -r1.62 gdbtypes.h
*** gdbtypes.h	6 Apr 2005 17:01:25 -0000	1.62
--- gdbtypes.h	18 Oct 2005 08:20:14 -0000
*************** struct block;
*** 65,71 ****
  #define FT_UNSIGNED_BYTE	27
  #define FT_TEMPLATE_ARG		28
  
! #define FT_NUM_MEMBERS		29	/* Highest FT_* above, plus one. */
  
  /* Some macros for char-based bitfields.  */
  
--- 65,76 ----
  #define FT_UNSIGNED_BYTE	27
  #define FT_TEMPLATE_ARG		28
  
! /* 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.  */
  
*************** enum type_code
*** 156,162 ****
      TYPE_CODE_TEMPLATE,		/* C++ template */
      TYPE_CODE_TEMPLATE_ARG,	/* C++ template arg */
  
!     TYPE_CODE_NAMESPACE		/* C++ namespace.  */
    };
  
  /* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
--- 161,169 ----
      TYPE_CODE_TEMPLATE,		/* C++ template */
      TYPE_CODE_TEMPLATE_ARG,	/* C++ template arg */
  
!     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
*************** struct builtin_type
*** 1002,1007 ****
--- 1009,1017 ----
    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.  */
*************** extern struct type *builtin_type_complex
*** 1025,1030 ****
--- 1035,1043 ----
  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: parse.c
===================================================================
RCS file: /cvs/src/src/gdb/parse.c,v
retrieving revision 1.50
diff -c -3 -p -r1.50 parse.c
*** parse.c	20 Sep 2005 06:25:34 -0000	1.50
--- parse.c	18 Oct 2005 08:20:23 -0000
*************** write_exp_elt_dblcst (DOUBLEST expelt)
*** 235,240 ****
--- 235,252 ----
  }
  
  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;
*************** operator_length_standard (struct express
*** 856,861 ****
--- 868,874 ----
  
      case OP_LONG:
      case OP_DOUBLE:
+     case OP_DECDOUBLE:
      case OP_VAR_VALUE:
        oplen = 4;
        break;
Index: valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/valprint.c,v
retrieving revision 1.56
diff -c -3 -p -r1.56 valprint.c
*** valprint.c	10 Oct 2005 01:03:59 -0000	1.56
--- valprint.c	18 Oct 2005 08:20:33 -0000
*************** print_floating (const gdb_byte *valaddr,
*** 464,469 ****
--- 464,481 ----
  }
  
  void
+ print_decimal_floating (const gdb_byte *valaddr, struct type *type,
+ 		struct ui_file *stream)
+ {
+   char decstr[128];
+   unsigned len = TYPE_LENGTH (type);
+ 
+   decimal_to_string (valaddr, len, decstr);
+   fputs_filtered (decstr, stream);
+   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.31
diff -c -3 -p -r1.31 value.c
*** value.c	2 Aug 2005 03:13:50 -0000	1.31
--- value.c	18 Oct 2005 08:20:41 -0000
*************** value_from_double (struct type *type, DO
*** 1534,1539 ****
--- 1534,1562 ----
  }
  
  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);
+ 
+   if (expect_type)
+     {
+       int expect_len = TYPE_LENGTH (expect_type);
+       char decstr[128];
+       int real_len;
+ 
+       decimal_to_string (decbytes, len, decstr);
+       real_len = strlen (decstr);
+       decstr [real_len - 2] = '\0';
+       decimal_from_string (decbytes, expect_len, decstr);
+     }
+ 
+   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.43
diff -c -3 -p -r1.43 valarith.c
*** valarith.c	21 Aug 2005 09:33:11 -0000	1.43
--- valarith.c	18 Oct 2005 08:20:51 -0000
*************** value_neg (struct value *arg1)
*** 1375,1380 ****
--- 1375,1389 ----
  
    type = check_typedef (value_type (arg1));
  
+   if (TYPE_CODE (type) == TYPE_CODE_DECFLT)
+     {
+       struct value *val = allocate_value (result_type);
+       gdb_byte *decbytes = value_contents (arg1);
+       decbytes[0] = decbytes[0] | 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	18 Oct 2005 08:20:51 -0000
***************
*** 0 ****
--- 1,101 ----
+ /* Decimal floating point support for GDB.
+ 
+    Copyright 2005 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 <string.h>
+ #include <stdio.h>
+ #include <stdint.h>
+ 
+ /* The first byte for Infinity, NaN and sNaN.  */
+ #define DECIMAL_Inf     0x78        /* 0 11110 00 Infinity */
+ #define DECIMAL_NaN     0x7c        /* 0 11111 00 NaN */
+ #define DECIMAL_sNaN    0x7e        /* 0 11111 10 sNaN */
+ 
+ /* Parameters for _Decimal32.  */
+ #define DECIMAL32_Pmax   7            // maximum precision (digits)
+ #define DECIMAL32_Emax   96           // maximum adjusted exponent
+ #define DECIMAL32_Emin  -95           // minimum adjusted exponent
+ #define DECIMAL32_Bias   101          // bias for the exponent
+ 
+ /* Parameters for _Decimal64.  */
+ #define DECIMAL64_Pmax   16           // maximum precision (digits)
+ #define DECIMAL64_Emax   384          // maximum adjusted exponent
+ #define DECIMAL64_Emin  -383          // minimum adjusted exponent
+ #define DECIMAL64_Bias   398          // bias for the exponent
+ 
+ /* Parameters for _Decimal128.  */
+ #define DECIMAL128_Pmax   34          // maximum precision (digits)
+ #define DECIMAL128_Emax   6144        // maximum adjusted exponent
+ #define DECIMAL128_Emin  -6143        // minimum adjusted exponent
+ #define DECIMAL128_Bias   6176        // bias for the exponent
+ 
+ /* The parse errors found in the conversion routine from the string to
+    decimal types (decimal_from_string).  */
+ #define SYNTAX_ERROR 		0x00000001
+ #define COEFF_OUTOFRANGE 	0x00000002
+ #define EXP_OUTOFRANGE 		0x00000004
+ #define INVALID_CHAR 		0x00000008
+ #define DIGIT_EXPECTED 		0x00000010
+ 
+ #define X10(i)  (((i) << 1) + ((i) << 3))
+ #define X100(i) (((i) << 2) + ((i) << 5) + ((i) << 6))
+ 
+ /* Get the sign bit, combinator bits, exponent continuation bits of
+    _Decimal32, _Decimal64 and _Decimal128.  */
+ #define decimalGetSign(d)	((unsigned)(d)[0] >> 7)
+ #define decimalGetComb(d)	(((d)[0] & 0x7c) >> 2)
+ #define decimal32GetExpCon(d)	((((d)[0] & 0x03) << 4) | \
+ 				((unsigned)(d)[1] >> 4))
+ #define decimal64GetExpCon(d)	((((d)[0] & 0x03) << 6) | \
+ 				((unsigned)(d)[1] >> 2))
+ #define decimal128GetExpCon(d)	((((d)[0] & 0x03) << 10) | \
+ 				((unsigned)(d)[1] << 2) | \
+ 				((unsigned)(d)[2] >> 6)) 
+ 
+ /* Set the sign bit and combinator bits.  */
+ #define decimalSetSign(d, b) 	{ (d)[0] |= ((unsigned)(b) << 7);	}
+ #define decimalSetComb(d, b) 	{ (d)[0] |= ((unsigned)(b) << 2);	}
+ 
+ /* Set the exponent continuation bits of _Decimal32, _Decimal64 and 
+    _Decimal128.  */
+ #define decimal32SetExpCon(d, e) { (d)[0] |= (uint8_t)((e) >> 4); \
+ 			           (d)[1] |= (uint8_t)(((e) & 0x0F) << 4);  }
+ #define decimal64SetExpCon(d, e) { (d)[0] |= (uint8_t)((e) >> 6); \
+ 				   (d)[1] |= (uint8_t)(((e) & 0x3F) << 2);  }
+ #define decimal128SetExpCon(d, e) { (d)[0] |= (uint8_t)((e) >> 10); \
+ 				    (d)[1] = (uint8_t)(((e) & 0x03FC) >> 2); \
+ 				    (d)[2] |= (uint8_t)(((e) & 0x03) << 6);  } 
+ 
+ /* The conversion from decimal floating point to string, and reverse.  */
+ extern void decimal_to_string (const uint8_t *, int, char *);
+ extern int decimal_from_string (uint8_t *, int, char *);
+ 
+ #endif
Index: dfp.c
===================================================================
RCS file: dfp.c
diff -N dfp.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- dfp.c	18 Oct 2005 08:21:05 -0000
***************
*** 0 ****
--- 1,872 ----
+ /* Decimal floating point support for GDB.
+ 
+    Copyright 2005 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 <ctype.h>
+ 
+ /* The bits composition of decimal32, decimal64 and decimal128.
+    For decimal32: 
+      1 (sign) + 5 (combinator) + 6 (exponent) + 20 (coefficient) = 32 bits
+    For decimal64:
+      1 (sign) + 5 (combinator) + 8 (exponent) + 50 (coefficient) = 64 bits
+    For decimal128:
+      1 (sign) + 5 (combinator) + 12 (exponent) + 110 (coefficient) = 128 bits
+ 
+    For more detailed description, refer to the decimal encoding specification,
+    described in http://www2.hursley.ibm.com/decimal/decbits.html.  */
+ 
+ static const int bits[3][4] = { { 1, 5, 6, 20 },
+ 				{ 1, 5, 8, 50 },
+ 				{ 1, 5, 12, 110 } };
+ 
+ /* The mapping table from Densely Packed Decimal (DPD) to/from Binary.  Refer 
+    to http://www2.hursley.ibm.com/decimal/decbits.html for more detail.  */
+ 
+ const uint16_t DPD2BIN[1024]={    0,    1,    2,    3,    4,    5,    6,    7,
+     8,    9,   80,   81,  800,  801,  880,  881,   10,   11,   12,   13,   14,
+    15,   16,   17,   18,   19,   90,   91,  810,  811,  890,  891,   20,   21,
+    22,   23,   24,   25,   26,   27,   28,   29,   82,   83,  820,  821,  808,
+   809,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   92,   93,
+   830,  831,  818,  819,   40,   41,   42,   43,   44,   45,   46,   47,   48,
+    49,   84,   85,  840,  841,   88,   89,   50,   51,   52,   53,   54,   55,
+    56,   57,   58,   59,   94,   95,  850,  851,   98,   99,   60,   61,   62,
+    63,   64,   65,   66,   67,   68,   69,   86,   87,  860,  861,  888,  889,
+    70,   71,   72,   73,   74,   75,   76,   77,   78,   79,   96,   97,  870,
+   871,  898,  899,  100,  101,  102,  103,  104,  105,  106,  107,  108,  109,
+   180,  181,  900,  901,  980,  981,  110,  111,  112,  113,  114,  115,  116,
+   117,  118,  119,  190,  191,  910,  911,  990,  991,  120,  121,  122,  123,
+   124,  125,  126,  127,  128,  129,  182,  183,  920,  921,  908,  909,  130,
+   131,  132,  133,  134,  135,  136,  137,  138,  139,  192,  193,  930,  931,
+   918,  919,  140,  141,  142,  143,  144,  145,  146,  147,  148,  149,  184,
+   185,  940,  941,  188,  189,  150,  151,  152,  153,  154,  155,  156,  157,
+   158,  159,  194,  195,  950,  951,  198,  199,  160,  161,  162,  163,  164,
+   165,  166,  167,  168,  169,  186,  187,  960,  961,  988,  989,  170,  171,
+   172,  173,  174,  175,  176,  177,  178,  179,  196,  197,  970,  971,  998,
+   999,  200,  201,  202,  203,  204,  205,  206,  207,  208,  209,  280,  281,
+   802,  803,  882,  883,  210,  211,  212,  213,  214,  215,  216,  217,  218,
+   219,  290,  291,  812,  813,  892,  893,  220,  221,  222,  223,  224,  225,
+   226,  227,  228,  229,  282,  283,  822,  823,  828,  829,  230,  231,  232,
+   233,  234,  235,  236,  237,  238,  239,  292,  293,  832,  833,  838,  839,
+   240,  241,  242,  243,  244,  245,  246,  247,  248,  249,  284,  285,  842,
+   843,  288,  289,  250,  251,  252,  253,  254,  255,  256,  257,  258,  259,
+   294,  295,  852,  853,  298,  299,  260,  261,  262,  263,  264,  265,  266,
+   267,  268,  269,  286,  287,  862,  863,  888,  889,  270,  271,  272,  273,
+   274,  275,  276,  277,  278,  279,  296,  297,  872,  873,  898,  899,  300,
+   301,  302,  303,  304,  305,  306,  307,  308,  309,  380,  381,  902,  903,
+   982,  983,  310,  311,  312,  313,  314,  315,  316,  317,  318,  319,  390,
+   391,  912,  913,  992,  993,  320,  321,  322,  323,  324,  325,  326,  327,
+   328,  329,  382,  383,  922,  923,  928,  929,  330,  331,  332,  333,  334,
+   335,  336,  337,  338,  339,  392,  393,  932,  933,  938,  939,  340,  341,
+   342,  343,  344,  345,  346,  347,  348,  349,  384,  385,  942,  943,  388,
+   389,  350,  351,  352,  353,  354,  355,  356,  357,  358,  359,  394,  395,
+   952,  953,  398,  399,  360,  361,  362,  363,  364,  365,  366,  367,  368,
+   369,  386,  387,  962,  963,  988,  989,  370,  371,  372,  373,  374,  375,
+   376,  377,  378,  379,  396,  397,  972,  973,  998,  999,  400,  401,  402,
+   403,  404,  405,  406,  407,  408,  409,  480,  481,  804,  805,  884,  885,
+   410,  411,  412,  413,  414,  415,  416,  417,  418,  419,  490,  491,  814,
+   815,  894,  895,  420,  421,  422,  423,  424,  425,  426,  427,  428,  429,
+   482,  483,  824,  825,  848,  849,  430,  431,  432,  433,  434,  435,  436,
+   437,  438,  439,  492,  493,  834,  835,  858,  859,  440,  441,  442,  443,
+   444,  445,  446,  447,  448,  449,  484,  485,  844,  845,  488,  489,  450,
+   451,  452,  453,  454,  455,  456,  457,  458,  459,  494,  495,  854,  855,
+   498,  499,  460,  461,  462,  463,  464,  465,  466,  467,  468,  469,  486,
+   487,  864,  865,  888,  889,  470,  471,  472,  473,  474,  475,  476,  477,
+   478,  479,  496,  497,  874,  875,  898,  899,  500,  501,  502,  503,  504,
+   505,  506,  507,  508,  509,  580,  581,  904,  905,  984,  985,  510,  511,
+   512,  513,  514,  515,  516,  517,  518,  519,  590,  591,  914,  915,  994,
+   995,  520,  521,  522,  523,  524,  525,  526,  527,  528,  529,  582,  583,
+   924,  925,  948,  949,  530,  531,  532,  533,  534,  535,  536,  537,  538,
+   539,  592,  593,  934,  935,  958,  959,  540,  541,  542,  543,  544,  545,
+   546,  547,  548,  549,  584,  585,  944,  945,  588,  589,  550,  551,  552,
+   553,  554,  555,  556,  557,  558,  559,  594,  595,  954,  955,  598,  599,
+   560,  561,  562,  563,  564,  565,  566,  567,  568,  569,  586,  587,  964,
+   965,  988,  989,  570,  571,  572,  573,  574,  575,  576,  577,  578,  579,
+   596,  597,  974,  975,  998,  999,  600,  601,  602,  603,  604,  605,  606,
+   607,  608,  609,  680,  681,  806,  807,  886,  887,  610,  611,  612,  613,
+   614,  615,  616,  617,  618,  619,  690,  691,  816,  817,  896,  897,  620,
+   621,  622,  623,  624,  625,  626,  627,  628,  629,  682,  683,  826,  827,
+   868,  869,  630,  631,  632,  633,  634,  635,  636,  637,  638,  639,  692,
+   693,  836,  837,  878,  879,  640,  641,  642,  643,  644,  645,  646,  647,
+   648,  649,  684,  685,  846,  847,  688,  689,  650,  651,  652,  653,  654,
+   655,  656,  657,  658,  659,  694,  695,  856,  857,  698,  699,  660,  661,
+   662,  663,  664,  665,  666,  667,  668,  669,  686,  687,  866,  867,  888,
+   889,  670,  671,  672,  673,  674,  675,  676,  677,  678,  679,  696,  697,
+   876,  877,  898,  899,  700,  701,  702,  703,  704,  705,  706,  707,  708,
+   709,  780,  781,  906,  907,  986,  987,  710,  711,  712,  713,  714,  715,
+   716,  717,  718,  719,  790,  791,  916,  917,  996,  997,  720,  721,  722,
+   723,  724,  725,  726,  727,  728,  729,  782,  783,  926,  927,  968,  969,
+   730,  731,  732,  733,  734,  735,  736,  737,  738,  739,  792,  793,  936,
+   937,  978,  979,  740,  741,  742,  743,  744,  745,  746,  747,  748,  749,
+   784,  785,  946,  947,  788,  789,  750,  751,  752,  753,  754,  755,  756,
+   757,  758,  759,  794,  795,  956,  957,  798,  799,  760,  761,  762,  763,
+   764,  765,  766,  767,  768,  769,  786,  787,  966,  967,  988,  989,  770,
+   771,  772,  773,  774,  775,  776,  777,  778,  779,  796,  797,  976,  977,
+   998,  999};
+ 
+ static uint16_t BIN2DPD[1000]={    0,    1,    2,    3,    4,    5,    6,    7,
+     8,    9,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,   32,
+    33,   34,   35,   36,   37,   38,   39,   40,   41,   48,   49,   50,   51,
+    52,   53,   54,   55,   56,   57,   64,   65,   66,   67,   68,   69,   70,
+    71,   72,   73,   80,   81,   82,   83,   84,   85,   86,   87,   88,   89,
+    96,   97,   98,   99,  100,  101,  102,  103,  104,  105,  112,  113,  114,
+   115,  116,  117,  118,  119,  120,  121,   10,   11,   42,   43,   74,   75,
+   106,  107,   78,   79,   26,   27,   58,   59,   90,   91,  122,  123,   94,
+    95,  128,  129,  130,  131,  132,  133,  134,  135,  136,  137,  144,  145,
+   146,  147,  148,  149,  150,  151,  152,  153,  160,  161,  162,  163,  164,
+   165,  166,  167,  168,  169,  176,  177,  178,  179,  180,  181,  182,  183,
+   184,  185,  192,  193,  194,  195,  196,  197,  198,  199,  200,  201,  208,
+   209,  210,  211,  212,  213,  214,  215,  216,  217,  224,  225,  226,  227,
+   228,  229,  230,  231,  232,  233,  240,  241,  242,  243,  244,  245,  246,
+   247,  248,  249,  138,  139,  170,  171,  202,  203,  234,  235,  206,  207,
+   154,  155,  186,  187,  218,  219,  250,  251,  222,  223,  256,  257,  258,
+   259,  260,  261,  262,  263,  264,  265,  272,  273,  274,  275,  276,  277,
+   278,  279,  280,  281,  288,  289,  290,  291,  292,  293,  294,  295,  296,
+   297,  304,  305,  306,  307,  308,  309,  310,  311,  312,  313,  320,  321,
+   322,  323,  324,  325,  326,  327,  328,  329,  336,  337,  338,  339,  340,
+   341,  342,  343,  344,  345,  352,  353,  354,  355,  356,  357,  358,  359,
+   360,  361,  368,  369,  370,  371,  372,  373,  374,  375,  376,  377,  266,
+   267,  298,  299,  330,  331,  362,  363,  334,  335,  282,  283,  314,  315,
+   346,  347,  378,  379,  350,  351,  384,  385,  386,  387,  388,  389,  390,
+   391,  392,  393,  400,  401,  402,  403,  404,  405,  406,  407,  408,  409,
+   416,  417,  418,  419,  420,  421,  422,  423,  424,  425,  432,  433,  434,
+   435,  436,  437,  438,  439,  440,  441,  448,  449,  450,  451,  452,  453,
+   454,  455,  456,  457,  464,  465,  466,  467,  468,  469,  470,  471,  472,
+   473,  480,  481,  482,  483,  484,  485,  486,  487,  488,  489,  496,  497,
+   498,  499,  500,  501,  502,  503,  504,  505,  394,  395,  426,  427,  458,
+   459,  490,  491,  462,  463,  410,  411,  442,  443,  474,  475,  506,  507,
+   478,  479,  512,  513,  514,  515,  516,  517,  518,  519,  520,  521,  528,
+   529,  530,  531,  532,  533,  534,  535,  536,  537,  544,  545,  546,  547,
+   548,  549,  550,  551,  552,  553,  560,  561,  562,  563,  564,  565,  566,
+   567,  568,  569,  576,  577,  578,  579,  580,  581,  582,  583,  584,  585,
+   592,  593,  594,  595,  596,  597,  598,  599,  600,  601,  608,  609,  610,
+   611,  612,  613,  614,  615,  616,  617,  624,  625,  626,  627,  628,  629,
+   630,  631,  632,  633,  522,  523,  554,  555,  586,  587,  618,  619,  590,
+   591,  538,  539,  570,  571,  602,  603,  634,  635,  606,  607,  640,  641,
+   642,  643,  644,  645,  646,  647,  648,  649,  656,  657,  658,  659,  660,
+   661,  662,  663,  664,  665,  672,  673,  674,  675,  676,  677,  678,  679,
+   680,  681,  688,  689,  690,  691,  692,  693,  694,  695,  696,  697,  704,
+   705,  706,  707,  708,  709,  710,  711,  712,  713,  720,  721,  722,  723,
+   724,  725,  726,  727,  728,  729,  736,  737,  738,  739,  740,  741,  742,
+   743,  744,  745,  752,  753,  754,  755,  756,  757,  758,  759,  760,  761,
+   650,  651,  682,  683,  714,  715,  746,  747,  718,  719,  666,  667,  698,
+   699,  730,  731,  762,  763,  734,  735,  768,  769,  770,  771,  772,  773,
+   774,  775,  776,  777,  784,  785,  786,  787,  788,  789,  790,  791,  792,
+   793,  800,  801,  802,  803,  804,  805,  806,  807,  808,  809,  816,  817,
+   818,  819,  820,  821,  822,  823,  824,  825,  832,  833,  834,  835,  836,
+   837,  838,  839,  840,  841,  848,  849,  850,  851,  852,  853,  854,  855,
+   856,  857,  864,  865,  866,  867,  868,  869,  870,  871,  872,  873,  880,
+   881,  882,  883,  884,  885,  886,  887,  888,  889,  778,  779,  810,  811,
+   842,  843,  874,  875,  846,  847,  794,  795,  826,  827,  858,  859,  890,
+   891,  862,  863,  896,  897,  898,  899,  900,  901,  902,  903,  904,  905,
+   912,  913,  914,  915,  916,  917,  918,  919,  920,  921,  928,  929,  930,
+   931,  932,  933,  934,  935,  936,  937,  944,  945,  946,  947,  948,  949,
+   950,  951,  952,  953,  960,  961,  962,  963,  964,  965,  966,  967,  968,
+   969,  976,  977,  978,  979,  980,  981,  982,  983,  984,  985,  992,  993,
+   994,  995,  996,  997,  998,  999, 1000, 1001, 1008, 1009, 1010, 1011, 1012,
+  1013, 1014, 1015, 1016, 1017,  906,  907,  938,  939,  970,  971, 1002, 1003,
+   974,  975,  922,  923,  954,  955,  986,  987, 1018, 1019,  990,  991,   12,
+    13,  268,  269,  524,  525,  780,  781,   46,   47,   28,   29,  284,  285,
+   540,  541,  796,  797,   62,   63,   44,   45,  300,  301,  556,  557,  812,
+   813,  302,  303,   60,   61,  316,  317,  572,  573,  828,  829,  318,  319,
+    76,   77,  332,  333,  588,  589,  844,  845,  558,  559,   92,   93,  348,
+   349,  604,  605,  860,  861,  574,  575,  108,  109,  364,  365,  620,  621,
+   876,  877,  814,  815,  124,  125,  380,  381,  636,  637,  892,  893,  830,
+   831,   14,   15,  270,  271,  526,  527,  782,  783,  110,  111,   30,   31,
+   286,  287,  542,  543,  798,  799,  126,  127,  140,  141,  396,  397,  652,
+   653,  908,  909,  174,  175,  156,  157,  412,  413,  668,  669,  924,  925,
+   190,  191,  172,  173,  428,  429,  684,  685,  940,  941,  430,  431,  188,
+   189,  444,  445,  700,  701,  956,  957,  446,  447,  204,  205,  460,  461,
+   716,  717,  972,  973,  686,  687,  220,  221,  476,  477,  732,  733,  988,
+   989,  702,  703,  236,  237,  492,  493,  748,  749, 1004, 1005,  942,  943,
+   252,  253,  508,  509,  764,  765, 1020, 1021,  958,  959,  142,  143,  398,
+   399,  654,  655,  910,  911,  238,  239,  158,  159,  414,  415,  670,  671,
+   926,  927,  254,  255 };
+ 
+ const uint8_t DPDMOD[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+ const uint8_t POWER[3] = { 100, 10, 1};
+ 
+ static int remove_trailing_zeros (char *, char **);
+ static void string_error (int status, char current);
+ 
+ /* 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)
+ {
+   int i;
+   uint8_t sign = decimalGetSign (dec);	/* The signedness of DEC.  */
+   uint8_t comb = decimalGetComb (dec);	/* Combinator, 5 bits.  */
+   uint8_t top = dec[0] & 0x7f;		/* Top byte, less sign bit.  */
+   int bindex;
+   char dfp_suffix[3];
+   uint8_t msd;		/* The most significant digit of coefficient.  */
+   int16_t exp;		/* Exponent, a signed number.  */
+   uint8_t line, column;
+   char cfirst[128];	/* The first character of coefficient.  */ 
+   char *clast = cfirst; /* The last character of coefficient.  */
+   int start = 0;	/* Found the first non-zero in the coefficient?  */
+   int cdigits;		/* The number of the digits in the coefficient.  */
+ 
+   /* Initialize some length-related data.  */
+   switch (len)
+     {
+     case 4:
+       bindex = 0;
+       strncpy (dfp_suffix, "df", 3);
+       exp = decimal32GetExpCon (dec) - DECIMAL32_Bias;
+       break;
+     case 8:
+       bindex = 1;
+       strncpy (dfp_suffix, "dd", 3);
+       exp = decimal64GetExpCon (dec) - DECIMAL64_Bias;
+       break;
+     case 16:
+       bindex = 2;
+       strncpy (dfp_suffix, "dl", 3);
+       exp = decimal128GetExpCon (dec) - DECIMAL128_Bias;
+       break;
+     default:
+       error ("We don't support decimal number of %d bytes yet.", len);
+     }
+ 
+   if (top >= DECIMAL_sNaN)
+     {
+       if (sign == 1)
+ 	strcpy (s, "-sNaN");
+       else
+ 	strcpy (s, "sNaN");
+       return;
+     }
+ 
+   if (top >= DECIMAL_NaN)
+     {
+       if (sign == 1)
+ 	strcpy (s, "-NaN");
+       else
+ 	strcpy (s, "NaN");
+       return;
+     }
+ 
+   if (top >= DECIMAL_Inf)
+     {
+       if (sign == 1)
+ 	strcpy (s, "-Infinity");
+       else
+ 	strcpy (s, "Infinity");
+       return;
+     }
+ 
+   /* This decimal is a finite number.  We try to get the MSD of the 
+      coefficient and the exponent first.  */
+   if (comb >= 0x18)
+     {
+       msd = 8 + (comb & 0x01);
+       exp += (comb & 0x06) << (bits[bindex][2] - 1);
+     }
+   else
+     {
+       msd = comb & 0x07;
+       exp += (comb & 0x18) << (bits[bindex][2] - 3);
+     }
+ 
+   /* From here on, we will try to get the string representation of the 
+      coefficient.  */
+   if (msd)
+     {
+       /* If MSD is non-zero, add it into coeff and set the start flag.  */
+       sprintf (clast, "%d", msd);
+       clast++;
+       start = 1;
+     }
+ 
+   /* We first get the starting position (line and column) of the coefficient.
+      Then get a group of 10 bits, transfer it to a unsigned short (dpdigits),
+      and get its corresponsing 3-digits representation (bin).  And then we
+      will add it into coeff and advance 10 bits to another group of 
+      10-bits until we get to the end.  In this process, we need to adapt the
+      string representaion of each 3-digits according to its real digit number
+      and the start flag.  */
+   line = (bits[bindex][0] + bits[bindex][1] + bits[bindex][2]) / 8;
+   column = (bits[bindex][0] + bits[bindex][1] + bits[bindex][2]) % 8;
+   for (i = 0; i < bits[bindex][3] / 10; i++)
+     {
+       uint16_t dpdigits = ((dec[line] & DPDMOD [7 - column]) << (2 + column))
+ 			  + (dec[line + 1] >> (6 - column));
+       uint16_t bin = DPD2BIN[dpdigits];
+ 
+       line++;
+       column += 2;
+       if (column == 8)
+ 	{
+ 	  column = 0;
+ 	  line++;
+ 	}
+ 
+       if (bin)
+ 	{
+ 	  if (!start)
+ 	    {
+ 	      sprintf (clast, "%d", bin);
+ 	      if (bin < 10)
+ 		clast += 1;
+ 	      else if (bin < 100)
+ 		clast += 2;
+ 	      else
+ 		clast += 3;
+ 	      start = 1;
+ 	    }
+ 	  else
+ 	    {
+ 	      if (bin < 10)
+ 		sprintf (clast, "00%d", bin);
+ 	      else if (bin < 100)
+ 		sprintf (clast, "0%d", bin);
+ 	      else
+ 		sprintf (clast, "%d", bin);
+ 	      clast += 3;
+ 	    }
+ 	}
+       else
+ 	{
+ 	  if (start)
+ 	    {
+ 	      sprintf(clast, "000");
+ 	      clast += 3;
+ 	    }
+ 	  continue;
+ 	}
+     }
+ 
+   /* If start still equals 0, then DEC is 0.  After adding a trailing '.'
+      and suffix, we can return to calling function at this point.  */
+   if (start == 0)
+     {
+       sprintf(s, "0.%s", dfp_suffix);
+       return;
+     }
+ 
+   exp += remove_trailing_zeros (cfirst, &clast);
+ 
+   /* If exp quals 0, then we already get DEC's string representation.  Add
+      a trailing '.' and suffix, and return.  */
+   if (exp == 0)
+     {
+       if (sign)
+ 	sprintf (s, "-%s.%s", cfirst, dfp_suffix);
+       else
+ 	sprintf (s, "%s.%s", cfirst, dfp_suffix);
+       return;
+     }
+ 
+   cdigits = (int)(clast - cfirst);
+   if (exp > 0  || (exp + cdigits) < -5)
+     {
+       char temps[128];		/* A temp string. */
+       char *c = temps;
+       char *digit;
+ 
+       if (sign)
+ 	{
+ 	  sprintf (c, "-");
+ 	  c++;
+ 	}
+ 
+       exp += cdigits - 1;
+       *c++ = *cfirst;
+       *c++ = '.';
+       for (digit = cfirst + 1; ;c++, digit++)
+ 	{
+ 	  if (digit == clast )
+ 	    break;
+ 	  *c = *digit;
+ 	}
+ 
+       if (exp > 0)
+ 	sprintf (c, "E+%d", exp);
+       else if (exp < 0)
+ 	sprintf (c, "E%d", exp);
+       else
+ 	*c = '\0';
+ 
+       sprintf (s, "%s%s", temps, dfp_suffix);
+     }
+   else
+     {
+       char temps[128];	/* A temp string.  */
+       char *c = temps;
+       char *digit = cfirst;
+ 
+       if (sign)
+         {
+           sprintf (c, "-");
+           c++;
+         }
+ 
+       /* Digits left to dot */
+       if ((cdigits + exp) > 0)
+         {
+           exp = cdigits + exp;
+           for (i = 0; i < exp; i++)
+             *c++ = *digit++;
+           sprintf (c, ".");
+           c++;
+         }
+       else
+         {
+           exp = -(exp + cdigits) + 1;
+           sprintf (c, "0.");
+           c += 2;
+           for (i = 1; i < exp; i++)
+             {
+               sprintf (c,"0");
+               c++;
+             }
+         }
+ 
+       for(;;c++, digit++)
+         {
+           if ( digit == clast )
+             break;
+           *c = *digit;
+         }
+       /* Trail temps with '\0'.  */
+       *c = '\0';
+       sprintf (s, "%s%s",temps, dfp_suffix);
+     }
+   return;
+ }
+ 
+ static int
+ remove_trailing_zeros (char *cfirst, char **pclast)
+ {
+   char *digit = *pclast - 1;
+   int trailing_zeros = 0;
+ 
+   while (digit >= cfirst)
+     if (*digit-- == '0')
+       trailing_zeros++;
+     else
+       break;
+ 
+   *pclast = *pclast - trailing_zeros;
+   **pclast = '\0';
+   return trailing_zeros;
+ }
+ 
+ int
+ decStrEq (const char *str1, const char *str2)
+ {
+   for (;;str1++, str2++)
+     {
+       if (*str1 == *str2)
+ 	{
+ 	  if (*str1 == '\0')
+ 	    break;
+ 	}
+       else
+ 	{
+ 	  if (tolower(*str1) != tolower(*str2))
+ 	    return 0;
+ 	}
+     }
+ 
+   return 1;
+ }
+ 
+ int
+ decimal_from_string (uint8_t *dec, int len, char *string)
+ {
+   int status = 0;
+   int i;
+   int sign = 0;                 /* The signedness of DEC.  */
+   int exp = 0;                  /* Exponent, a signed number.  */
+   int indicator = 0;		/* To indicate the type of the DEC.  */
+   int isZero = 0;               /* Is cofficient 0?  */
+   int lpad, rpad;               /* The number of left or right padding '0'.  */
+   const char *dotchar = NULL;   /* Where dot was found.  */
+   const char *cfirst;           /* The first digit of coefficient.  */
+   const char *clast = NULL;     /* The last digit of coefficient.  */
+   int   d=0;               	/* The count of digits in the coefficient.  */
+ 
+   int bindex;
+   int dfp_pmax, dfp_emax, dfp_emin, dfp_bias;
+ 
+   /* Initializing the dec array and type-related variables.  */
+ 
+   for (i = 0; i < len; i++)
+     dec[i] = 0;
+ 
+   switch (len)
+     {
+     case 4:
+       bindex = 0;
+       dfp_pmax = DECIMAL32_Pmax;
+       dfp_emax = DECIMAL32_Emax;
+       dfp_emin = DECIMAL32_Emin;
+       dfp_bias = DECIMAL32_Bias;
+       break;
+     case 8:
+       bindex = 1;
+       dfp_pmax = DECIMAL64_Pmax;
+       dfp_emax = DECIMAL64_Emax;
+       dfp_emin = DECIMAL64_Emin;
+       dfp_bias = DECIMAL64_Bias;
+       break;
+     case 16:
+       bindex = 2;
+       dfp_pmax = DECIMAL128_Pmax;
+       dfp_emax = DECIMAL128_Emax;
+       dfp_emin = DECIMAL128_Emin;
+       dfp_bias = DECIMAL128_Bias;
+       break;
+     default:
+       error ("There is no decimal floating point of length %d", len);
+     }
+ 
+   do
+     {
+       const char *c = string; 
+ 
+       /* Handle leading '-' or '+'.  */
+       if (*c == '-')
+ 	sign = 1;
+       if (*c == '-' || *c == '+')
+ 	c++;
+ 
+       /* We're at the start of the number.  */
+       cfirst = c;
+       for (;; c++)
+ 	{
+ 	  if (*c >= '0' && *c <= '9')
+ 	    { 
+ 	      /* Test for decimal digit.  */
+ 	      clast = c;
+ 	      d++;			/* Count of real digits.  */
+ 	      continue;			/* Still in decimal part.  */
+ 	    }
+ 	  if (*c != '.')
+ 	     break;			/* Done with decimal part.  */
+ 
+ 	  /* Find another dot, break and report error.  */
+ 	  if (dotchar != NULL)
+ 	    {
+ 	      clast = NULL;
+ 	      break;
+ 	    } 
+ 	  dotchar = c;			/* The offset into decimal part */
+ 	}
+ 
+       /* No decimal digits found, maybe Infinity or NaNs.  */
+       if (clast == NULL)
+ 	{
+ 	  if (decStrEq (c, "Infinity") || decStrEq (c, "Inf"))
+ 	    {
+ 	      indicator = DECIMAL_Inf;
+ 	      break;			/* All done.  */
+ 	    }
+ 	  else
+ 	    { /* A NaN expected. */
+ 	      status = SYNTAX_ERROR;		/* Assume the worst.  */
+ 	      indicator = DECIMAL_NaN;		/* Assume simple NaN.  */
+ 
+ 	      /* If c begins with 's' or 'S', it might be "sNaN".  */
+ 	      if (*c == 's' || *c == 'S')
+ 		{
+ 		  c++;
+ 		  indicator = DECIMAL_sNaN;
+ 		}
+ 	      /* Check caseless "NaN".  */
+ 	      if (!strcasecmp (c, "NaN"))
+ 		c += 3;
+ 	      else
+ 		string_error (INVALID_CHAR, *c);
+ 
+ 	      /* Skip leading 0s.  */
+ 	      for (cfirst = c; *cfirst == '0';)
+ 		cfirst++;
+ 	      if (*cfirst == '\0')
+ 		{ /* "NaN" or "sNaN", maybe with all 0s */
+ 		  status = 0;                   /* It's good.  */
+ 		  break;
+ 		}
+ 
+ 	      /* Something other than 0s; setup clast and d as usual.  */
+ 	      for (c = cfirst;; c++, d++)
+ 		{
+ 		  if (*c < '0' || *c > '9')
+ 		    break; 			/* Test for Arabic digit.  */
+ 		  clast = c;
+ 		}
+ 
+ 	      /* If not all digits, report error and exit.  */
+ 	      if (*c != '\0')
+ 		string_error (INVALID_CHAR, *c);
+ 
+ 	      /* Good; set status to ok.  */
+ 	      status = 0;
+ 	    }
+ 	}
+ 
+       /* If it is not at the end yet, we need to see whether it is the 
+ 	 exponent part.  */
+       if (*c != '\0')
+ 	{
+ 	  int esign = 0;
+ 	  const char *firstexp;	/* The first significant exponent digit.  */
+ 
+ 	  if (*c != 'e' && *c != 'E')
+ 	    string_error (INVALID_CHAR, *c);
+ 
+ 	  /* Found 'e' or 'E', process explicit exponent.  */
+ 	  c++;
+ 	  if (*c == '-')
+ 	    {
+ 	      esign = 1;
+ 	      c++;
+ 	    }
+ 	  else if (*c == '+')
+ 	    c++;
+ 	  
+ 	  if (*c == '\0')
+ 	    string_error (DIGIT_EXPECTED, *(c - 1));
+ 
+ 	  /* Strip insignificant zeros.  */
+ 	  for (; *c == '0' && *(c+1) != '\0';)
+ 	    c++;  
+ 
+ 	  firstexp = c;		/* Save exponent digit place.  */
+ 	  for (; ;c++)
+ 	    {
+ 	      if (*c < '0' || *c > '9')
+ 		break;    /* Not a digit.  */
+ 	      exp = X10 (exp) + (int)*c - (int)'0';
+ 	    }
+ 	  /* If it doesn't end on '\0', report the error.  */
+ 	  if (*c != '\0')
+ 	    string_error (INVALID_CHAR, *c);
+ 
+ 	  if (c - firstexp + 1 > 9)
+ 	    string_error (EXP_OUTOFRANGE, *c);
+ 
+ 	  if (esign)
+ 	    exp = -exp;
+ 	}
+ 
+       /* Handle decimal point... */
+       if (dotchar != NULL && dotchar < clast)
+ 	exp = exp - (clast - dotchar);
+ 
+       /* Strip leading zeros/dot (leave final if all 0's).  */
+       for (c = cfirst; c < clast; c++)
+ 	{
+ 	  if (*c == '0')
+ 	    d--;		/* 0 stripped.  */
+ 	  else if (*c != '.')
+ 	    break;
+ 	  cfirst++;		/* Step past leader.  */
+ 	}
+ 
+       /* Get the count of padding zeros and the value of exponent.  And
+ 	 if there are any out of range, report error.  */
+       rpad = 0;
+       if (d > dfp_pmax)
+ 	string_error (COEFF_OUTOFRANGE, 0);
+       else if (exp < (dfp_emin - dfp_pmax + 1) || exp > (dfp_emax - d +1))
+ 	string_error (EXP_OUTOFRANGE, 0);
+       else if (exp > (dfp_emax - dfp_pmax + 1))
+ 	{
+ 	  rpad += exp - (dfp_emax - dfp_pmax + 1);
+ 	  exp = dfp_emax - dfp_pmax + 1 + dfp_bias;
+ 	  lpad = dfp_pmax - d - rpad; 
+ 	}
+       else
+ 	{
+ 	  lpad = dfp_pmax - d;
+ 	  exp += dfp_bias;
+ 	} 
+ 
+     } while (0);
+ 
+   /* If status non-zero, there must be some error in the input string.  */
+ 
+   if (status)
+     string_error (status, 0);
+ 
+   /* Begin to transfer the string representation to decimal type.  */
+ 
+   if (sign)
+     decimalSetSign (dec, sign);
+ 
+   if (!indicator)
+     { 
+       char cc[128];	/* The string of coefficient continuation.  */
+       char *s = cc;
+       const char *c;
+       uint8_t comb;	/* Combinator, 5 bits.  */
+       uint8_t msd;	/* The most significant digit of coefficient.  */
+       uint8_t line, column;
+  
+       /* It is a finite number, we need to get MSD cofficient first.  */
+       if (lpad > 0)
+ 	{
+ 	  msd = 0;
+ 	  lpad -= 1;
+ 	}
+       else
+ 	{
+ 	  msd = *cfirst - '0';
+ 	  if (cfirst == clast)
+ 	    {
+ 	      cfirst = NULL;
+ 	    }
+ 	  else
+ 	    cfirst++;
+ 	}
+       if (msd == 0)
+ 	isZero = 1;
+ 
+       /* Set combinator bits.  */
+       if (msd >= 8)
+ 	comb = (msd & 0x1) + (((exp >> bits[bindex][2]) & 0x3) << 1) + 0x18;
+       else
+ 	comb = (msd & 0x7 ) + (((exp >> bits[bindex][2]) & 0x3) << 3);
+       decimalSetComb (dec, comb);
+ 
+       /* Set exponent continuation bits.  */
+       if (len == 4)
+ 	{
+ 	  exp &= 0x3F;
+ 	  decimal32SetExpCon (dec, exp);
+ 	}
+       if (len == 8)
+ 	{
+ 	  exp &= 0xFF;
+ 	  decimal64SetExpCon (dec, exp);
+ 	}
+       if (len == 16)
+ 	{
+ 	  exp &= 0x0FFF;
+ 	  decimal128SetExpCon (dec, exp);
+ 	}
+ 
+       /* Get the clean coefficient continuation string first.  */
+ 
+       while (lpad--)
+ 	*s++ = '0';
+ 
+       for (c = cfirst; c != NULL; c++)
+ 	{
+ 	  if (*c == '.')
+ 	    {
+ 	      if (c != clast)
+ 		continue;
+ 
+ 	      break;
+ 	    }
+ 	  *s = *c;
+ 	  s++;
+ 	  if (isZero && (*c != '0'))
+ 	    isZero = 0;
+ 	  if (c == clast)
+ 	    break;
+ 	}
+ 
+       while (rpad--)
+ 	*s++ = '0';
+ 
+       *s = '\0';
+ 
+       /* Then try to set these coefficient continuation bits in the resulting
+ 	 decimal variable.  */
+ 
+       line = (bits[bindex][0] + bits[bindex][1] + bits[bindex][2]) / 8;
+       column = (bits[bindex][0] + bits[bindex][1] + bits[bindex][2]) % 8;
+       s = cc;
+ 
+       for (i = 0; i < bits[bindex][3] / 10; i++)
+         {
+ 	  int j; 
+           uint16_t dpd, bin = 0;
+ 
+ 	  /* Firstly, get bin from cc string.  */
+ 	  for (j = 0; j < 3; j++)
+ 	    {
+ 	      bin += (*s - '0') * POWER[j];
+ 	      s++;
+ 	    }
+ 
+ 	  /* Then, map bin to DPD.  */
+ 	  dpd = BIN2DPD[bin];
+ 
+ 	  /* Last, set dec array using what we just got above.  */
+ 	  dec[line] |= (dpd >> (2+column));
+ 	  dec[line+1] |= ((dpd & DPDMOD[1+column]) << (6-column));
+ 
+ 	  /* Go on to the next 10-bits group.  */
+ 	  line++;
+ 	  column += 2;
+ 	  if (column == 8)
+ 	    {
+ 	      column = 0;
+ 	      line++;
+ 	    }
+ 	}
+     }
+   else
+     { /* It is Inf, sNaN or qNaN.  */ 
+       uint8_t comb;
+ 
+       if (indicator == DECIMAL_Inf)
+ 	{
+ 	  comb = 0x1E;
+ 	  decimalSetComb (dec, comb);
+ 	}
+       else
+ 	{
+ 	  comb = 0x1F;
+ 	  decimalSetComb (dec, comb);
+ 	  if (indicator == DECIMAL_sNaN)
+ 	    dec[0] |= 0x2;
+ 	}
+     }
+ 
+   return status;
+ }
+ 
+ static void
+ string_error (int status, char current)
+ {
+   switch (status)
+     {
+     case COEFF_OUTOFRANGE:
+       error ("The coefficient is out of range.");
+     case EXP_OUTOFRANGE:
+       error ("The exponent is out of range.");
+     case INVALID_CHAR:
+       error ("Invalid char found by dfp, near \'%c\'", current);
+     case DIGIT_EXPECTED:
+       error ("Digit expected, get a non-digit instead, near \'%c\'.", current);
+     case SYNTAX_ERROR:
+       error ("There are syntax error in the above decimal.");
+     }
+ }
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.756
diff -c -3 -p -r1.756 Makefile.in
*** Makefile.in	13 Oct 2005 09:31:59 -0000	1.756
--- Makefile.in	18 Oct 2005 08:22:06 -0000
*************** dictionary_h = dictionary.h
*** 663,668 ****
--- 663,669 ----
  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
*************** COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
*** 896,902 ****
  	auxv.o \
  	bfd-target.o \
  	blockframe.o breakpoint.o findvar.o regcache.o \
! 	charset.o disasm.o dummy-frame.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 \
--- 897,903 ----
  	auxv.o \
  	bfd-target.o \
  	blockframe.o breakpoint.o findvar.o regcache.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 \
*************** dsrec.o: dsrec.c $(defs_h) $(serial_h) $
*** 1883,1888 ****
--- 1884,1890 ----
  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)
  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)
		 

Best Regards
- Wu Zhou


On Wed, 12 Oct 2005, Daniel Jacobowitz wrote:

> On Wed, Oct 12, 2005 at 10:46:22PM +0800, Wu Zhou wrote:
> > > Or just use the decNumber packed representation, in value_contents().
> > > Take a look at all the references to FLOATFORMAT to see how we handle
> > > floating point types.
> > 
> > I did had some looks at FLOATFORMAT, but found that there are quite
> > some difference between DFP encoding format and normal binary floating
> > encoding format: for example, dfp's fields is composed of combinator
> > bits, exponent continuation bits and coefficient continuation bits.  
> > While most bfp floatformat is composed of two fields (exponent bits 
> > and coefficient bits).  And they also have different representation 
> > for non-finite number (infinity and NaN).  
> 
> Yes, sorry - I wasn't suggesting that you define floatformats for
> these, just that you handle them in the same set of places that we
> handle floatformats.
> 
> > So I am now thinking of adding a builtin type other than TYPE_CODE_FLT to
> > represent dfp.  This type (I am thinking of using TYPE_CODE_DECFLT) will 
> > have three fundamental type like TYPE_CODE_FLT for different sizes. In the
> > fields it will have four fields: signedness, combinator, exponent 
> > continuation and coefficient continuation.  And these fields will merged 
> > together into value.aligner.contents.  In this way, we can not only 
> > support the setting and printing of dfp types (constants or variables), 
> > but also can add other feature (such as arithmetic operation) as needed. 
> > 
> > Is there any clear deficiency in this method?  Do you think that it is 
> > feasible? and also extensible?  I will start to code in this direction if 
> > there is not any obvous weakness.
> 
> This may be what you're saying, but the only copy of the data should be
> in value_contents, not duplicated in unpacked form elsewhere.
> 
> Yes, I think introducing a new type code is a good idea; that will be
> more robust than reusing TYPE_CODE_FLT.  There are 230 references to
> TYPE_CODE_FLT in gdb; many of them you'd want to handle DECFLT the same
> way, but many you wouldn't.  For instance, calling functions which take
> decimal floating point arguments.
> 
> -- 
> Daniel Jacobowitz
> CodeSourcery, LLC
> 
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]