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]

[patch] DFP support for GDB 6.6


Hi folks,

Here's the DFP patch I posted earlier, adapted to apply to GDB 6.6. I
post it here because people already starting to work with DFP would find
it useful to have this functionality in a stable version of GDB.
-- 
[]'s
Thiago Jung Bauermann
Software Engineer
IBM Linux Technology Center
diff -pruN gdb-6.6/gdb/c-exp.y gdb-6.6-dfp/gdb/c-exp.y
--- gdb-6.6/gdb/c-exp.y	2006-08-01 22:13:20.000000000 -0500
+++ gdb-6.6-dfp/gdb/c-exp.y	2007-02-26 12:08:18.000000000 -0600
@@ -53,6 +53,7 @@ Boston, MA 02110-1301, USA.  */
 #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 @@ void yyerror (char *);
       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 @@ static int parse_number (char *, int, in
 
 %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 @@ exp	:	FLOAT
 			  write_exp_elt_opcode (OP_DOUBLE); }
 	;
 
+exp	:	DECFLOAT
+			{ write_exp_elt_opcode (OP_DECFLOAT);
+			  write_exp_elt_type ($1.type);
+			  write_exp_elt_decfloatcst ($1.val);
+			  write_exp_elt_opcode (OP_DECFLOAT); }
+	;
+
 exp	:	variable
 	;
 
