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 float point patch based on libdecnumber: gdb patch


Appended is the patch.  I had tested it with the latest gcc-4.2 cvs tree 
on x86, with option "--enable-decimal-float". All the 121 tests passed.
Please review and comment.  Thanks a lot.

2006-06-21  Wu Zhou  <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.
	* parser-defs.h (write_exp_elt_decdblcst): Prototype.
	* parse.c (write_exp_elt_decdblcst): New function to write a decimal
	double const into the expression.
	(operator_length_standard): Set operator length for OP_DECDOUBLE 
	to 4.
	* c-exp.y (YYSTYPE): Add typed_val_decfloat for decimal floating 
	point in YYSTYPE union.
	Add token DECFLOAT for typed_val_decfloat.
	Add expression element handling code for DECFLOAT.
	(parse_number): Parse DFP constants, which end with suffix 'df',
	'dd' or 'dl'.  Return DECFLOAT.
	* c-lang.c (c_create_fundamental_type): Create fundamental types
	for DFP.
	* c-valprint.c (c_val_print): Call print_decimal_floating to print
	DFP values.
	* dwarf2read.c (read_base_type): Read DW_ATE_decimal_float attribute
	code and return TYPE_CODE_DECFLT.
	(dwarf_base_type): Set dwarf2_fundamental_type for DFP values.
	* eval.c (evaluate_subexp_standard): Call value_from_decdouble to
	handle OP_DECDOUBLE.
	* gdbtypes.h: Add three fundamental types for DFP.
	(enum type_code): Add TYPE_CODE_DECFLT as a type code for DFP.
	(struct builtin_type): Add builtin_decfloat, builtin_decdouble
	and builtin_declong.
	* gdbtypes.c: Add three builtin types for DFP.
	(build_gdbtypes): Build these three builtin types for DFP.
	(gdbtypes_post_init): Initialize builtin_decfloat, builtin_decdouble
	and builtin_declong.
	* value.h (value_from_decdouble): Prototype.
	(print_decimal_floating): Prototype.
	* valprint.c (print_decimal_floating): New function to print DFP
	values.
	* value.c (value_from_decdouble): New function to get the value
	from a decimal double.
	* valarith.c (value_neg): Add some code to handle the negation
	operation of DFP values.
	* dfp.h: New header file for decimal floating point support in
	GDB.
	* dfp.c: New source file for decimal floating point support in
	GDB.  Implement decimal_from_string and decimal_to_string based
	on libdecnumber API.
	* Makefile.in: Add decimal floating point related entry.  Add
	some macro to specify the libdecnumber directory, cflags and the
	name of libdecnumber library.

Index: expression.h
===================================================================
RCS file: /cvs/src/src/gdb/expression.h,v
retrieving revision 1.18
diff -u -r1.18 expression.h
--- expression.h	17 Dec 2005 22:33:59 -0000	1.18
+++ expression.h	21 Jun 2006 23:08:51 -0000
@@ -327,6 +327,11 @@
     /* A F90 array range operator (for "exp:exp", "exp:", ":exp" and ":").  */
     OP_F90_RANGE,
 
+    /* OP_DECDOUBLE is followed by a type pointer in the next exp_element
+       and a dec long constant value in the following exp_element.
+       Then comes another OP_DECDOUBLE.  */
+    OP_DECDOUBLE,
+
      /* First extension operator.  Individual language modules define
         extra operators they need as constants with values 
         OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate 
@@ -354,6 +359,7 @@
     struct symbol *symbol;
     LONGEST longconst;
     DOUBLEST doubleconst;
+    gdb_byte decdoubleconst[16];
     /* Really sizeof (union exp_element) characters (or less for the last
        element of a string).  */
     char string;
Index: parser-defs.h
===================================================================
RCS file: /cvs/src/src/gdb/parser-defs.h,v
retrieving revision 1.20
diff -u -r1.20 parser-defs.h
--- parser-defs.h	17 Dec 2005 22:34:01 -0000	1.20
+++ parser-defs.h	21 Jun 2006 23:08:51 -0000
@@ -121,6 +121,8 @@
 
 extern void write_exp_elt_dblcst (DOUBLEST);
 
+extern void write_exp_elt_decdblcst (gdb_byte *);
+
 extern void write_exp_elt_type (struct type *);
 
 extern void write_exp_elt_intern (struct internalvar *);
Index: parse.c
===================================================================
RCS file: /cvs/src/src/gdb/parse.c,v
retrieving revision 1.52
diff -u -r1.52 parse.c
--- parse.c	24 Jan 2006 15:20:10 -0000	1.52
+++ parse.c	21 Jun 2006 23:08:51 -0000
@@ -236,6 +236,18 @@
 }
 
 void
+write_exp_elt_decdblcst (gdb_byte expelt[16])
+{
+  union exp_element tmp;
+  int index;
+
+  for (index = 0; index < 16; index++)
+    tmp.decdoubleconst[index] = expelt[index];
+
+  write_exp_elt (tmp);
+}
+
+void
 write_exp_elt_type (struct type *expelt)
 {
   union exp_element tmp;
@@ -857,6 +869,7 @@
 
     case OP_LONG:
     case OP_DOUBLE:
+    case OP_DECDOUBLE:
     case OP_VAR_VALUE:
       oplen = 4;
       break;
Index: c-exp.y
===================================================================
RCS file: /cvs/src/src/gdb/c-exp.y,v
retrieving revision 1.34
diff -u -r1.34 c-exp.y
--- c-exp.y	23 Feb 2006 18:43:41 -0000	1.34
+++ c-exp.y	21 Jun 2006 23:08:51 -0000
@@ -53,6 +53,7 @@
 #include "charset.h"
 #include "block.h"
 #include "cp-support.h"
+#include "dfp.h"
 
 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
    as well as gratuitiously global symbol names, so we can have multiple
@@ -131,6 +132,10 @@
       DOUBLEST dval;
       struct type *type;
     } typed_val_float;
+    struct {
+      gdb_byte val[16];
+      struct type *type;
+    } typed_val_decfloat;
     struct symbol *sym;
     struct type *tval;
     struct stoken sval;
@@ -163,6 +168,7 @@
 
 %token <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.
@@ -497,6 +503,13 @@
 			  write_exp_elt_opcode (OP_DOUBLE); }
 	;
 
+exp	:	DECFLOAT
+			{ write_exp_elt_opcode (OP_DECDOUBLE);
+			  write_exp_elt_type ($1.type);
+			  write_exp_elt_decdblcst ($1.val);
+			  write_exp_elt_opcode (OP_DECDOUBLE); }
+	;
+
 exp	:	variable
 	;
 
