* 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.
This commit is contained in:
Mark Kettenis 2001-10-28 22:06:27 +00:00
parent 4583280ca5
commit 87ffba60fb
3 changed files with 105 additions and 53 deletions

View 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

View file

@ -532,7 +532,6 @@ floatformat_mantissa (const struct floatformat *fmt, char *val)
return res;
}
/* Convert TO/FROM target to the hosts DOUBLEST floating-point format.
@ -607,84 +606,118 @@ floatformat_from_doublest (const struct floatformat *fmt,
}
/* 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. */
static const struct floatformat *
floatformat_from_length (int len)
{
if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
return TARGET_FLOAT_FORMAT;
else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
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)
{
DOUBLEST dretval;
if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
const struct floatformat *fmt = floatformat_from_length (len);
DOUBLEST val;
if (fmt == NULL)
{
floatformat_to_doublest (TARGET_FLOAT_FORMAT, addr, &dretval);
warning ("Can't store a floating-point number of %d bytes.", len);
return NAN;
}
else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
{
floatformat_to_doublest (TARGET_DOUBLE_FORMAT, addr, &dretval);
}
else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
{
floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval);
}
else
{
error ("Can't deal with a floating point number of %d bytes.", len);
}
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)
const struct floatformat *fmt = floatformat_from_length (len);
if (fmt == NULL)
{
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
{
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);
}

View 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);