* 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:
parent
4583280ca5
commit
87ffba60fb
3 changed files with 105 additions and 53 deletions
|
@ -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>
|
2001-10-28 Mark Kettenis <kettenis@gnu.org>
|
||||||
|
|
||||||
* i387-tdep.c (print_i387_value): Use extract_typed_floating to
|
* i387-tdep.c (print_i387_value): Use extract_typed_floating to
|
||||||
|
|
129
gdb/doublest.c
129
gdb/doublest.c
|
@ -532,7 +532,6 @@ floatformat_mantissa (const struct floatformat *fmt, char *val)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Convert TO/FROM target to the hosts DOUBLEST floating-point format.
|
/* 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
|
/* Return a floating-point format for a floating-point variable of
|
||||||
ADDR to/from a DOUBLEST. The LEN is used to select between the
|
length LEN. Return NULL, if no suitable floating-point format
|
||||||
pre-defined target type FLOAT, DOUBLE or LONG_DOUBLE. These
|
could be found.
|
||||||
functions are used when extract/store typed floating() find that
|
|
||||||
the ``struct type'' did not include a FLOATFORMAT (e.g. some symbol
|
We need this functionality since information about the
|
||||||
table readers and XXX-language support modules). */
|
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
|
DOUBLEST
|
||||||
extract_floating (const void *addr, int len)
|
extract_floating (const void *addr, int len)
|
||||||
{
|
{
|
||||||
DOUBLEST dretval;
|
const struct floatformat *fmt = floatformat_from_length (len);
|
||||||
if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
|
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 (fmt, addr, &val);
|
||||||
floatformat_to_doublest (TARGET_DOUBLE_FORMAT, addr, &dretval);
|
return val;
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Store VAL as a floating-point number of length LEN to a
|
||||||
|
target-order byte-stream at ADDR. */
|
||||||
|
|
||||||
void
|
void
|
||||||
store_floating (void *addr, int len, DOUBLEST val)
|
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);
|
warning ("Can't store a floating-point number of %d bytes.", len);
|
||||||
}
|
memset (addr, 0, len);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
floatformat_from_doublest (fmt, &val, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract/store a floating-point number of format TYPE from a
|
/* Extract a floating-point number of type TYPE from a target-order
|
||||||
target-ordered byte-stream at ADDR to/from an internal DOUBLEST
|
byte-stream at ADDR. Returns the value as type 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. */
|
|
||||||
|
|
||||||
DOUBLEST
|
DOUBLEST
|
||||||
extract_typed_floating (const void *addr, const struct type *type)
|
extract_typed_floating (const void *addr, const struct type *type)
|
||||||
{
|
{
|
||||||
DOUBLEST retval;
|
DOUBLEST retval;
|
||||||
|
|
||||||
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
|
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
|
||||||
|
|
||||||
if (TYPE_FLOATFORMAT (type) == NULL)
|
if (TYPE_FLOATFORMAT (type) == NULL)
|
||||||
retval = extract_floating (addr, TYPE_LENGTH (type));
|
return extract_floating (addr, TYPE_LENGTH (type));
|
||||||
else
|
|
||||||
floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval);
|
floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Store VAL as a floating-point number of type TYPE to a target-order
|
||||||
|
byte-stream at ADDR. */
|
||||||
|
|
||||||
void
|
void
|
||||||
store_typed_floating (void *addr, const struct type *type, DOUBLEST val)
|
store_typed_floating (void *addr, const struct type *type, DOUBLEST val)
|
||||||
{
|
{
|
||||||
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
|
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));
|
memset (addr, 0, TYPE_LENGTH (type));
|
||||||
|
|
||||||
if (TYPE_FLOATFORMAT (type) == NULL)
|
if (TYPE_FLOATFORMAT (type) == NULL)
|
||||||
store_floating (addr, TYPE_LENGTH (type), val);
|
return store_floating (addr, TYPE_LENGTH (type), val);
|
||||||
else
|
|
||||||
floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr);
|
floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,9 +61,12 @@ extern int floatformat_is_negative (const struct floatformat *, char *);
|
||||||
extern int floatformat_is_nan (const struct floatformat *, char *);
|
extern int floatformat_is_nan (const struct floatformat *, char *);
|
||||||
extern char *floatformat_mantissa (const struct floatformat *, char *);
|
extern char *floatformat_mantissa (const struct floatformat *, char *);
|
||||||
|
|
||||||
/* Use extract_typed_float() and store_typed_float(). */
|
/* These two functions are deprecated in favour of
|
||||||
extern DOUBLEST extract_floating (const void *in, int); /* DEPRECATED */
|
extract_typed_floating and store_typed_floating. See comments in
|
||||||
extern void store_floating (void *, int, DOUBLEST); /* DEPRECATED */
|
'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,
|
extern DOUBLEST extract_typed_floating (const void *addr,
|
||||||
const struct type *type);
|
const struct type *type);
|
||||||
|
|
Loading…
Add table
Reference in a new issue