This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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

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
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]