convert_doublest_to_floatformat: handle off-range values.

On x86_64-linux targetting AVR, we see the following issues:

    (gdb) print 1.6e+308
    $1 = 0.89002949
    (gdb) print 1.6e-308
    $3 = 2.87630892

What happens is that GDB is trying to convert the value it read
(as a host "long double") into a target "double" value. The routine
performing the conversion does not realize that 1.6e+308 is just
too large to fit in a double. Similarly, it does not notice that
1.6e-308 is too small to be represented.

This patch enhances convert_doublest_to_floatformat to both handle
floats that are too small and too large.

gdb/ChangeLog:

        * doublest.c (convert_doublest_to_floatformat): If the exponent
        is too small, treat the value as zero.  If the exponent is too
        large, treat the value as infinity.
This commit is contained in:
Joel Brobecker 2012-07-25 18:27:21 +00:00
parent a22d44ff78
commit 33d7655bb2
2 changed files with 28 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2012-07-25 Joel Brobecker <brobecker@adacore.com>
* doublest.c (convert_doublest_to_floatformat): If the exponent
is too small, treat the value as zero. If the exponent is too
large, treat the value as infinity.
2012-07-25 Joel Brobecker <brobecker@adacore.com>
* configure.ac: Add --enable-lmcheck configure option.

View File

@ -472,6 +472,28 @@ convert_doublest_to_floatformat (CONST struct floatformat *fmt,
mant = frexp (dfrom, &exponent);
#endif
if (exponent + fmt->exp_bias <= 0)
{
/* The value is too small to be expressed in the destination
type (not enough bits in the exponent. Treat as 0. */
put_field (uto, order, fmt->totalsize, fmt->exp_start,
fmt->exp_len, 0);
put_field (uto, order, fmt->totalsize, fmt->man_start,
fmt->man_len, 0);
goto finalize_byteorder;
}
if (exponent + fmt->exp_bias >= (1 << fmt->exp_len) - 1)
{
/* The value is too large to fit into the destination.
Treat as infinity. */
put_field (uto, order, fmt->totalsize, fmt->exp_start,
fmt->exp_len, fmt->exp_nan);
put_field (uto, order, fmt->totalsize, fmt->man_start,
fmt->man_len, 0);
goto finalize_byteorder;
}
put_field (uto, order, fmt->totalsize, fmt->exp_start, fmt->exp_len,
exponent + fmt->exp_bias - 1);