@@ -1078,6 +1091,40 @@ parse_number (p, len, parsed_float, puti
       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')
+	{
+	  p[len - 2] = '\0';
+	  putithere->typed_val_decfloat.type =
+	    builtin_type (current_gdbarch)->builtin_decfloat;
+	  decimal_from_string (putithere->typed_val_decfloat.val, 4, p);
+	  p[len] = saved_char;
+	  return (DECFLOAT);
+	}
+
+      if (p[len - 2] == 'd' && p[len - 1] == 'd')
+	{
+	  p[len - 2] = '\0';
+	  putithere->typed_val_decfloat.type =
+	    builtin_type (current_gdbarch)->builtin_decdouble;
+	  decimal_from_string (putithere->typed_val_decfloat.val, 8, p);
+	  p[len] = saved_char;
+	  return (DECFLOAT);
+	}
+
+      if (p[len - 2] == 'd' && p[len - 1] == 'l')
+	{
+	  p[len - 2] = '\0';
+	  putithere->typed_val_decfloat.type =
+	    builtin_type (current_gdbarch)->builtin_declong;
+	  decimal_from_string (putithere->typed_val_decfloat.val, 16, p);
+	  p[len] = saved_char;
+	  return (DECFLOAT);
+	}
+
       num = sscanf (p, DOUBLEST_SCAN_FORMAT "%s",
 		    &putithere->typed_val_float.dval, s);
       p[len] = saved_char;	/* restore the input stream */
diff -pruN gdb-6.6/gdb/c-lang.c gdb-6.6-dfp/gdb/c-lang.c
--- gdb-6.6/gdb/c-lang.c	2005-12-17 16:33:59.000000000 -0600
+++ gdb-6.6-dfp/gdb/c-lang.c	2007-02-26 12:08:18.000000000 -0600
@@ -322,6 +322,21 @@ c_create_fundamental_type (struct objfil
 			TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
 			0, "long double", objfile);
       break;
+    case FT_DECFLOAT:
+      type = init_type (TYPE_CODE_DECFLOAT,
+			32 / 8,
+			0, "decimal float", objfile);
+      break;
+    case FT_DBL_PREC_DECFLOAT:
+      type = init_type (TYPE_CODE_DECFLOAT,
+			64 / 8,
+			0, "decimal double", objfile);
+      break;
+    case FT_EXT_PREC_DECFLOAT:
+      type = init_type (TYPE_CODE_DECFLOAT,
+			128 / 8,
+			0, "decimal long double", objfile);
+      break;
     case FT_COMPLEX:
       type = init_type (TYPE_CODE_FLT,
 			2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
diff -pruN gdb-6.6/gdb/c-valprint.c gdb-6.6-dfp/gdb/c-valprint.c
--- gdb-6.6/gdb/c-valprint.c	2006-01-18 15:24:19.000000000 -0600
+++ gdb-6.6-dfp/gdb/c-valprint.c	2007-02-26 12:08:18.000000000 -0600
@@ -450,6 +450,14 @@ c_val_print (struct type *type, const gd
 	break;
       }
 
+    case TYPE_CODE_DECFLOAT:
+      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_VOID:
       fprintf_filtered (stream, "void");
       break;
diff -pruN gdb-6.6/gdb/dfp.c gdb-6.6-dfp/gdb/dfp.c
--- gdb-6.6/gdb/dfp.c	1969-12-31 18:00:00.000000000 -0600
+++ gdb-6.6-dfp/gdb/dfp.c	2007-02-26 12:47:56.000000000 -0600
@@ -0,0 +1,122 @@
+/* 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"
+
+/* In gdb, we are using an array of gdb_byte to represent decimal values. The
+   byte order of our representation might be different than that of underlying
+   architecture.  This routine does the conversion if it is necessary.  */
+static void
+exchange_dfp (const gdb_byte *valaddr, int len, gdb_byte *dec_val)
+{
+  int index;
+
+  if (gdbarch_byte_order (current_gdbarch) == 1)
+    for (index = 0; index < len; index++)
+      dec_val[index] = valaddr[len - index - 1];
+  else
+    for (index = 0; index < len; index++)
+      dec_val[index] = valaddr[index];
+
+  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 *decbytes, int len, char *s)
+{
+  uint8_t *dec = (uint8_t *)malloc (len);
+
+  exchange_dfp (decbytes, len, dec);
+  switch (len)
+    {
+      case 4:
+        decimal32ToString ((decimal32 *) dec, s);
+        return;
+      case 8:
+        decimal64ToString ((decimal64 *) dec, s);
+        return;
+      case 16:
+        decimal128ToString ((decimal128 *) dec, s);
+        return;
+      default:
+	return;
+    }
+
+  free (dec);
+}
+
+/* Convert the string form of a decimal value to its decimal representation.
+   LEN is the length of the decimal type, 4 bytes for decimal32, 8 bytes for
+   decimal64 and 16 bytes for decimal128.  */
+int
+decimal_from_string (uint8_t *decbytes, int len, char *string)
+{
+  decNumber dn;
+  decContext set;
+  int index;
+  uint8_t *dec = (uint8_t *)malloc (len);
+
+  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;
+    }
+
+  set.traps = 0;
+
+  decNumberFromString (&dn, string, &set);
+  switch (len)
+    {
+      case 4:
+	decimal32FromNumber ((decimal32 *) dec, &dn, &set);
+	break;
+      case 8:
+	decimal64FromNumber ((decimal64 *) dec, &dn, &set);
+	break;
+      case 16:
+	decimal128FromNumber ((decimal128 *) dec, &dn, &set);
+	break;
+    }
+
+  exchange_dfp (dec, len, decbytes);
+  free (dec);
+  return 1;
+}
diff -pruN gdb-6.6/gdb/dfp.h gdb-6.6-dfp/gdb/dfp.h
--- gdb-6.6/gdb/dfp.h	1969-12-31 18:00:00.000000000 -0600
+++ gdb-6.6-dfp/gdb/dfp.h	2007-02-26 12:47:56.000000000 -0600
@@ -0,0 +1,40 @@
+/* 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>
+
+extern void decimal_to_string (const uint8_t *, int, char *);
+extern int decimal_from_string (uint8_t *, int, char *);
+
+#endif
diff -pruN gdb-6.6/gdb/dwarf2read.c gdb-6.6-dfp/gdb/dwarf2read.c
--- gdb-6.6/gdb/dwarf2read.c	2006-11-02 15:34:07.000000000 -0600
+++ gdb-6.6-dfp/gdb/dwarf2read.c	2007-02-26 12:08:18.000000000 -0600
@@ -4829,6 +4829,9 @@ read_base_type (struct die_info *die, st
 	case DW_ATE_complex_float:
 	  code = TYPE_CODE_COMPLEX;
 	  break;
+	case DW_ATE_decimal_float:
+	  code = TYPE_CODE_DECFLOAT;
+	  break;
 	case DW_ATE_float:
 	  code = TYPE_CODE_FLT;
 	  break;
@@ -7635,6 +7638,18 @@ dwarf_base_type (int encoding, int size,
 	  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)
 	{
diff -pruN gdb-6.6/gdb/eval.c gdb-6.6-dfp/gdb/eval.c
--- gdb-6.6/gdb/eval.c	2006-10-09 22:17:53.000000000 -0500
+++ gdb-6.6-dfp/gdb/eval.c	2007-02-26 12:08:18.000000000 -0600
@@ -451,6 +451,11 @@ evaluate_subexp_standard (struct type *e
       return value_from_double (exp->elts[pc + 1].type,
 				exp->elts[pc + 2].doubleconst);
 
+    case OP_DECFLOAT:
+      (*pos) += 3;
+      return value_from_decfloat (expect_type, exp->elts[pc + 1].type,
+				exp->elts[pc + 2].decfloatconst);
+
     case OP_VAR_VALUE:
       (*pos) += 3;
       if (noside == EVAL_SKIP)
diff -pruN gdb-6.6/gdb/expression.h gdb-6.6-dfp/gdb/expression.h
--- gdb-6.6/gdb/expression.h	2006-10-09 22:17:53.000000000 -0500
+++ gdb-6.6-dfp/gdb/expression.h	2007-02-26 12:08:18.000000000 -0600
@@ -334,6 +334,11 @@ enum exp_opcode
     /* A F90 array range operator (for "exp:exp", "exp:", ":exp" and ":").  */
     OP_F90_RANGE,
 
+    /* OP_DECFLOAT 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_DECFLOAT.  */
+    OP_DECFLOAT,
+
      /* 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 
@@ -363,6 +368,7 @@ union exp_element
     DOUBLEST doubleconst;
     /* Really sizeof (union exp_element) characters (or less for the last
        element of a string).  */
+    gdb_byte decfloatconst[16];
     char string;
     struct type *type;
     struct internalvar *internalvar;
diff -pruN gdb-6.6/gdb/gdbtypes.c gdb-6.6-dfp/gdb/gdbtypes.c
--- gdb-6.6/gdb/gdbtypes.c	2006-08-22 14:45:12.000000000 -0500
+++ gdb-6.6-dfp/gdb/gdbtypes.c	2007-02-26 12:37:31.000000000 -0600
@@ -76,6 +76,12 @@ struct type *builtin_type_int128;
 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 @@ build_gdbtypes (void)
 #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_DECFLOAT, 32 / 8,
+	       0,
+	       "decimal float", (struct objfile *) NULL);
+  builtin_type_decdouble =
+    init_type (TYPE_CODE_DECFLOAT, 64 / 8,
+	       0,
+	       "decimal double", (struct objfile *) NULL);
+  builtin_type_declong =
+    init_type (TYPE_CODE_DECFLOAT, 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 @@ gdbtypes_post_init (struct gdbarch *gdba
 	       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_DECFLOAT, 32 / 8,
+               0,
+               "decimal float", (struct objfile *) NULL);
+  builtin_type->builtin_decdouble =
+    init_type (TYPE_CODE_DECFLOAT, 64 / 8,
+               0,
+               "decimal double", (struct objfile *) NULL);
+  builtin_type->builtin_declong =
+    init_type (TYPE_CODE_DECFLOAT, 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 @@ _initialize_gdbtypes (void)
   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
diff -pruN gdb-6.6/gdb/gdbtypes.h gdb-6.6-dfp/gdb/gdbtypes.h
--- gdb-6.6/gdb/gdbtypes.h	2006-02-01 17:14:10.000000000 -0600
+++ gdb-6.6-dfp/gdb/gdbtypes.h	2007-02-26 12:08:18.000000000 -0600
@@ -67,7 +67,12 @@ struct block;
 #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 @@ enum type_code
     TYPE_CODE_TEMPLATE,		/* C++ template */
     TYPE_CODE_TEMPLATE_ARG,	/* C++ template arg */
 
-    TYPE_CODE_NAMESPACE		/* C++ namespace.  */
+    TYPE_CODE_NAMESPACE,	/* C++ namespace.  */
+
+    TYPE_CODE_DECFLOAT		/* Decimal floating point.  */
   };
 
 /* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
@@ -1005,6 +1012,9 @@ struct builtin_type
   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_complex
 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
diff -pruN gdb-6.6/gdb/Makefile.in gdb-6.6-dfp/gdb/Makefile.in
--- gdb-6.6/gdb/Makefile.in	2006-11-24 13:54:14.000000000 -0600
+++ gdb-6.6-dfp/gdb/Makefile.in	2007-02-26 12:47:06.000000000 -0600
@@ -122,6 +122,12 @@ BFD = $(BFD_DIR)/libbfd.a
 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
@@ -354,7 +360,7 @@ CXXFLAGS = -g -O
 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_CPPFLAGS)
 INTERNAL_WARN_CFLAGS = $(INTERNAL_CFLAGS_BASE) $(GDB_WARN_CFLAGS)
 INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS)
@@ -377,10 +383,10 @@ INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CF
 # 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) $(LIBEXPAT) \
 	$(LIBIBERTY) $(WIN32LIBS)
@@ -611,6 +617,10 @@ splay_tree_h =  $(INCLUDE_DIR)/splay-tre
 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
 #
@@ -678,6 +688,7 @@ dictionary_h = dictionary.h
 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
@@ -925,7 +936,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
 	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 \
@@ -1944,6 +1955,7 @@ dummy-frame.o: dummy-frame.c $(defs_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)
+dfp.o: dfp.c $(defs_h) $(dfp_h) $(decimal128_h) $(decimal64_h) $(decimal32_h)
 dwarf2expr.o: dwarf2expr.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) \
 	$(gdbcore_h) $(elf_dwarf2_h) $(dwarf2expr_h)
 dwarf2-frame.o: dwarf2-frame.c $(defs_h) $(dwarf2expr_h) $(elf_dwarf2_h) \
@@ -2828,7 +2840,7 @@ valops.o: valops.c $(defs_h) $(symtab_h)
 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) \
diff -pruN gdb-6.6/gdb/parse.c gdb-6.6-dfp/gdb/parse.c
--- gdb-6.6/gdb/parse.c	2006-11-21 18:05:37.000000000 -0600
+++ gdb-6.6-dfp/gdb/parse.c	2007-02-26 12:08:18.000000000 -0600
@@ -251,6 +251,18 @@ write_exp_elt_dblcst (DOUBLEST expelt)
 }
 
 void
+write_exp_elt_decfloatcst (gdb_byte expelt[16])
+{
+  union exp_element tmp;
+  int index;
+
+  for (index = 0; index < 16; index++)
+    tmp.decfloatconst[index] = expelt[index];
+
+  write_exp_elt (tmp);
+}
+
+void
 write_exp_elt_type (struct type *expelt)
 {
   union exp_element tmp;
@@ -892,6 +904,7 @@ operator_length_standard (struct express
 
     case OP_LONG:
     case OP_DOUBLE:
+    case OP_DECFLOAT:
     case OP_VAR_VALUE:
       oplen = 4;
       break;
diff -pruN gdb-6.6/gdb/parser-defs.h gdb-6.6-dfp/gdb/parser-defs.h
--- gdb-6.6/gdb/parser-defs.h	2006-10-09 22:17:53.000000000 -0500
+++ gdb-6.6-dfp/gdb/parser-defs.h	2007-02-26 12:08:18.000000000 -0600
@@ -121,6 +121,8 @@ extern void write_exp_elt_longcst (LONGE
 
 extern void write_exp_elt_dblcst (DOUBLEST);
 
+extern void write_exp_elt_decfloatcst (gdb_byte *);
+
 extern void write_exp_elt_type (struct type *);
 
 extern void write_exp_elt_intern (struct internalvar *);
diff -pruN gdb-6.6/gdb/valarith.c gdb-6.6-dfp/gdb/valarith.c
--- gdb-6.6/gdb/valarith.c	2006-01-24 15:21:12.000000000 -0600
+++ gdb-6.6-dfp/gdb/valarith.c	2007-02-26 12:08:18.000000000 -0600
@@ -1378,6 +1378,20 @@ value_neg (struct value *arg1)
 
   type = check_typedef (value_type (arg1));
 
+  if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
+    {
+      struct value *val = allocate_value (result_type);
+      int len = TYPE_LENGTH (type);
+      gdb_byte *decbytes = (gdb_byte *) value_contents (arg1);
+
+      if (gdbarch_byte_order (current_gdbarch))
+	decbytes[len-1] = decbytes[len - 1] | 0x80;
+      else
+	decbytes[0] = decbytes[0] | 0x80;
+      memcpy (value_contents_raw (val), decbytes, 16);
+      return val;
+    }
+
   if (TYPE_CODE (type) == TYPE_CODE_FLT)
     return value_from_double (result_type, -value_as_double (arg1));
   else if (is_integral_type (type))
diff -pruN gdb-6.6/gdb/valprint.c gdb-6.6-dfp/gdb/valprint.c
--- gdb-6.6/gdb/valprint.c	2006-08-22 16:36:05.000000000 -0500
+++ gdb-6.6-dfp/gdb/valprint.c	2007-02-26 12:08:18.000000000 -0600
@@ -35,6 +35,7 @@
 #include "floatformat.h"
 #include "doublest.h"
 #include "exceptions.h"
+#include "dfp.h"
 
 #include <errno.h>
 
@@ -497,6 +498,18 @@ print_floating (const gdb_byte *valaddr,
 }
 
 void
+print_decimal_floating (const gdb_byte *valaddr, struct type *type,
+			struct ui_file *stream)
+{
+  char decstr[128];
+  unsigned len = TYPE_LENGTH (type);
+
+  decimal_to_string (valaddr, len, decstr);
+  fputs_filtered (decstr, stream);
+  return;
+}
+
+void
 print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
 		    unsigned len)
 {
diff -pruN gdb-6.6/gdb/value.c gdb-6.6-dfp/gdb/value.c
--- gdb-6.6/gdb/value.c	2006-03-31 04:36:18.000000000 -0600
+++ gdb-6.6-dfp/gdb/value.c	2007-02-26 12:08:18.000000000 -0600
@@ -37,6 +37,7 @@
 #include "gdb_assert.h"
 #include "regcache.h"
 #include "block.h"
+#include "dfp.h"
 
 /* Prototypes for exported functions. */
 
@@ -1610,6 +1611,27 @@ value_from_double (struct type *type, DO
 }
 
 struct value *
+value_from_decfloat (struct type *expect_type, struct type *type,
+		      gdb_byte decbytes[16])
+{
+  struct value *val = allocate_value (type);
+  int len = TYPE_LENGTH (type);
+
+  if (expect_type)
+    {
+      int expect_len = TYPE_LENGTH (expect_type);
+      char decstr[128];
+      int real_len;
+
+      decimal_to_string (decbytes, len, decstr);
+      decimal_from_string (decbytes, expect_len, decstr);
+    }
+
+  memcpy (value_contents_raw (val), decbytes, len);
+  return val;
+}
+
+struct value *
 coerce_ref (struct value *arg)
 {
   struct type *value_type_arg_tmp = check_typedef (value_type (arg));
diff -pruN gdb-6.6/gdb/value.h gdb-6.6-dfp/gdb/value.h
--- gdb-6.6/gdb/value.h	2006-11-24 13:59:57.000000000 -0600
+++ gdb-6.6-dfp/gdb/value.h	2007-02-26 12:08:18.000000000 -0600
@@ -274,6 +274,9 @@ extern LONGEST unpack_field_as_long (str
 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_decfloat (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);
@@ -476,6 +479,9 @@ extern void print_longest (struct ui_fil
 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]