@@ -1080,6 +1093,49 @@
       char saved_char = p[len];
 
       p[len] = 0;	/* null-terminate the token */
+
+      /* If it ends at "df", "dd" or "dl", take it as type of decimal floating
+         point.  Return DECFLOAT.  */
+
+      if (p[len - 2] == 'd' && p[len - 1] == 'f')
+	{
+	  gdb_byte *dec_val = (gdb_byte *)malloc (4);
+	  p[len - 2] = '\0';
+	  putithere->typed_val_decfloat.type = 
+	    builtin_type (current_gdbarch)->builtin_decfloat;
+	  decimal_from_string (dec_val, 4, p);
+	  reverse_dfp (dec_val, 4, putithere->typed_val_decfloat.val);
+	  free (dec_val);
+	  p[len] = saved_char;
+	  return (DECFLOAT);
+	}
+
+      if (p[len - 2] == 'd' && p[len - 1] == 'd')
+	{
+	  gdb_byte *dec_val = (gdb_byte *)malloc (8);
+	  p[len - 2] = '\0';
+	  putithere->typed_val_decfloat.type = 
+	    builtin_type (current_gdbarch)->builtin_decdouble;
+	  decimal_from_string (dec_val, 8, p);
+	  reverse_dfp (dec_val, 8, putithere->typed_val_decfloat.val);
+	  free (dec_val);
+	  p[len] = saved_char;
+	  return (DECFLOAT);
+	}
+
+      if (p[len - 2] == 'd' && p[len - 1] == 'l')
+	{
+	  gdb_byte *dec_val = (gdb_byte *)malloc (16);
+	  p[len - 2] = '\0';
+	  putithere->typed_val_decfloat.type = 
+	    builtin_type (current_gdbarch)->builtin_declong;
+	  decimal_from_string (dec_val, 16, p);
+	  reverse_dfp (dec_val, 16, putithere->typed_val_decfloat.val);
+	  free (dec_val);
+	  p[len] = saved_char;
+	  return (DECFLOAT);
+	}
+
       num = sscanf (p, DOUBLEST_SCAN_FORMAT "%s",
 		    &putithere->typed_val_float.dval, s);
       p[len] = saved_char;	/* restore the input stream */
Index: c-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/c-lang.c,v
retrieving revision 1.39
diff -u -r1.39 c-lang.c
--- c-lang.c	17 Dec 2005 22:33:59 -0000	1.39
+++ c-lang.c	21 Jun 2006 23:08:52 -0000
@@ -322,6 +322,21 @@
 			TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
 			0, "long double", objfile);
       break;
+    case FT_DECFLOAT:
+      type = init_type (TYPE_CODE_DECFLT,
+			32 / 8,
+			0, "decimal float", objfile);
+      break;
+    case FT_DBL_PREC_DECFLOAT:
+      type = init_type (TYPE_CODE_DECFLT,
+			64 / 8,
+			0, "decimal double", objfile);
+      break;
+    case FT_EXT_PREC_DECFLOAT:
+      type = init_type (TYPE_CODE_DECFLT,
+			128 / 8,
+			0, "decimal long double", objfile);
+      break;
     case FT_COMPLEX:
       type = init_type (TYPE_CODE_FLT,
 			2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
Index: c-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-valprint.c,v
retrieving revision 1.39
diff -u -r1.39 c-valprint.c
--- c-valprint.c	18 Jan 2006 21:24:19 -0000	1.39
+++ c-valprint.c	21 Jun 2006 23:08:52 -0000
@@ -442,6 +442,17 @@
 	}
       break;
 
+    case TYPE_CODE_DECFLT:
+      if (format)
+	{
+	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+	}
+      else
+	{
+	  print_decimal_floating (valaddr + embedded_offset, type, stream);
+	}
+      break;
+
     case TYPE_CODE_METHOD:
       {
 	struct value *v = value_at (type, address);
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.198
diff -u -r1.198 dwarf2read.c
--- dwarf2read.c	9 Jun 2006 00:44:28 -0000	1.198
+++ dwarf2read.c	21 Jun 2006 23:08:52 -0000
@@ -4739,6 +4739,9 @@
 	case DW_ATE_complex_float:
 	  code = TYPE_CODE_COMPLEX;
 	  break;
+	case DW_ATE_decimal_float:
+	  code = TYPE_CODE_DECFLT;
+	  break;
 	case DW_ATE_float:
 	  code = TYPE_CODE_FLT;
 	  break;
@@ -7507,6 +7510,14 @@
 	  type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
 	}
       return type;
+    case DW_ATE_decimal_float:
+      if (size == 16)
+	type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_DECFLOAT, cu);
+      else if (size == 8)
+	type = dwarf2_fundamental_type (objfile, FT_EXT_PREC_DECFLOAT, cu);
+      else
+	type = dwarf2_fundamental_type (objfile, FT_DECFLOAT, cu);
+      return type;
     case DW_ATE_signed:
       switch (size)
 	{
Index: eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.61
diff -u -r1.61 eval.c
--- eval.c	18 Feb 2006 20:47:54 -0000	1.61
+++ eval.c	21 Jun 2006 23:08:52 -0000
@@ -447,6 +447,11 @@
       return value_from_double (exp->elts[pc + 1].type,
 				exp->elts[pc + 2].doubleconst);
 
+    case OP_DECDOUBLE:
+      (*pos) += 3;
+      return value_from_decdouble (expect_type, exp->elts[pc + 1].type,
+				exp->elts[pc + 2].decdoubleconst);
+
     case OP_VAR_VALUE:
       (*pos) += 3;
       if (noside == EVAL_SKIP)
Index: gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.65
diff -u -r1.65 gdbtypes.h
--- gdbtypes.h	1 Feb 2006 23:14:10 -0000	1.65
+++ gdbtypes.h	21 Jun 2006 23:08:52 -0000
@@ -67,7 +67,12 @@
 #define FT_UNSIGNED_BYTE	27
 #define FT_TEMPLATE_ARG		28
 
-#define FT_NUM_MEMBERS		29	/* Highest FT_* above, plus one. */
+/* The following three fundamental types are for decimal floating point.  */
+#define FT_DECFLOAT		29	
+#define FT_DBL_PREC_DECFLOAT	30
+#define FT_EXT_PREC_DECFLOAT	31	
+
+#define FT_NUM_MEMBERS		32	/* Highest FT_* above, plus one. */
 
 /* Some macros for char-based bitfields.  */
 
@@ -159,7 +164,9 @@
     TYPE_CODE_TEMPLATE,		/* C++ template */
     TYPE_CODE_TEMPLATE_ARG,	/* C++ template arg */
 
-    TYPE_CODE_NAMESPACE		/* C++ namespace.  */
+    TYPE_CODE_NAMESPACE,	/* C++ namespace.  */
+
+    TYPE_CODE_DECFLT		/* Decimal floating point.  */
   };
 
 /* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
@@ -1005,6 +1012,9 @@
   struct type *builtin_bool;
   struct type *builtin_long_long;
   struct type *builtin_unsigned_long_long;
+  struct type *builtin_decfloat;
+  struct type *builtin_decdouble;
+  struct type *builtin_declong;
 };
 
 /* Return the type table for the specified architecture.  */
