Re: [patch/rfc] Add host's floatformat

Andrew Cagney
2004-05-03T19:11:47Z

[-- Attachment #1: Type: text/plain, Size: 383 bytes --]

> Minor request: the functions should have "get" in there somewhere,
> such as "floatformat_get_host_float" or "get_host_float_floatformat"
> or something. I can be talked out of this, though.

Per the attached, it looks too verbose. 'nuf talking?

> As for the code, I was thinking of something like this (probably got
> the bit patterns wrong):

Like this? I feel ill.

Andrew

[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 5287 bytes --]

Index: include/ChangeLog
2004-04-30 Andrew Cagney <cagney@redhat.com>

* floatformat.h (floatformat_get_host_float)
(floatformat_get_host_double)
(floatformat_get_host_long_double): Declare.

Index: libiberty/ChangeLog
2004-04-30 Andrew Cagney <cagney@redhat.com>

* 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