* doublest.c: Improve comments a bit.
authorMark Kettenis <kettenis@gnu.org>
Sun, 28 Oct 2001 22:06:27 +0000 (22:06 +0000)
committerMark Kettenis <kettenis@gnu.org>
Sun, 28 Oct 2001 22:06:27 +0000 (22:06 +0000)
(floatformat_from_length): New function.
(NAN): Define to 0.0 if not already defined.
(extract_floating): Rewrite to use floatformat_from_length.  Warn
instead of error if LEN doesn't match a known floating-point type,
and return NaN (or 0.0 if NaN isn't available) in that case.
(store_floating): Likewise, but zero out the target byte-stream if
LEN doesn't match a known floating-point type.
(extract_typed_floating): Reformat a bit.
(store_typed_floating): Reformat a bit.  Add comment about zeroing
out padding in the target buffer.
* doublest.h (extract_floating, store_floating): Fix comment about
deprecation of these functions.  Add parameter names to prototypes.

gdb/ChangeLog
gdb/doublest.c
gdb/doublest.h

index fad9d4a6a4bc1709d87e1726dcb8fce7707cc36a..67e27fe4f226db6e524683a39189822e13d91926 100644 (file)
@@ -1,3 +1,19 @@
+2001-10-28  Mark Kettenis  <kettenis@gnu.org>
+
+       * doublest.c: Improve comments a bit.
+       (floatformat_from_length): New function.
+       (NAN): Define to 0.0 if not already defined.
+       (extract_floating): Rewrite to use floatformat_from_length.  Warn
+       instead of error if LEN doesn't match a known floating-point type,
+       and return NaN (or 0.0 if NaN isn't available) in that case.
+       (store_floating): Likewise, but zero out the target byte-stream if
+       LEN doesn't match a known floating-point type.
+       (extract_typed_floating): Reformat a bit.
+       (store_typed_floating): Reformat a bit.  Add comment about zeroing
+       out padding in the target buffer.
+       * doublest.h (extract_floating, store_floating): Fix comment about
+       deprecation of these functions.  Add parameter names to prototypes.
+
 2001-10-28  Mark Kettenis  <kettenis@gnu.org>
 
        * i387-tdep.c (print_i387_value): Use extract_typed_floating to
index e2dd3e896dc00345836c223134484b13d1f3e5fb..2fbf3755cbb00735ea3af71d6327d6b624b5fea5 100644 (file)
@@ -532,7 +532,6 @@ floatformat_mantissa (const struct floatformat *fmt, char *val)
   return res;
 }
 
-
 \f
 /* Convert TO/FROM target to the hosts DOUBLEST floating-point format.
 
@@ -607,84 +606,118 @@ floatformat_from_doublest (const struct floatformat *fmt,
 }
 
 \f
-/* Extract/store a target floating-point number from byte-stream at
-   ADDR to/from a DOUBLEST.  The LEN is used to select between the
-   pre-defined target type FLOAT, DOUBLE or LONG_DOUBLE.  These
-   functions are used when extract/store typed floating() find that
-   the ``struct type'' did not include a FLOATFORMAT (e.g. some symbol
-   table readers and XXX-language support modules).  */
+/* Return a floating-point format for a floating-point variable of
+   length LEN.  Return NULL, if no suitable floating-point format
+   could be found.
 
-DOUBLEST
-extract_floating (const void *addr, int len)
+   We need this functionality since information about the
+   floating-point format of a type is not always available to GDB; the
+   debug information typically only tells us the size of a
+   floating-point type.
+
+   FIXME: kettenis/2001-10-28: In many places, particularly in
+   target-dependent code, the format of floating-point types is known,
+   but not passed on by GDB.  This should be fixed.  */
+
+static const struct floatformat *
+floatformat_from_length (int len)
 {
-  DOUBLEST dretval;
   if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
-    {
-      floatformat_to_doublest (TARGET_FLOAT_FORMAT, addr, &dretval);
-    }
+    return TARGET_FLOAT_FORMAT;
   else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
-    {
-      floatformat_to_doublest (TARGET_DOUBLE_FORMAT, addr, &dretval);
-    }
+    return TARGET_DOUBLE_FORMAT;
   else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
+    return TARGET_LONG_DOUBLE_FORMAT;
+
+  return NULL;
+}
+
+/* If the host doesn't define NAN, use zero instead.  */
+#ifndef NAN
+#define NAN 0.0
+#endif
+
+/* Extract a floating-point number of length LEN from a target-order
+   byte-stream at ADDR.  Returns the value as type DOUBLEST.  */
+
+DOUBLEST
+extract_floating (const void *addr, int len)
+{
+  const struct floatformat *fmt = floatformat_from_length (len);
+  DOUBLEST val;
+
+  if (fmt == NULL)
     {
-      floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval);
-    }
-  else
-    {
-      error ("Can't deal with a floating point number of %d bytes.", len);
+      warning ("Can't store a floating-point number of %d bytes.", len);
+      return NAN;
     }
-  return dretval;
+
+  floatformat_to_doublest (fmt, addr, &val);
+  return val;
 }
 
