Index: include/ChangeLog 2004-04-30 Andrew Cagney * floatformat.h (floatformat_get_host_float) (floatformat_get_host_double) (floatformat_get_host_long_double): Declare. Index: libiberty/ChangeLog 2004-04-30 Andrew Cagney * configure.ac: Define HOST_LONG_DOUBLE. * configure, config.in: Re-generate. * floatformat.c (struct host_format, struct probe_state) (probe_host_format, floatformat_get_host_float) (floatformat_get_host_double, floatformat_get_host_long_double): New. Find/return the floatformat corresponding to the host's float, double and long double types. Index: include/floatformat.h =================================================================== RCS file: /cvs/src/src/include/floatformat.h,v retrieving revision 1.9 diff -p -u -r1.9 floatformat.h --- include/floatformat.h 22 Sep 2003 17:41:02 -0000 1.9 +++ include/floatformat.h 3 May 2004 19:08:02 -0000 @@ -1,5 +1,7 @@ /* IEEE floating point support declarations, for GDB, the GNU Debugger. - Copyright 1991, 1994, 1995, 1997, 2000, 2003 Free Software Foundation, Inc. + + Copyright 1991, 1994, 1995, 1997, 2000, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -129,5 +131,11 @@ floatformat_from_double PARAMS ((const s extern int floatformat_is_valid PARAMS ((const struct floatformat *fmt, const char *from)); + +/* If non-NULL, the host's floatformat corresponding to the compilers + "float", "double" and "long double" types. */ +extern const struct floatformat *floatformat_get_host_float PARAMS ((void)); +extern const struct floatformat *floatformat_get_host_double PARAMS ((void)); +extern const struct floatformat *floatformat_get_host_long_double PARAMS ((void)); #endif /* defined (FLOATFORMAT_H) */ Index: libiberty/configure.ac =================================================================== RCS file: /cvs/src/src/libiberty/configure.ac,v retrieving revision 1.6 diff -p -u -r1.6 configure.ac --- libiberty/configure.ac 26 Apr 2004 18:23:59 -0000 1.6 +++ libiberty/configure.ac 3 May 2004 19:08:04 -0000 @@ -520,6 +520,18 @@ case "${host}" in esac AC_SUBST(pexecute) +dnl See if compiler supports "long double" type. Can't use AC_C_LONG_DOUBLE +dnl because autoconf complains about cross-compilation issues. However, this +dnl code uses the same variables as the macro for compatibility. +AC_MSG_CHECKING(for long double support in compiler) +AC_CACHE_VAL(ac_cv_c_long_double, +[AC_TRY_COMPILE(, [long double foo;], +ac_cv_c_long_double=yes, ac_cv_c_long_double=no)]) +AC_MSG_RESULT($ac_cv_c_long_double) +if test $ac_cv_c_long_double = yes; then + AC_DEFINE(HAVE_LONG_DOUBLE) +fi + libiberty_AC_FUNC_STRNCMP # Install a library built with a cross compiler in $(tooldir) rather Index: libiberty/floatformat.c =================================================================== RCS file: /cvs/src/src/libiberty/floatformat.c,v retrieving revision 1.12 diff -p -u -r1.12 floatformat.c --- libiberty/floatformat.c 3 Dec 2003 19:03:29 -0000 1.12 +++ libiberty/floatformat.c 3 May 2004 19:08:04 -0000 @@ -1,5 +1,7 @@ /* IEEE floating point support routines, for GDB, the GNU Debugger. - Copyright (C) 1991, 1994, 1999, 2000, 2003 Free Software Foundation, Inc. + + Copyright 1991, 1994, 1999, 2000, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -548,6 +550,78 @@ floatformat_is_valid (fmt, from) return fmt->is_valid (fmt, from); } +/* If non-NULL, the host's floatformat. */ + +struct host_format +{ + long size; + const struct floatformat *ff; + /* Use "(gdb) x/16ob &val" to get the value. */ + const char *bits; +}; + +struct probe_state +{ + int probed; + const struct floatformat *ff; +}; + +static const struct floatformat * +probe_host_format (struct probe_state *state, const void *one, long sizeof_one) +{ + static struct host_format host_one[] = { + { 4, &floatformat_ieee_single_big, "\77\200\0\0" }, + { 4, &floatformat_ieee_single_little, "\0\0\200\77" }, + { 8, &floatformat_ieee_double_big, "\77\360\0\0\0\0\0\0" }, + { 8, &floatformat_ieee_double_little, "\0\0\0\0\0\0\360\77" }, + { 16, &floatformat_i387_ext, "\0\0\0\0\0\0\0\200\377\77\0\0\0\0\0\0" }, + { 0, NULL, NULL } + }; + if (!state->probed) + { + const struct host_format *ff; + + state->probed = 1; + for (ff = host_one; ff->ff != NULL; ff++) + { + if (sizeof_one == ff->size + && memcmp (one, ff->bits, sizeof_one) == 0) + { + state->ff = ff->ff; + break; + } + } + } + return state->ff; +} + +const struct floatformat * +floatformat_get_host_float () +{ + static float one = 1.0; + static struct probe_state probe_state; + return probe_host_format (&probe_state, &one, sizeof (one)); +} + +const struct floatformat * +floatformat_get_host_double () +{ + static double one = 1.0; + static struct probe_state probe_state; + return probe_host_format (&probe_state, &one, sizeof (one)); +} + +const struct floatformat * +floatformat_get_host_long_double () +{ +#if HAVE_LONG_DOUBLE + static long double one = 1.0; + static struct probe_state probe_state; + return probe_host_format (&probe_state, &one, sizeof (one)); +#else + return NULL; +#endif +} #ifdef IEEE_DEBUG