@@ -1028,6 +1038,9 @@
 extern struct type *builtin_type_double_complex;
 extern struct type *builtin_type_string;
 extern struct type *builtin_type_bool;
+extern struct type *builtin_type_decfloat;
+extern struct type *builtin_type_decdouble;
+extern struct type *builtin_type_declong;
 
 /* Address/pointer types: */
 /* (C) Language `pointer to data' type.  Some target platforms use an
Index: gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.105
diff -u -r1.105 gdbtypes.c
--- gdbtypes.c	1 Mar 2006 19:34:46 -0000	1.105
+++ gdbtypes.c	21 Jun 2006 23:08:52 -0000
@@ -76,6 +76,12 @@
 struct type *builtin_type_uint128;
 struct type *builtin_type_bool;
 
+/* The following three are about decimal floating point types, which are now 
+   considered as potential extension to C99 standard.  */ 
+struct type *builtin_type_decfloat;
+struct type *builtin_type_decdouble;
+struct type *builtin_type_declong;
+
 /* 128 bit long vector types */
 struct type *builtin_type_v2_double;
 struct type *builtin_type_v4_float;
@@ -3379,6 +3385,21 @@
 #if 0
   TYPE_FLOATFORMAT (builtin_type_long_double) = TARGET_LONG_DOUBLE_FORMAT;
 #endif
+
+  /* Builtin types for decimal floating point types.  */
+  builtin_type_decfloat =
+    init_type (TYPE_CODE_DECFLT, 32 / 8,
+	       0,
+	       "decimal float", (struct objfile *) NULL);
+  builtin_type_decdouble =
+    init_type (TYPE_CODE_DECFLT, 64 / 8,
+               0,
+               "decimal double", (struct objfile *) NULL);
+  builtin_type_declong =
+    init_type (TYPE_CODE_DECFLT, 128 / 8,
+	       0,
+	       "decimal long double", (struct objfile *) NULL);
+
   builtin_type_complex =
     init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
 	       0,
@@ -3604,6 +3625,21 @@
 	       0,
 	       "bool", (struct objfile *) NULL);
 
+  /* The following three are about decimal floating point types, which are 
+     32-bits, 64-bits and 128-bits respectively.  */
+  builtin_type->builtin_decfloat = 
+   init_type (TYPE_CODE_DECFLT, 32 / 8,
+               0,
+               "decimal float", (struct objfile *) NULL);
+  builtin_type->builtin_decdouble =
+    init_type (TYPE_CODE_DECFLT, 64 / 8,
+               0,
+               "decimal double", (struct objfile *) NULL);
+  builtin_type->builtin_declong =
+    init_type (TYPE_CODE_DECFLT, 128 / 8,
+               0,
+               "decimal long double", (struct objfile *) NULL);
+
   /* Pointer/Address types. */
 
   /* NOTE: on some targets, addresses and pointers are not necessarily
@@ -3742,6 +3778,9 @@
   DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_void_func_ptr);
   DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR);
   DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_bfd_vma);
+  DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_decfloat);
+  DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_decdouble);
+  DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_declong);
   deprecated_register_gdbarch_swap (NULL, 0, build_gdbtypes);
 
   /* Note: These types do not need to be swapped - they are target
Index: value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.91
diff -u -r1.91 value.h
--- value.h	31 Mar 2006 10:36:18 -0000	1.91
+++ value.h	21 Jun 2006 23:08:52 -0000
@@ -274,6 +274,7 @@
 extern struct value *value_from_longest (struct type *type, LONGEST num);
 extern struct value *value_from_pointer (struct type *type, CORE_ADDR addr);
 extern struct value *value_from_double (struct type *type, DOUBLEST num);
+extern struct value *value_from_decdouble (struct type *expect_type, struct type *type, gdb_byte decbytes[16]);
 extern struct value *value_from_string (char *string);
 
 extern struct value *value_at (struct type *type, CORE_ADDR addr);
@@ -469,6 +470,9 @@
 extern void print_floating (const gdb_byte *valaddr, struct type *type,
 			    struct ui_file *stream);
 
+extern void print_decimal_floating (const gdb_byte *valaddr, struct type *type,
+			    struct ui_file *stream);
+
 extern int value_print (struct value *val, struct ui_file *stream, int format,
 			enum val_prettyprint pretty);
 
Index: valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/valprint.c,v
retrieving revision 1.60
diff -u -r1.60 valprint.c
--- valprint.c	15 May 2006 16:53:38 -0000	1.60
+++ valprint.c	21 Jun 2006 23:08:53 -0000
@@ -35,6 +35,7 @@
 #include "floatformat.h"
 #include "doublest.h"
 #include "exceptions.h"
+#include "dfp.h"
 
 #include <errno.h>
 
@@ -496,6 +497,21 @@
 }
 
 void
+print_decimal_floating (const gdb_byte *valaddr, struct type *type,
+		struct ui_file *stream)
+{
+  char decstr[128];
+  unsigned len = TYPE_LENGTH (type);
+  gdb_byte *dec_val = (gdb_byte *)malloc (len);
+
+  reverse_dfp (valaddr, len, dec_val);
+  decimal_to_string (dec_val, len, decstr);
+  fputs_filtered (decstr, stream);
+  free (dec_val);
+  return;
+}
+
+void
 print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
 		    unsigned len)
 {
Index: value.c
===================================================================
RCS file: /cvs/src/src/gdb/value.c,v
retrieving revision 1.36
diff -u -r1.36 value.c
--- value.c	31 Mar 2006 10:36:18 -0000	1.36
+++ value.c	21 Jun 2006 23:08:53 -0000
@@ -37,6 +37,7 @@
 #include "gdb_assert.h"
 #include "regcache.h"
 #include "block.h"
+#include "dfp.h"
 
 /* Prototypes for exported functions. */
 
@@ -1610,6 +1611,30 @@
 }
 
 struct value *