+/* Store VAL as a floating-point number of length LEN to a
+   target-order byte-stream at ADDR.  */
+
 void
 store_floating (void *addr, int len, DOUBLEST val)
 {
-  if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
-    {
-      floatformat_from_doublest (TARGET_FLOAT_FORMAT, &val, addr);
-    }
-  else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
-    {
-      floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &val, addr);
-    }
-  else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
-    {
-      floatformat_from_doublest (TARGET_LONG_DOUBLE_FORMAT, &val, addr);
-    }
-  else
+  const struct floatformat *fmt = floatformat_from_length (len);
+
+  if (fmt == NULL)
     {
-      error ("Can't deal with a floating point number of %d bytes.", len);
+      warning ("Can't store a floating-point number of %d bytes.", len);
+      memset (addr, 0, len);
     }
+
+  floatformat_from_doublest (fmt, &val, addr);
 }
 
-/* Extract/store a floating-point number of format TYPE from a
-   target-ordered byte-stream at ADDR to/from an internal DOUBLEST
-   accroding to its TYPE_FORMAT().  When GDB reads in debug
-   information, it is sometimes only provided with the type name, its
-   length and the fact that it is a float (TYPE_FORMAT() is not set).
-   For such types, the old extract/store floating() functions are
-   used. */
+/* Extract a floating-point number of type TYPE from a target-order
+   byte-stream at ADDR.  Returns the value as type DOUBLEST.  */
 
 DOUBLEST
 extract_typed_floating (const void *addr, const struct type *type)
 {
   DOUBLEST retval;
+
   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+
   if (TYPE_FLOATFORMAT (type) == NULL)
-    retval = extract_floating (addr, TYPE_LENGTH (type));
-  else
-    floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval);
+    return extract_floating (addr, TYPE_LENGTH (type));
+
+  floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval);
   return retval;
 }
 
+/* Store VAL as a floating-point number of type TYPE to a target-order
+   byte-stream at ADDR.  */
+
 void
 store_typed_floating (void *addr, const struct type *type, DOUBLEST val)
 {
   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+
+  /* FIXME: kettenis/2001-10-28: It is debatable whether we should
+     zero out any remaining bytes in the target buffer when TYPE is
+     longer than the actual underlying floating-point format.  Perhaps
+     we should store a fixed bitpattern in those remaining bytes,
+     instead of zero, or perhaps we shouldn't touch those remaining
+     bytes at all.
+
+     NOTE: cagney/2001-10-28: With the way things currently work, it
+     isn't a good idea to leave the end bits undefined.  This is
+     because GDB writes out the entire sizeof(<floating>) bits of the
+     floating-point type even though the value might only be stored
+     in, and the target processor may only refer to, the first N <
+     TYPE_LENGTH (type) bits.  If the end of the buffer wasn't
+     initialized, GDB would write undefined data to the target.  An
+     errant program, refering to that undefined data, would then
+     become non-deterministic.  */
   memset (addr, 0, TYPE_LENGTH (type));
+
   if (TYPE_FLOATFORMAT (type) == NULL)
-    store_floating (addr, TYPE_LENGTH (type), val);
-  else
-    floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr);
+    return store_floating (addr, TYPE_LENGTH (type), val);
+
+  floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr);
 }
index d3955b37955b2f4aa83facfc716e693bcee91eb1..a31d8497fd1a462d50cef815b7b2f79d08b3264d 100644 (file)
@@ -61,9 +61,12 @@ extern int floatformat_is_negative (const struct floatformat *, char *);
 extern int floatformat_is_nan (const struct floatformat *, char *);
 extern char *floatformat_mantissa (const struct floatformat *, char *);
 
-/* Use extract_typed_float() and store_typed_float(). */
-extern DOUBLEST extract_floating (const void *in, int); /* DEPRECATED */
-extern void store_floating (void *, int, DOUBLEST); /* DEPRECATED */
+/* These two functions are deprecated in favour of
+   extract_typed_floating and store_typed_floating.  See comments in
+   'doublest.c' for details.  */
+
+extern DOUBLEST extract_floating (const void *addr, int len);
+extern void store_floating (void *addr, int len, DOUBLEST val);
 
 extern DOUBLEST extract_typed_floating (const void *addr,
                                        const struct type *type);