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)


Hello all,

Let me firstly introduce some background for this.  

As we all know, most computers today support binary floating-point in 
hardware.  While suitable for many purposes, binary floating-point 
arithmetic has its own shorts, to say, it can't represent float data 
exactly.  This limits its application a little.

Decimal floating point can avoid this by using base 10 (decimal) exponents
and preserving those exponents where possible.  It is now discussed by an IEEE
WG to extend IEEE 754 standard to be incorporate.  And C standard committee is 
also discussing possibility to add it into C99 standard revision.  For 
more detailed description, please refer to: 
http://grouper.ieee.org/groups/754/revision.html,
http://www2.hursley.ibm.com/decimal/ and
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1107.htm.

Ben Elliston is now hosting a project trying to add DFP support into GCC 
in dfp-branch. (For some detail, please refer to
http://gcc.gnu.org/wiki/Decimal%20Floating-Point)

This patch is intended to add decimal floating point (DFP) support into
GDB.  It currently supports the printing and setting of DFP.  And also 
support displaying the dfp types in function argument and backtrace.  
If you think that any other features are also desired, please let me know.  
I will try to see whether it can also be supported.

Here goes the patch (testcase will be posted in another mail). Please 
review and comment, any suggestion, comments and ideas are highly 
appreciated.

2005-9-28  Wu Zhou  <woodzltc@cn.ibm.com>
	
	* gdbtypes.h (TYPE_FLAG_DECIMAL): New flag to indicate that this
	float type is decimal.
	* gdbtypes.h (TYPE_DECIMAL): New predicate to determine whether a
	type is decimal floating point.
	* dwarf2read.c (read_base_type): Read out decimal attribute and set
	type code and decimal flag.
	* dwarf2read.c (dwarf_base_type): Set the dwarf2 fundamental type 
	for different decimal types.
	* dwarf2read.c (dwarf_type_encoding_name): Set the type encoding 
	name for decimal floating point types.
	* c-exp.y (parse_number): Parse the decimal floating point, which 
	has a suffix ('df', 'dd' or 'dl') and return STRING here.
	* eval.c (evaluate_subexp_standard): Call value_set_dfp to set the 
	value of decimal floating point types. 
	* valops.c (value_set_dfp): New function, calling decimal_from_string
	to set the value of decimal floating point types.
	* valprint.c (print_floating): If decimal flag is set, call 
	decimal_to_string to print this floating variable.
	* dfp.h: New header file for decimal floating point support in GDB.
	main functions is decimal_from_string and decimal_to_string.
	* dfp.c: New source file for decimal floating point support in GDB.
	Implement decimal_from_string and decimal_to_strin.
	* Makefile.in: Add dfp.h and dfp.c.

Index: gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.62
diff -c -p -r1.62 gdbtypes.h
*** gdbtypes.h	6 Apr 2005 17:01:25 -0000	1.62
--- gdbtypes.h	28 Sep 2005 04:32:14 -0000
*************** enum type_code
*** 304,309 ****
--- 304,314 ----
  
  #define TYPE_FLAG_FIXED_INSTANCE (1 << 15)
  
+ /* Differentiate decimal floating point from binary floating point types.  */
+ 
+ #define TYPE_FLAG_DECIMAL (1 << 16)
+ #define TYPE_DECIMAL(t) (TYPE_FLAGS (t) & TYPE_FLAG_DECIMAL)
+ 
  /*  Array bound type.  */
  enum array_bound_type
  {
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.183
diff -c -p -r1.183 dwarf2read.c
*** dwarf2read.c	1 Aug 2005 04:06:27 -0000	1.183
--- dwarf2read.c	28 Sep 2005 04:32:43 -0000
*************** read_base_type (struct die_info *die, st
*** 4704,4709 ****
--- 4704,4713 ----
  	case DW_ATE_complex_float:
  	  code = TYPE_CODE_COMPLEX;
  	  break;
+         case DW_ATE_decimal_float:
+           code = TYPE_CODE_FLT;
+           type_flags |= TYPE_FLAG_DECIMAL;
+           break;
  	case DW_ATE_float:
  	  code = TYPE_CODE_FLT;
  	  break;
*************** dwarf_base_type (int encoding, int size,
*** 7408,7413 ****
--- 7412,7425 ----
  	  type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
  	}
        return type;
+     case DW_ATE_decimal_float:
+       if (size == 16)
+ 	type = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT, cu);
+       else if (size == 8)
+ 	type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
+       else
+ 	type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
+       return type;
      case DW_ATE_signed:
        switch (size)
  	{
*************** dwarf_type_encoding_name (unsigned enc)
*** 8248,8253 ****
--- 8260,8267 ----
        return "DW_ATE_boolean";
      case DW_ATE_complex_float:
        return "DW_ATE_complex_float";
+     case DW_ATE_decimal_float:
+       return "DW_ATE_decimal_float";
      case DW_ATE_float:
        return "DW_ATE_float";
      case DW_ATE_signed:
Index: c-exp.y
===================================================================
RCS file: /cvs/src/src/gdb/c-exp.y,v
retrieving revision 1.30
diff -c -p -r1.30 c-exp.y
*** c-exp.y	20 Sep 2005 08:55:55 -0000	1.30
--- c-exp.y	28 Sep 2005 04:32:50 -0000
*************** parse_number (p, len, parsed_float, puti
*** 1080,1085 ****
--- 1080,1096 ----
  
        p[len] = 0;	/* null-terminate the token */
  
+       /* If it ends at "df", "dd" or "dl", take it as type of decimal floating
+          point.  Return STRING for later string-to-dfp conversion.  */
+       if (p[len - 2] == 'd'
+ 	  && (p[len - 1] == 'f' || p[len - 1] == 'd' ||  p[len - 1] == 'l'))
+ 	{
+ 	  p[len - 2] = '\0';
+ 	  yylval.sval.ptr = p;
+ 	  yylval.sval.length = len - 2;
+ 	  return (STRING);
+ 	}
+ 
        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: eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.59
diff -c -p -r1.59 eval.c
*** eval.c	20 Sep 2005 06:25:34 -0000	1.59
--- eval.c	28 Sep 2005 04:32:56 -0000
*************** evaluate_subexp_standard (struct type *e
*** 1456,1461 ****
--- 1456,1471 ----
  
      case BINOP_ASSIGN:
        arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ 
+       /* If the type of arg1 is one of decimal floating point, then call
+ 	 value_set_dfp to assign arg2 to arg1.  */
+       if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_FLT
+ 	  && TYPE_DECIMAL (value_type (arg1)))
+ 	{
+ 	  arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ 	  return value_set_dfp (arg1, arg2);
+ 	}
+ 
        arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
  
        /* Do special stuff for HP aCC pointers to members */
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.161
diff -c -p -r1.161 valops.c
*** valops.c	27 May 2005 04:39:32 -0000	1.161
--- valops.c	28 Sep 2005 04:33:03 -0000
***************
*** 44,49 ****
--- 44,50 ----
  #include "gdb_assert.h"
  #include "cp-support.h"
  #include "observer.h"
+ #include "dfp.h"
  
  extern int overload_debug;
  /* Local functions.  */
*************** value_fetch_lazy (struct value *val)
*** 518,523 ****
--- 519,558 ----
    return 0;
  }
  
+ /* Store the contents of FROMVAL into the location of TOVAL, which is a
+    decimal floating point.  Return a new value with the location of TOVAL
+    and contents of FROMVAL.  */
+ 
+ struct value *
+ value_set_dfp (struct value *toval, struct value *fromval)
+ {
+   struct type *type = value_type (toval);
+   gdb_byte *valaddr = value_contents_raw (toval);
+   char *string = (char *)(value_contents_all (fromval));
+   struct frame_id old_frame;
+   struct frame_info *fi;
+ 
+   /* Since modifying a register can trash the frame chain, and modifying memory
+      can trash the frame cache, we save the old frame and then restore the new
+      frame afterwards.  */
+   old_frame = get_frame_id (deprecated_selected_frame);
+   
+   if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_DECIMAL (type))
+     {
+       unsigned int len = TYPE_LENGTH (type);
+       CORE_ADDR changed_addr = VALUE_ADDRESS (toval) + value_offset (toval);
+ 
+       decimal_from_string (valaddr, len, string);
+       write_memory (changed_addr, valaddr, len);
+     }
+ 
+   reinit_frame_cache ();
+   fi = frame_find_by_id (old_frame);
+   if (fi != NULL)
+     select_frame (fi);
+ 
+   return toval;
+ }
  
  /* Store the contents of FROMVAL into the location of TOVAL.
     Return a new value with the location of TOVAL and contents of FROMVAL.  */
Index: valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/valprint.c,v
retrieving revision 1.54
diff -c -p -r1.54 valprint.c
*** valprint.c	10 Jun 2005 06:07:32 -0000	1.54
--- valprint.c	28 Sep 2005 04:33:05 -0000
***************
*** 34,39 ****
--- 34,40 ----
  #include "valprint.h"
  #include "floatformat.h"
  #include "doublest.h"
+ #include "dfp.h"
  
  #include <errno.h>
  
*************** print_floating (const gdb_byte *valaddr,
*** 400,405 ****
--- 401,415 ----
    const struct floatformat *fmt = NULL;
    unsigned len = TYPE_LENGTH (type);
  
+   if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_DECIMAL (type))
+     {
+       char decstr[100];
+ 
+       decimal_to_string (valaddr, len, decstr);
+       fputs_filtered (decstr, stream);
+       return;
+     }
+ 
    /* If it is a floating-point, check for obvious problems.  */
    if (TYPE_CODE (type) == TYPE_CODE_FLT)
      fmt = floatformat_from_type (type);
Index: dfp.h
===================================================================
RCS file: dfp.h
diff -N dfp.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- dfp.h	28 Sep 2005 04:33:05 -0000
***************
*** 0 ****
--- 1,103 ----
+ /* Decimal floating point support for GDB.
+ 
+    Copyright 2005 Free Software Foundation, Inc.
+ 
+    Contributed by Cygnus Support, using pieces from other GDB modules.
+ 
+    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	28 Sep 2005 04:33:09 -0000
***************
*** 0 ****
--- 1,874 ----
+ /* Decimal floating point support for GDB.
+ 
+    Copyright 2005 Free Software Foundation, Inc.
+ 
+    Contributed by Cygnus Support, using pieces from other GDB modules.
+ 
+    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, 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.753
diff -c -p -r1.753 Makefile.in
*** Makefile.in	10 Sep 2005 18:11:01 -0000	1.753
--- Makefile.in	28 Sep 2005 04:33:23 -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) $(YYOBJ) \
*** 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) $
*** 1885,1890 ****
--- 1886,1892 ----
  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)


Regards
- Wu Zhou


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