+value_from_decdouble (struct type *expect_type, struct type *type, 
+		      gdb_byte decbytes[16])
+{
+  struct value *val = allocate_value (type);
+  int len = TYPE_LENGTH (type);
+  gdb_byte *dec_val = (gdb_byte *)malloc (16);
+
+  if (expect_type)
+    {
+      int expect_len = TYPE_LENGTH (expect_type);
+      char decstr[128];
+      int real_len;
+
+      reverse_dfp (decbytes, expect_len, dec_val);
+      decimal_to_string (dec_val, len, decstr);
+      decimal_from_string (dec_val, expect_len, decstr);
+      reverse_dfp (dec_val, expect_len, decbytes);
+    }
+
+  memcpy (value_contents_raw (val), decbytes, len);
+  return val;
+}
+
+struct value *
 coerce_ref (struct value *arg)
 {
   struct type *value_type_arg_tmp = check_typedef (value_type (arg));
Index: valarith.c
===================================================================
RCS file: /cvs/src/src/gdb/valarith.c,v
retrieving revision 1.45
diff -u -r1.45 valarith.c
--- valarith.c	24 Jan 2006 21:21:12 -0000	1.45
+++ valarith.c	21 Jun 2006 23:08:53 -0000
@@ -1378,6 +1378,18 @@
 
   type = check_typedef (value_type (arg1));
 
+  if (TYPE_CODE (type) == TYPE_CODE_DECFLT)
+    {
+      struct value *val = allocate_value (result_type);
+      int len = TYPE_LENGTH (type);
+      gdb_byte *decbytes = (gdb_byte *) value_contents (arg1);
+
+      /* To change the first bit is ok.  */
+      decbytes[len-1] = decbytes[len - 1] | 0x80;
+      memcpy (value_contents_raw (val), decbytes, 16);
+      return val;
+    }
+
   if (TYPE_CODE (type) == TYPE_CODE_FLT)
     return value_from_double (result_type, -value_as_double (arg1));
   else if (is_integral_type (type))
Index: dfp.h
===================================================================
RCS file: dfp.h
diff -N dfp.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dfp.h	21 Jun 2006 23:08:53 -0000
@@ -0,0 +1,45 @@
+/* Decimal floating point support for GDB.
+
+   Copyright 2006 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* Decimal floating point is one of the extension to IEEE 754, which is
+   described in http://grouper.ieee.org/groups/754/revision.html and
+   http://www2.hursley.ibm.com/decimal/.  It completes binary floating
+   point by representing floating point more exactly.  */
+
+/* There is a project intended to add DFP support into GCC, described in
+   http://gcc.gnu.org/wiki/Decimal%20Floating-Point.  This file is intended
+   to add DFP support into GDB.  */
+
+#ifndef DFP_H
+#define DFP_H
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+
+/* The conversion from decimal floating point to string, and reverse.  */
+extern void decimal_to_string (const uint8_t *, int, char *);
+extern void decimal_from_string (uint8_t *, int, char *);
+
+/* The value struct of gdb and decimal type of libdecnumber are using
+   different endian for storing the content.  This routine is used to
+   convert between these two.  */
+extern void reverse_dfp (const gdb_byte *, int, gdb_byte *);
+#endif
Index: dfp.c
===================================================================
RCS file: dfp.c
diff -N dfp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dfp.c	21 Jun 2006 23:08:53 -0000
@@ -0,0 +1,104 @@
+/* Decimal floating point support for GDB.
+
+   Copyright 2006 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "dfp.h"
+#include <ctype.h>
+
+/* The order of the following headers is important for making sure
+   decNumber structure is large enough to hold decimal128 digits.  */
+
+#include "decimal128.h"
+#include "decimal64.h"
+#include "decimal32.h"
+#include "decNumber.h"
+
+void
+reverse_dfp (const gdb_byte *valaddr, int len, gdb_byte *dec_val)
+{
+  int index;
+
+  for (index = 0; index < len; index++)
+    dec_val[index] = valaddr[len - index - 1];
+
+  return;
+}
+
+/* Convert deciaml type to its string representation.  LEN is the length
+   of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and
+   16 bytes for decimal128.  */
+void
+decimal_to_string (const uint8_t *dec, int len, char *s)
+{
+  switch (len)
+    {
+      case 4:
+        decimal32ToString ((decimal32 *)dec, s);
+        return;
+      case 8:
+        decimal64ToString ((decimal64 *)dec, s);
+        return;
+      case 16:
+        decimal128ToString ((decimal128 *)dec, s);
+        return;
+      default:
+	error ("We don't support decimal number of %d bytes.", len);
+    }
+}
+
+void
+decimal_from_string (uint8_t *dec, int len, char *string)
+{
+  decNumber dn;
+  decContext set;
+  switch (len)
+    {
+      case 4:
+	decContextDefault (&set, DEC_INIT_DECIMAL32);
+	break;
+      case 8:
+	decContextDefault (&set, DEC_INIT_DECIMAL64);
+	break;
+      case 16:
+	decContextDefault (&set, DEC_INIT_DECIMAL128);
+	break;
+      default:
+	error ("We don't support decimal number of %d bytes.", len);
+    }
+
+  set.traps = 0;
+
+  decNumberFromString (&dn, string, &set);
+  switch (len)
+    {
+      case 4:
+	decimal32FromNumber ((decimal32 *)dec, &dn, &set);
+	return;
+      case 8:
+	decimal64FromNumber ((decimal64 *)dec, &dn, &set);
+	return;
+      case 16:
+	decimal128FromNumber ((decimal128 *)dec, &dn, &set);
+	return;
+      default:
+	error ("We don't support decimal number of %d bytes.", len);
+    }
+}
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.821
diff -u -r1.821 Makefile.in
--- Makefile.in	31 May 2006 15:14:36 -0000	1.821
+++ Makefile.in	21 Jun 2006 23:08:53 -0000
@@ -122,6 +122,12 @@
 BFD_SRC = $(srcdir)/$(BFD_DIR)
 BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC)
 
+# Where is the decnumber library?  Typically in ../libdecnumber.
+LIBDECNUMBER_DIR = ../libdecnumber
+LIBDECNUMBER = $(LIBDECNUMBER_DIR)/libdecnumber.a
+LIBDECNUMBER_SRC = $(srcdir)/$(LIBDECNUMBER_DIR)
+LIBDECNUMBER_CFLAGS = -I$(LIBDECNUMBER_DIR) -I$(LIBDECNUMBER_SRC)
+
 # Where is the READLINE library?  Typically in ../readline.
 READLINE_DIR = ../readline
 READLINE = $(READLINE_DIR)/libreadline.a
@@ -348,7 +354,7 @@
 INTERNAL_CFLAGS_BASE = \
 	$(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
 	$(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) \
-	$(BFD_CFLAGS) $(INCLUDE_CFLAGS) \
+	$(BFD_CFLAGS) $(INCLUDE_CFLAGS) $(LIBDECNUMBER_CFLAGS) \
 	$(INTL_CFLAGS) $(ENABLE_CFLAGS)
 INTERNAL_WARN_CFLAGS = $(INTERNAL_CFLAGS_BASE) $(GDB_WARN_CFLAGS)
 INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS)
