aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Jung Bauermann <bauerman@br.ibm.com>2007-10-25 17:52:32 +0000
committerThiago Jung Bauermann <bauerman@br.ibm.com>2007-10-25 17:52:32 +0000
commit9b913628cfe092b3fdd328de4264def1ec1e94cb (patch)
treeff478f2ba89a0537777a3cebad52b198b46faa57
parentc6e653525f8ea3235ab15b974cb9cf9ee686bf8e (diff)
downloadgdb-9b913628cfe092b3fdd328de4264def1ec1e94cb.zip
gdb-9b913628cfe092b3fdd328de4264def1ec1e94cb.tar.gz
gdb-9b913628cfe092b3fdd328de4264def1ec1e94cb.tar.bz2
2007-10-25 Wu Zhou <woodzltc@cn.ibm.com>
Thiago Jung Bauermann <bauerman@br.ibm.com> * Makefile.in (LIBDECNUMBER_DIR, LIBDECNUMBER, LIBDECNUMBER_SRC LIBDECNUMBER_CFLAGS): New macros for libdecnumber. (INTERNAL_CFLAGS_BASE): Add LIBDECNUMBER_CFLAGS in. (INSTALLED_LIBS): Add -ldecnumber in. (CLIBS): Add LIBDECNUMBER in. (decimal128_h, decimal64_h, decimal32_h): New macros for decimal headers. (dfp_h): New macros for decimal floating point. (dfp.o): New target. (COMMON_OBS): Add dfp.o in. (c-exp.o): Add dfp_h as dependency. (valprint.o): Add dfp_h as dependency. (value.o): Add dfp_h as dependency. * 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. * configure.ac: Add AC_C_BIGENDIAN test. * config.in, configure: Regenerate.
-rw-r--r--gdb/ChangeLog24
-rw-r--r--gdb/Makefile.in26
-rw-r--r--gdb/config.in4
-rwxr-xr-xgdb/configure230
-rw-r--r--gdb/configure.ac1
-rw-r--r--gdb/dfp.c113
-rw-r--r--gdb/dfp.h35
7 files changed, 426 insertions, 7 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 82eaeb3..530adc6 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,27 @@
+2007-10-25 Wu Zhou <woodzltc@cn.ibm.com>
+ Thiago Jung Bauermann <bauerman@br.ibm.com>
+
+ * Makefile.in (LIBDECNUMBER_DIR, LIBDECNUMBER, LIBDECNUMBER_SRC
+ LIBDECNUMBER_CFLAGS): New macros for libdecnumber.
+ (INTERNAL_CFLAGS_BASE): Add LIBDECNUMBER_CFLAGS in.
+ (INSTALLED_LIBS): Add -ldecnumber in.
+ (CLIBS): Add LIBDECNUMBER in.
+ (decimal128_h, decimal64_h, decimal32_h): New macros for decimal
+ headers.
+ (dfp_h): New macros for decimal floating point.
+ (dfp.o): New target.
+ (COMMON_OBS): Add dfp.o in.
+ (c-exp.o): Add dfp_h as dependency.
+ (valprint.o): Add dfp_h as dependency.
+ (value.o): Add dfp_h as dependency.
+ * 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.
+ * configure.ac: Add AC_C_BIGENDIAN test.
+ * config.in, configure: Regenerate.
+
2007-10-25 David Ung <davidu@mips.com>
Maciej W. Rozycki <macro@mips.com>
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 36ed948..52c6035 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -125,6 +125,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_SRC = $(srcdir)/$(READLINE_DIR)
@@ -358,7 +364,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)
@@ -381,10 +387,10 @@ INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(MH_LDFLAGS) $(LDFLAGS) $(CONFIG_
# 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)
@@ -623,6 +629,10 @@ safe_ctype_h = $(INCLUDE_DIR)/safe-ctype.h
hashtab_h = $(INCLUDE_DIR)/hashtab.h
filenames_h = $(INCLUDE_DIR)/filenames.h
+decimal128_h = $(LIBDECNUMBER_DIR)/dpd/decimal128.h
+decimal64_h = $(LIBDECNUMBER_DIR)/dpd/decimal64.h
+decimal32_h = $(LIBDECNUMBER_DIR)/dpd/decimal32.h
+
#
# $BUILD/ headers
#
@@ -689,6 +699,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
@@ -959,7 +970,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
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 \
@@ -1893,7 +1904,7 @@ buildsym.o: buildsym.c $(defs_h) $(bfd_h) $(gdb_obstack_h) $(symtab_h) \
$(cp_support_h) $(dictionary_h) $(buildsym_h) $(stabsread_h)
c-exp.o: c-exp.c $(defs_h) $(gdb_string_h) $(expression_h) $(value_h) \
$(parser_defs_h) $(language_h) $(c_lang_h) $(bfd_h) $(symfile_h) \
- $(objfiles_h) $(charset_h) $(block_h) $(cp_support_h)
+ $(objfiles_h) $(charset_h) $(block_h) $(cp_support_h) $(dfp_h)
charset.o: charset.c $(defs_h) $(charset_h) $(gdbcmd_h) $(gdb_assert_h) \
$(gdb_string_h)
c-lang.o: c-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
@@ -1976,6 +1987,7 @@ dsrec.o: dsrec.c $(defs_h) $(serial_h) $(srec_h) $(gdb_assert_h) \
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)
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) \
@@ -2847,11 +2859,11 @@ valops.o: valops.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) $(frame_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) $(demangle_h) $(doublest_h) \
- $(gdb_assert_h) $(regcache_h) $(block_h)
+ $(gdb_assert_h) $(regcache_h) $(block_h) $(dfp_h)
varobj.o: varobj.c $(defs_h) $(exceptions_h) $(value_h) $(expression_h) \
$(frame_h) $(language_h) $(wrapper_h) $(gdbcmd_h) $(block_h) \
$(gdb_assert_h) $(gdb_string_h) $(varobj_h) $(vec_h)
diff --git a/gdb/config.in b/gdb/config.in
index 39e00e0..eb82da0 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -586,6 +586,10 @@
/* Define if the simulator is being linked in. */
#undef WITH_SIM
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
/* Define to 1 if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
diff --git a/gdb/configure b/gdb/configure
index ebd6980..ea65297 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -15804,6 +15804,236 @@ _ACEOF
;;
esac
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_bigendian=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+ # try to guess the endianness by grepping values into an object file
+ ac_cv_c_bigendian=unknown
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+ ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+fi
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+main ()
+{
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_bigendian=no
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+ yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+ no)
+ ;;
+ *)
+ { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+
# ------------------------------ #
# Checks for library functions. #
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 491e753..eab68b0 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -502,6 +502,7 @@ AC_CHECK_TYPES(uintptr_t, [], [], [#include <stdint.h>])
AC_C_CONST
AC_C_INLINE
+AC_C_BIGENDIAN
# ------------------------------ #
# Checks for library functions. #
diff --git a/gdb/dfp.c b/gdb/dfp.c
new file mode 100644
index 0000000..67cee13
--- /dev/null
+++ b/gdb/dfp.c
@@ -0,0 +1,113 @@
+/* Decimal floating point support for GDB.
+
+ Copyright 2007 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+
+/* The order of the following headers is important for making sure
+ decNumber structure is large enough to hold decimal128 digits. */
+
+#include "dpd/decimal128.h"
+#include "dpd/decimal64.h"
+#include "dpd/decimal32.h"
+
+/* In GDB, we are using an array of gdb_byte to represent decimal values.
+ They are stored in host byte order. This routine does the conversion if
+ the target byte order is different. */
+static void
+match_endianness (const gdb_byte *from, int len, gdb_byte *to)
+{
+ int i;
+
+#if WORDS_BIGENDIAN
+#define OPPOSITE_BYTE_ORDER BFD_ENDIAN_LITTLE
+#else
+#define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
+#endif
+
+ if (gdbarch_byte_order (current_gdbarch) == OPPOSITE_BYTE_ORDER)
+ for (i = 0; i < len; i++)
+ to[i] = from[len - i - 1];
+ else
+ for (i = 0; i < len; i++)
+ to[i] = from[i];
+
+ return;
+}
+
+/* Convert decimal 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 gdb_byte *decbytes, int len, char *s)
+{
+ gdb_byte dec[16];
+
+ match_endianness (decbytes, len, dec);
+ switch (len)
+ {
+ case 4:
+ decimal32ToString ((decimal32 *) dec, s);
+ break;
+ case 8:
+ decimal64ToString ((decimal64 *) dec, s);
+ break;
+ case 16:
+ decimal128ToString ((decimal128 *) dec, s);
+ break;
+ default:
+ error (_("Unknown decimal floating point type.\n"));
+ break;
+ }
+}
+
+/* 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 (gdb_byte *decbytes, int len, const char *string)
+{
+ decContext set;
+ gdb_byte dec[16];
+
+ switch (len)
+ {
+ case 4:
+ decContextDefault (&set, DEC_INIT_DECIMAL32);
+ set.traps = 0;
+ decimal32FromString ((decimal32 *) dec, string, &set);
+ break;
+ case 8:
+ decContextDefault (&set, DEC_INIT_DECIMAL64);
+ set.traps = 0;
+ decimal64FromString ((decimal64 *) dec, string, &set);
+ break;
+ case 16:
+ decContextDefault (&set, DEC_INIT_DECIMAL128);
+ set.traps = 0;
+ decimal128FromString ((decimal128 *) dec, string, &set);
+ break;
+ default:
+ error (_("Unknown decimal floating point type.\n"));
+ break;
+ }
+
+ match_endianness (dec, len, decbytes);
+
+ return 1;
+}
diff --git a/gdb/dfp.h b/gdb/dfp.h
new file mode 100644
index 0000000..75481b9
--- /dev/null
+++ b/gdb/dfp.h
@@ -0,0 +1,35 @@
+/* Decimal floating point support for GDB.
+
+ Copyright 2007 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+/* 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. */
+
+#ifndef DFP_H
+#define DFP_H
+
+/* When using decimal128, this is the maximum string length + 1
+ * (value comes from libdecnumber's DECIMAL128_String constant). */
+#define MAX_DECIMAL_STRING 43
+
+extern void decimal_to_string (const gdb_byte *, int, char *);
+extern int decimal_from_string (gdb_byte *, int, const char *);
+
+#endif