* Re: [RFC] Restructure doublest.c a bit
@ 2001-10-28 14:06 Mark Kettenis
0 siblings, 0 replies; 3+ messages in thread
From: Mark Kettenis @ 2001-10-28 14:06 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
OK. I added the note. Here's what I actually checked in.
Mark
Index: ChangeLog
from 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>
Index: doublest.c
===================================================================
RCS file: /cvs/src/src/gdb/doublest.c,v
retrieving revision 1.4
diff -u -p -r1.4 doublest.c
--- doublest.c 2001/09/24 17:16:53 1.4
+++ doublest.c 2001/10/28 22:01:32
@@ -532,7 +532,6 @@ floatformat_mantissa (const struct float
return res;
}
-
\f
/* Convert TO/FROM target to the hosts DOUBLEST floating-point format.
@@ -607,84 +606,118 @@ floatformat_from_doublest (const struct
}
\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.
+
+ 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. */
-DOUBLEST
-extract_floating (const void *addr, int len)
+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)
- {
- floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval);
- }
- else
+ 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)
{
- 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: doublest.h
===================================================================
RCS file: /cvs/src/src/gdb/doublest.h,v
retrieving revision 1.5
diff -u -p -r1.5 doublest.h
--- doublest.h 2001/09/24 17:16:53 1.5
+++ doublest.h 2001/10/28 22:01:32
@@ -61,9 +61,12 @@ extern int floatformat_is_negative (cons
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);
^ permalink raw reply [flat|nested] 3+ messages in thread* [RFC] Restructure doublest.c a bit
@ 2001-10-28 4:39 Mark Kettenis
2001-10-28 11:22 ` Andrew Cagney
0 siblings, 1 reply; 3+ messages in thread
From: Mark Kettenis @ 2001-10-28 4:39 UTC (permalink / raw)
To: ac131313, gdb-patches
Here's a patch that restructures doublest.c a bit. It moves the logic
to determine the floating-point format from the length of a
floating-point variable into a special function. It also turns the
error that would occur when the floating-point format could not be
guessed into a warning, and tries to return a NaN in that case.
Andrew, what do you think? I'd like to check this in such that I can
make changes that will change the type of the i387 floating-point
registers to i386_ext.
Mark
Index: ChangeLog
from 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.
Index: doublest.c
===================================================================
RCS file: /cvs/src/src/gdb/doublest.c,v
retrieving revision 1.4
diff -u -p -r1.4 doublest.c
--- doublest.c 2001/09/24 17:16:53 1.4
+++ doublest.c 2001/10/28 12:33:26
@@ -532,7 +532,6 @@ floatformat_mantissa (const struct float
return res;
}
-
\f
/* Convert TO/FROM target to the hosts DOUBLEST floating-point format.
@@ -607,84 +606,108 @@ floatformat_from_doublest (const struct
}
\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.
+
+ 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. */
-DOUBLEST
-extract_floating (const void *addr, int len)
+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)
- {
- floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval);
- }
- else
+ 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)
{
- 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-06: 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. */
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: doublest.h
===================================================================
RCS file: /cvs/src/src/gdb/doublest.h,v
retrieving revision 1.5
diff -u -p -r1.5 doublest.h
--- doublest.h 2001/09/24 17:16:53 1.5
+++ doublest.h 2001/10/28 12:33:26
@@ -61,9 +61,12 @@ extern int floatformat_is_negative (cons
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);
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [RFC] Restructure doublest.c a bit
2001-10-28 4:39 Mark Kettenis
@ 2001-10-28 11:22 ` Andrew Cagney
0 siblings, 0 replies; 3+ messages in thread
From: Andrew Cagney @ 2001-10-28 11:22 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
Yes fine.
> +
> + /* FIXME: kettenis/2001-10-06: 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. */
>
Can you add this:
/* 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(<float>) 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<LENGTH 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 would become
non-deterministic. */
enjoy,
Andrew
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2001-10-28 14:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-28 14:06 [RFC] Restructure doublest.c a bit Mark Kettenis
-- strict thread matches above, loose matches on Subject: below --
2001-10-28 4:39 Mark Kettenis
2001-10-28 11:22 ` Andrew Cagney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox