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 INT %token FLOAT +%token DECFLOAT /* Both NAME and TYPENAME tokens represent symbols in the input, and both convey their data as strings. @@ -497,6 +503,13 @@ 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 + +/* 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 +#include +#include + +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 @@ -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);