@@ -371,10 +377,10 @@
 # LIBIBERTY appears twice on purpose.
 # If you have the Cygnus libraries installed,
 # you can use 'CLIBS=$(INSTALLED_LIBS)' 'CDEPS='
-INSTALLED_LIBS=-lbfd -lreadline -lopcodes -liberty \
+INSTALLED_LIBS=-lbfd -lreadline -lopcodes -liberty -ldecnumber \
 	$(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \
 	-lintl -liberty
-CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(INTL) $(LIBIBERTY) \
+CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(INTL) $(LIBIBERTY) $(LIBDECNUMBER) \
 	$(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \
 	$(LIBICONV) \
 	$(LIBIBERTY) $(WIN32LIBS)
@@ -605,6 +611,10 @@
 safe_ctype_h =  $(INCLUDE_DIR)/safe-ctype.h
 hashtab_h =	$(INCLUDE_DIR)/hashtab.h
 
+decimal128_h = $(LIBDECNUMBER_DIR)/decimal128.h
+decimal64_h = $(LIBDECNUMBER_DIR)/decimal64.h
+decimal32_h = $(LIBDECNUMBER_DIR)/decimal32.h
+
 #
 # $BUILD/ headers
 #
@@ -670,6 +680,7 @@
 disasm_h = disasm.h
 doublest_h = doublest.h $(floatformat_h)
 dummy_frame_h = dummy-frame.h
+dfp_h = dfp.h
 dwarf2expr_h = dwarf2expr.h
 dwarf2_frame_h = dwarf2-frame.h
 dwarf2loc_h = dwarf2loc.h
@@ -912,7 +923,7 @@
 	auxv.o \
 	bfd-target.o \
 	blockframe.o breakpoint.o findvar.o regcache.o \
-	charset.o disasm.o dummy-frame.o \
+	charset.o disasm.o dummy-frame.o dfp.o \
 	source.o value.o eval.o valops.o valarith.o valprint.o printcmd.o \
 	block.o symtab.o symfile.o symmisc.o linespec.o dictionary.o \
 	infcall.o \
@@ -1917,6 +1928,7 @@
 dummy-frame.o: dummy-frame.c $(defs_h) $(dummy_frame_h) $(regcache_h) \
 	$(frame_h) $(inferior_h) $(gdb_assert_h) $(frame_unwind_h) \
 	$(command_h) $(gdbcmd_h) $(gdb_string_h)
+dfp.o: dfp.c $(defs_h) $(dfp_h) $(decimal128_h) $(decimal64_h) $(decimal32_h)
 dve3900-rom.o: dve3900-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
 	$(serial_h) $(inferior_h) $(command_h) $(gdb_string_h) $(regcache_h) \
 	$(mips_tdep_h)
@@ -2790,7 +2802,7 @@
 valprint.o: valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
 	$(value_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(language_h) \
 	$(annotate_h) $(valprint_h) $(floatformat_h) $(doublest_h) \
-	$(exceptions_h)
+	$(exceptions_h) $(dfp_h)
 value.o: value.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
 	$(value_h) $(gdbcore_h) $(command_h) $(gdbcmd_h) $(target_h) \
 	$(language_h) $(scm_lang_h) $(demangle_h) $(doublest_h) \


Here is the patch to add libdecnumber code into gdb top-level repository.  
I didn't figure out how to add a whole new directory into the cvs.  Anyone 
can help me on this?  I only attach the makefile change here:

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/Makefile.in,v
retrieving revision 1.244
diff -r1.244 Makefile.in
396a397,401
> @if libdecnumber
> HOST_LIB_PATH_libdecnumber = \
>   $$r/$(HOST_SUBDIR)/libdecnumber/.libs:$$r/$(HOST_SUBDIR)/prev-libdecnumber/.libs:
> @endif libdecnumber
> 


Regards
- Wu Zhou

On Thu, 22 Jun 2006, Wu Zhou wrote:

> Hello Daniel/all,
> 
> About one week ago, I said that I will rework my dfp patch based on libdecnumber.
> OK.  Here it is.  This post is about what it can support right now.  The
> testcase can tell easily about this.  The gdb patch will be posted in 
> another email.
> 
> The functions this patch provides are much the same as before.  But it is 
> more exensible because it is based on libdecnumber.  I list here what is 
> available now.  If you think any functionality is desirable, please tell 
> me.  I will try to add them in.
> 
> - for dfp constants, this patch supports two kind of representation: 
> scientific one and non-scientific one.  To input any dfp constants, you 
> need to add suffix to differentiate it from binary float: "df" for deciaml 
> float (32 bits), "dd" for deciaml double (64 bits), and "dl" for deciaml
> long (128 bits).  When printing dfp constants, it will strip the suffix.  
> 
> - it supports the displaying of dfp values in variables, struct, function 
> argument and also back trace.  Any more is needed?
> 
> - it support the negation operation (-dfp), assign operation (d1 = d2 or 
> d1 = -d2),
> 
> - it can handle finite dfp numbers, infinity (positive and negative), and 
> NaN (not a number).  
> 
> - it can also support the max, normalized min and subnormalized min well.
> 
> - we can't do conversion between binary float and decimal float right, or 
> between two different dfp types right now
> 
> Here goes the testcase.  Please review.  Any comment or suggestion is 
> highly appreciated.  
> 
> P.S: I am trying to make it self explanatory.  But if you think more 
> comment is needed in some place, feel free to tell me.
> 
> 2006-06-21  Wu Zhou  <woodzltc@cn.ibm.com>
> 
> 	* gdb.base/dfp-exprs.exp: New testcase to verify that gdb can
> 	handle dfp constants correctly.
> 	* gdb.base/dfp-test.c: New test file, used for dfp-test.exp.
> 	* gdb.base/dfp-test.exp: New testcase toverify that gdb can handle
> 	dfp related operation.
> 
> Index: gdb.base/dfp-exprs.exp
> ===================================================================
> RCS file: gdb.base/dfp-exprs.exp
> diff -N gdb.base/dfp-exprs.exp
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ gdb.base/dfp-exprs.exp	21 Jun 2006 21:00:23 -0000
> @@ -0,0 +1,88 @@
> +# Copyright (C) 2005 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 2 of the License, or
> +# (at your option) any later version.
> +# 
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +# 
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
> +
> +# This file was written by Wu Zhou. (woodzltc@cn.ibm.com)
> +
> +# This file is part of the gdb testsuite.  It contains test for evaluating 
> +# simple decimal floating point (DFP) expression.
> +
> +if $tracelevel then {
> +	strace $tracelevel
> +}
> +
> +proc test_dfp_literals_accepted {} {
> +
> +    # Test various dfp values, covering 32-bit, 64-bit and 128-bit ones
> +
> +    # _Decimal32 constants, which can support up to 7 digits
> +    gdb_test "p 1.2df" " = 1.2"
> +    gdb_test "p -1.2df" " = -1.2"
> +    gdb_test "p 1.234567df" " = 1.234567" 
> +    gdb_test "p -1.234567df" " = -1.234567"
> +    gdb_test "p 1234567.df" " = 1234567"
> +    gdb_test "p -1234567.df" " = -1234567"
> +
> +    gdb_test "p 1.2E1df" " = 12"
> +    gdb_test "p 1.2E10df" " = 1.2E\\+10"
> +    gdb_test "p 1.2E-10df" " = 1.2E-10"
> +
> +    # The largest exponent for 32-bit dfp value is 96.
> +    gdb_test "p 1.2E96df" " = 1.200000E\\+96"
> +
> +    # _Decimal64 constants, which can support up to 16 digits
> +    gdb_test "p 1.2dd" " = 1.2"
> +    gdb_test "p -1.2dd" " = -1.2"
> +    gdb_test "p 1.234567890123456dd" " = 1.234567890123456"
> +    gdb_test "p -1.234567890123456dd" " = -1.234567890123456"
> +    gdb_test "p 1234567890123456.dd" " = 1234567890123456"
> +    gdb_test "p -1234567890123456.dd" " = -1234567890123456"
> +
> +    gdb_test "p 1.2E1dd" " = 12"
> +    gdb_test "p 1.2E10dd" " = 1.2E\\+10"
> +    gdb_test "p 1.2E-10dd" " = 1.2E-10"
> +
> +    # The largest exponent for 64-bit dfp value is 384.
> +    gdb_test "p 1.2E384dd" " = 1.200000000000000E\\+384"
> +
> +    # _Decimal128 constants, which can support up to 34 digits
> +    gdb_test "p 1.2dl" " = 1.2"
> +    gdb_test "p -1.2dl" " = -1.2"
> +    gdb_test "p 1.234567890123456789012345678901234dl" " = 1.234567890123456789012345678901234"
> +    gdb_test "p -1.234567890123456789012345678901234dl" " = -1.234567890123456789012345678901234"
> +    gdb_test "p 1234567890123456789012345678901234.dl" " = 1234567890123456789012345678901234"
> +    gdb_test "p -1234567890123456789012345678901234.dl" " = -1234567890123456789012345678901234"
> +
> +    gdb_test "p 1.2E1dl" " = 12"
> +    gdb_test "p 1.2E10dl" " = 1.2E\\+10"
> +    gdb_test "p 1.2E-10dl" " = 1.2E-10"
> +
> +    # The largest exponent for 128-bit dfp value is 6144.
> +    gdb_test "p 1.2E6144dl" " = 1.200000000000000000000000000000000E\\+6144"  
> +}
> +
> +proc test_arithmetic_expressions {} {
> +
> +# Arithmetic operations for DFP types are not yet implemented in GDB.
> +
> +}
> +
> +# Start with a fresh gdb.
> +
> +gdb_exit
> +gdb_start
> +gdb_reinitialize_dir $srcdir/$subdir
> +
> +test_dfp_literals_accepted
> Index: gdb.base/dfp-test.c
> ===================================================================
> RCS file: gdb.base/dfp-test.c
> diff -N gdb.base/dfp-test.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ gdb.base/dfp-test.c	21 Jun 2006 21:00:23 -0000
> @@ -0,0 +1,95 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2006 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 2 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program; if not, write to the Free Software
> +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
> +   02111-1307, USA.  */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +volatile _Decimal32 d32;
> +volatile _Decimal64 d64;
> +volatile _Decimal128 d128;
> +
> +struct decstruct
> +{
> +  int int4;
> +  long long8;
> +  _Decimal32 dec32;
> +  _Decimal64 dec64;
> +  _Decimal128 dec128;
> +} ds;
> +
> +static _Decimal32
> +arg0_32 (_Decimal32 arg0, _Decimal32 arg1, _Decimal32 arg2,
> +         _Decimal32 arg3, _Decimal32 arg4, _Decimal32 arg5)
> +{
> +  return arg0;
> +}
> +
> +static _Decimal64
> +arg0_64 (_Decimal64 arg0, _Decimal64 arg1, _Decimal64 arg2,
> +         _Decimal64 arg3, _Decimal64 arg4, _Decimal64 arg5)
> +{
> +  return arg0;
> +}
> +
> +static _Decimal128
> +arg0_128 (_Decimal128 arg0, _Decimal128 arg1, _Decimal128 arg2,
> +         _Decimal128 arg3, _Decimal128 arg4, _Decimal128 arg5)
> +{
> +  return arg0;
> +}
> +
> +int main()
> +{
> +  /* An finite 32-bits decimal floating point.  */
> +  d32 = 1.2345df;		/* Initialize d32.  */
> +
> +  /* Non-finite 32-bits decimal floating point: infinity and NaN.  */
> +  d32 = __builtin_infd32();	/* Positive infd32.  */
> +  d32 = -__builtin_infd32();	/* Negative infd32.  */
> +  d32 = __builtin_nand32("");
> +
> +  /* An finite 64-bits decimal floating point.  */
> +  d64 = 1.2345dd;		/* Initialize d64.  */
> +
> +  /* Non-finite 64-bits decimal floating point: infinity and NaN.  */
> +  d64 = __builtin_infd64();	/* Positive infd64.  */
> +  d64 = -__builtin_infd64();	/* Negative infd64.  */
> +  d64 = __builtin_nand64("");
> +
> +  /* An finite 128-bits decimal floating point.  */
> +  d128 = 1.2345dl;		/* Initialize d128.  */
> +
> +  /* Non-finite 128-bits decimal floating point: infinity and NaN.  */
> +  d128 = __builtin_infd128();	/* Positive infd128.  */
> +  d128 = -__builtin_infd128();	/* Negative infd128.  */
> +  d128 = __builtin_nand128("");
> +
> +  /* Functions with decimal floating point as parameter and return value.  */
> +  d32 = arg0_32 (0.1df, 1.0df, 2.0df, 3.0df, 4.0df, 5.0df);
> +  d64 = arg0_64 (0.1dd, 1.0dd, 2.0dd, 3.0dd, 4.0dd, 5.0dd);
> +  d128 = arg0_128 (0.1dl, 1.0dl, 2.0dl, 3.0dl, 4.0dl, 5.0dl);
> +
> +  ds.int4 = 1;
> +  ds.long8 = 2;
> +  ds.dec32 = 1.2345df;
> +  ds.dec64 = 1.2345dd;
> +  ds.dec128 = 1.2345dl;
> +
> +  return 0;	/* Exit point.  */
> +}
> Index: gdb.base/dfp-test.exp
> ===================================================================
> RCS file: gdb.base/dfp-test.exp
> diff -N gdb.base/dfp-test.exp
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ gdb.base/dfp-test.exp	21 Jun 2006 21:00:23 -0000
> @@ -0,0 +1,247 @@
> +# Copyright 2005 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 2 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
> +
> +#  This file was written by Wu Zhou. (woodzltc@cn.ibm.com)
> +
> +# This file is part of the gdb testsuite.  It is intended to test that
> +# gdb could correctly hane decimal floating point introduced in IEEE 754R.
> +
> +proc d32_set_tests {} {
> +
> +    gdb_test "p d32=123.45df" " = 123.45"
> +    gdb_test "p d32=12345.df" " = 12345"
> +    gdb_test "p d32=12345.67df" " = 12345.67"
> +    gdb_test "p d32=1234567.df" " = 1234567"
> +
> +    gdb_test "p d32=1.234567E0df" " = 1.234567" 
> +    gdb_test "p d32=1.234567E10df" " = 1.234567E\\+10"
> +    gdb_test "p d32=1.234567E+96df" " = 1.234567E\\+96"
> +
> +    # Test that gdb could handle the max, normalized min and subnormalized min.
> +    gdb_test "p d32=9.999999E96df" " = 9.999999E\\+96"
> +    gdb_test "p d32=1.0E-95df" " = 1.0E\\-95"
> +    gdb_test "p d32=1.E-101df" " = 1E\\-101"
> +    gdb_test "p d32=0.000001E-95df" " = 1E\\-101"
> +
> +    # Test that gdb could detect coefficient/exponent out of range.
> +    # The coefficient out of range will be rounded to its nearest value.
> +    # And the exponent out of range will be handled as infinity.
> +    gdb_test "p d32=1.2345678df" " = 1.234568" "1.2345678 is rounded to 1.234568"
> +    gdb_test "p d32=1.0E-101df" " = 1E-101" "1.0E-101 is rounded to 1E-101"
> +    gdb_test "p d32=1.234567E+97df" " = Infinity" "1.234567E+97 is Infinity"
> +
> +    # Test that gdb could detect the errors in the string representation of _Decimal32
> +    gdb_test "p d32=12345.df" " = 12345" "12345. is an valid number"
> +    gdb_test "p d32=12345df" ".*Invalid number.*" "12345 is an invalid number"
> +    gdb_test "p d32=1.23Edf" " = NaN" "1.23E is NaN (not a number)"
> +    gdb_test "p d32=1.23E45Adf" " = NaN" "1.23E45A is NaN (not a number)"
> +}
> +
> +proc d64_set_tests {} {
> +
> +    gdb_test "p d64=123.45dd" " = 123.45"
> +    gdb_test "p d64=12345.dd" " = 12345"
> +    gdb_test "p d64=12345.67dd" " = 12345.67"
> +    gdb_test "p d64=1.234567890123456dd" " = 1.234567890123456"
> +
> +    gdb_test "p d64=1.234567890123456E10dd" " = 12345678901.23456"
> +    gdb_test "p d64=1.234567890123456E100dd" " = 1.234567890123456E\\+100"
> +    gdb_test "p d64=1.234567890123456E384dd" " = 1.234567890123456E\\+384"
> +
> +    # Test that gdb could handle the max, normalized min and subnormalized min.
> +    gdb_test "p d64=9.999999999999999E384dd" " = 9.999999999999999E\\+384"
> +    gdb_test "p d64=1.E-383dd" " = 1E\\-383"
> +    gdb_test "p d64=1.E-398dd" " = 1E\\-398"
> +    gdb_test "p d64=0.000000000000001E-383dd" " = 1E\\-398"
> +
> +    # Test that gdb could detect coefficient/exponent out of range.
> +    # The coefficient out of range will be rounded to its nearest value.
> +    # And the exponent out of range will be handled as infinity.
> +    gdb_test "p d64=1.2345678901234567dd" " = 1.234567890123457" "1.2345678901234567 is rounded to 1.234567890123457" 
> +    gdb_test "p d64=9.9999999999999999E384dd" " = Infinity" "d64=9.9999999999999999E384 is Infinity"
> +    gdb_test "p d64=1.234567890123456E385dd" " = Infinity" "d64=1.234567890123456E385 is Infinity"
> +
> +    # Test that gdb could detect the errors in the string representation of _Decimal64
> +    gdb_test "p d64=12345dd" ".*Invalid number.*" "12345dd is an invalid number"
> +    gdb_test "p d64=1.23Edd" " = NaN" "1.23E is NaN (not a number)"
> +    gdb_test "p d64=1.23E45Add" "= NaN" "1.23E45A is NaN (not a number)"
> +}
> +
> +proc d128_set_tests {} {
> +
> +    gdb_test "p d128=123.45dl" " = 123.45"
> +    gdb_test "p d128=12345.dl" " = 12345"
> +    gdb_test "p d128=12345.67dl" " = 12345.67"
> +    gdb_test "p d128=1.234567890123456789012345678901234dl" " = 1.234567890123456789012345678901234"
> +
> +    gdb_test "p d128=1.234567890123456E10dl" " = 12345678901.23456"
> +    gdb_test "p d128=1.234567890123456E100dl" " = 1.234567890123456E\\+100"
> +    gdb_test "p d128=1.234567890123456E1000dl" " = 1.234567890123456E\\+1000"
> +
> +    # Test that gdb could handle the max, normalized min and subnormalized min.
> +    gdb_test "p d128=9.999999999999999999999999999999999E6144dl" " = 9.999999999999999999999999999999999E\\+6144"
> +    gdb_test "p d128=1.E-6143dl" " = 1E\\-6143"
> +    gdb_test "p d128=1.E-6176dl" " = 1E\\-6176"
> +    gdb_test "p d128=0.000000000000000000000000000000001E-6143dl" " = 1E\\-6176"
> +
> +    # Test that gdb could detect coefficient/exponent out of range.
> +    # The coefficient out of range will be rounded to its nearest value.
> +    # And the exponent out of range will be handled as infinity.
> +    gdb_test "p d128=1.2345678901234567890123456789012345dl" "1.234567890123456789012345678901234" "1.2345678901234567890123456789012345 is rounded to 1.234567890123456789012345678901234"
> +    gdb_test "p d128=1.234567890123456E6145dl" "Infinity" "d128=1.234567890123456E6145 is Infinity"
> +
> +    # Test that gdb could detect the errors in the string representation of _Decimal128
> +    gdb_test "p d128=12345dl" ".*Invalid number.*" "12345dl is an invalid number"
> +    gdb_test "p d128=1.23Edl" " = NaN" "1.23E is NaN (not a number)"
> +    gdb_test "p d128=1.23E45Adl" "= NaN" "1.23E45A is NaN (not a number)"
> +}
> +
> +
> +if $tracelevel {
> +    strace $tracelevel
> +}
> +
> +set testfile "dfp-test"
> +set srcfile ${testfile}.c
> +set binfile ${objdir}/${subdir}/${testfile}
> +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
> +    untested "Couldn't compile ${srcfile}"
> +    return -1
> +}
> +
> +gdb_exit
> +gdb_start
> +gdb_reinitialize_dir $srcdir/$subdir
> +gdb_load ${binfile}
> +
> +if ![runto_main] then {
> +    perror "couldn't run to breakpoint"
> +    continue
> +}
> +
> +# Different tests on 32-bits decimal floating point, including the printing 
> +# of finite numbers, infinite and NaN, and also the setting of different
> +# decimal value.
> +
> +if [gdb_test "next" \
> +    ".*Positive infd32.*" \
> +    "next after initializing d32"] then { gdb_suppress_tests }
> +gdb_test "print d32" "1.2345" "d32 is initialized to 1.2345"
> +
> +if [gdb_test "next" \
> +    ".*Negative infd32.*" \
> +    "next after assigning builtin infinity to d32"] then { gdb_suppress_tests }
> +gdb_test "print d32" "Infinity" "d32 is positive Infinity"
> +
> +if [gdb_test "next" \
> +    ".*__builtin_nand32.*" \
> +    "next after assigning negative builtin infinity to d32"] then { gdb_suppress_tests }
> +gdb_test "print d32" "-Infinity" "d32 is negative Infinity"
> +
> +if [gdb_test "next" \
> +    ".*d64 = 1.2345.*" \
> +    "next after assigning builtin NaN to d32"] then { gdb_suppress_tests }
> +gdb_test "print d32" "NaN" "d32 is NaN"
> +
> +d32_set_tests 
> +
> +
> +# Different tests on 64-bits decimal floating point, including the display
> +# of finite number, infinite and NaN, and also the setting of different
> +# decimal value.
> +
> +if [gdb_test "next" \
> +    ".*Positive infd64.*" \
> +    "next after initializing d64"] then { gdb_suppress_tests }
> +gdb_test "print d64" "1.2345" "d64 is initialized to 1.2345"
> +
> +if [gdb_test "next" \
> +    ".*Negative infd64.*" \
> +    "next after assigning builtin infinity to d64"] then { gdb_suppress_tests }
> +gdb_test "print d64" "Infinity" "d64 is positive Infinity"
> +
> +if [gdb_test "next" \
> +    ".*__builtin_nand64.*" \
> +    "next after assigning negative builtin infinity to d64"] then { gdb_suppress_tests }
> +gdb_test "print d64" "-Infinity" "d64 is negative Infinity"
> +
> +if [gdb_test "next" \
> +    ".*d128 = 1.2345.*" \
> +    "next after assigning builtin NaN to d64"] then { gdb_suppress_tests }
> +gdb_test "print d64" "NaN" "d64 is NaN"
> +
> +d64_set_tests 
> +
> +
> +# Different tests on 128-bits decimal floating point, including the display
> +# of finite number, infinite and NaN, and also the setting of different
> +# decimal value.
> +
> +if [gdb_test "next" \
> +    ".*Positive infd128.*" \
> +    "next after initializing d128"] then { gdb_suppress_tests }
> +gdb_test "print d128" "1.2345" "d128 is initialized to 1.2345"
> +
> +d128_set_tests
> +
> +if [gdb_test "next" \
> +    ".*Negative infd128.*" \
> +    "next after assigning builtin infinity to d128"] then { gdb_suppress_tests }
> +gdb_test "print d128" "Infinity" "d128 is positive Infinity"
> +
> +if [gdb_test "next" \
> +    ".*__builtin_nand128.*" \
> +    "next after assigning negative builtin infinity to d128"] then { gdb_suppress_tests }
> +gdb_test "print d128" "-Infinity" "d128 is negative Infinity"
> +
> +if [gdb_test "next" \
> +    ".*arg0_32.*" \
> +    "next after assigning builtin NaN to d128"] then { gdb_suppress_tests }
> +gdb_test "print d128" "NaN" "d128 is NaN"
> +
> +# The following tests are intended to verify that gdb can correctly handle 
> +# DFP types in function arguments.
> +
> +gdb_breakpoint arg0_32
> +gdb_continue_to_breakpoint "entry to arg0_32"
> +gdb_test "backtrace" ".*arg0_32 \\(arg0=0.1, arg1=1.0, arg2=2.0, arg3=3.0, arg4=4.0, arg5=5.0\\).*" "backtrace at arg0_32"
> +
> +gdb_breakpoint arg0_64
> +gdb_continue_to_breakpoint "entry to arg0_64"
> +gdb_test "backtrace" ".*arg0_64 \\(arg0=0.1, arg1=1.0, arg2=2.0, arg3=3.0, arg4=4.0, arg5=5.0\\).*" "backtrace at arg0_64"
> +
> +gdb_breakpoint arg0_128
> +gdb_continue_to_breakpoint "entry to arg0_128"
> +gdb_test "backtrace" ".*arg0_128 \\(arg0=0.1, arg1=1.0, arg2=2.0, arg3=3.0, arg4=4.0, arg5=5.0\\).*" "backtrace at arg0_128"
> +
> +# The following tests are intended to verify that gdb can handle DFP types
> +# correctly in struct.
> +
> +gdb_breakpoint [gdb_get_line_number "Exit point"]
> +gdb_continue_to_breakpoint "Setting a decimal struct"
> +gdb_test "print ds.dec32" " = 1.2345"
> +gdb_test "print ds.dec64" " = 1.2345"
> +gdb_test "print ds.dec128" " = 1.2345"
> +
> +# The following tests are intended to verify that gdb can handle "d1=d2"
> +# and "d1=-d2" correctly.
> +
> +gdb_test "print ds.dec32=d32" " = 0.1"
> +gdb_test "print ds.dec64=d64" " = 0.1"
> +gdb_test "print ds.dec128=d128" " = 0.1"
> +gdb_test "print ds.dec32 = -d32" " = -0.1"
> +gdb_test "print ds.dec64 = -d64" " = -0.1"
> +gdb_test "print ds.dec128 = -d128" " = -0.1"
> 
> 
> Regards
> - Wu Zhou
> 


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