diff options
-rw-r--r-- | gdb/ChangeLog | 24 | ||||
-rw-r--r-- | gdb/Makefile.in | 26 | ||||
-rw-r--r-- | gdb/config.in | 4 | ||||
-rwxr-xr-x | gdb/configure | 230 | ||||
-rw-r--r-- | gdb/configure.ac | 1 | ||||
-rw-r--r-- | gdb/dfp.c | 113 | ||||
-rw-r--r-- | gdb/dfp.h | 35 |
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 |