* doublest.h (convert_typed_floating): New prototype.
authorMark Kettenis <kettenis@gnu.org>
Mon, 29 Oct 2001 23:35:37 +0000 (23:35 +0000)
committerMark Kettenis <kettenis@gnu.org>
Mon, 29 Oct 2001 23:35:37 +0000 (23:35 +0000)
* doublest.c (convert_typed_floating): New function.

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

index 67e27fe4f226db6e524683a39189822e13d91926..5f4c9ef1e7ba3d1bd883f67c3d28029201323c9d 100644 (file)
@@ -1,3 +1,8 @@
+2001-10-29  Mark Kettenis  <kettenis@gnu.org>
+
+       * doublest.h (convert_typed_floating): New prototype.
+       * doublest.c (convert_typed_floating): New function.
+
 2001-10-28  Mark Kettenis  <kettenis@gnu.org>
 
        * doublest.c: Improve comments a bit.
index 2fbf3755cbb00735ea3af71d6327d6b624b5fea5..083a50a98aa1f2dc4570f2a9c6d1ec64b2f95bc4 100644 (file)
@@ -713,7 +713,9 @@ store_typed_floating (void *addr, const struct type *type, DOUBLEST val)
      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.  */
+     become non-deterministic.
+
+     See also the function convert_typed_floating below.  */
   memset (addr, 0, TYPE_LENGTH (type));
 
   if (TYPE_FLOATFORMAT (type) == NULL)
@@ -721,3 +723,60 @@ store_typed_floating (void *addr, const struct type *type, DOUBLEST val)
 
   floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr);
 }
+
+/* Convert a floating-point number of type FROM_TYPE from a
+   target-order byte-stream at FROM to a floating-point number of type
+   TO_TYPE, and store it to a target-order byte-stream at TO.  */
+
+void
+convert_typed_floating (const void *from, const struct type *from_type,
+                        void *to, const struct type *to_type)
+{
+  const struct floatformat *from_fmt = TYPE_FLOATFORMAT (from_type);
+  const struct floatformat *to_fmt = TYPE_FLOATFORMAT (to_type);
+
+  gdb_assert (TYPE_CODE (from_type) == TYPE_CODE_FLT);
+  gdb_assert (TYPE_CODE (to_type) == TYPE_CODE_FLT);
+
+  /* If the floating-point format of FROM_TYPE or TO_TYPE isn't known,
+     try to guess it from the type's length.  */
+  if (from_fmt == NULL)
+    from_fmt = floatformat_from_length (TYPE_LENGTH (from_type));
+  if (to_fmt == NULL)
+    to_fmt = floatformat_from_length (TYPE_LENGTH (to_type));
+
+  if (from_fmt == NULL || to_fmt == NULL)
+    {
+      /* If we don't know the floating-point format of FROM_TYPE or
+         TO_TYPE, there's not much we can do.  We might make the
+         assumption that if the length of FROM_TYPE and TO_TYPE match,
+         their floating-point format would match too, but that
+         assumption might be wrong on targets that support
+         floating-point types that only differ in endianness for
+         example.  So we warn instead, and zero out the target buffer.  */
+      warning ("Can't convert floating-point number to desired type.");
+      memset (to, 0, TYPE_LENGTH (to_type));
+    }
+  else if (from_fmt == to_fmt)
+    {
+      /* We're in business.  The floating-point format of FROM_TYPE
+         and TO_TYPE match.  However, even though the floating-point
+         format matches, the length of the type might still be
+         different.  Make sure we don't overrun any buffers.  See
+         comment in store_typed_floating for a discussion about
+         zeroing out remaining bytes in the target buffer.  */
+      memset (to, 0, TYPE_LENGTH (to_type));
+      memcpy (to, from, min (TYPE_LENGTH (from_type), TYPE_LENGTH (to_type)));
+    }
+  else
+    {
+      /* The floating-point types don't match.  The best we can do
+         (aport from simulating the target FPU) is converting to the
+         widest floating-point type supported by the host, and then
+         again to the desired type.  */
+      DOUBLEST d;
+
+      floatformat_to_doublest (from_fmt, from, &d);
+      floatformat_from_doublest (to_fmt, &d, to);
+    }
+}
index a31d8497fd1a462d50cef815b7b2f79d08b3264d..ccd92336275250abf622333873adb231a4b59f5c 100644 (file)
@@ -72,5 +72,8 @@ extern DOUBLEST extract_typed_floating (const void *addr,
                                        const struct type *type);
 extern void store_typed_floating (void *addr, const struct type *type,
                                  DOUBLEST val);
+extern void convert_typed_floating (const void *from,
+                                   const struct type *from_type,
+                                    void *to, const struct type *to_type);
 
 #endif