* doublest.c (convert_floatformat_to_doublest): Use
floatformat_classify. (floatformat_is_nan): Rename to... (floatformat_classify): ...this. Return more information. * doublest.h (enum float_kind): New. (floatformat_is_nan): Replace prototype... (floatformat_classify): ...with this one. * valprint.c (print_floating): Use floatformat_classify. Handle infinity. * gdb.base/infnan.c, gdb.base/infnan.exp: New files.
This commit is contained in:
parent
30b50213ec
commit
203890574d
@ -1,3 +1,15 @@
|
||||
2007-03-30 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* doublest.c (convert_floatformat_to_doublest): Use
|
||||
floatformat_classify.
|
||||
(floatformat_is_nan): Rename to...
|
||||
(floatformat_classify): ...this. Return more information.
|
||||
* doublest.h (enum float_kind): New.
|
||||
(floatformat_is_nan): Replace prototype...
|
||||
(floatformat_classify): ...with this one.
|
||||
* valprint.c (print_floating): Use floatformat_classify. Handle
|
||||
infinity.
|
||||
|
||||
2007-03-30 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* README: Mention ISO C library requirement.
|
||||
|
@ -180,10 +180,23 @@ convert_floatformat_to_doublest (const struct floatformat *fmt,
|
||||
int special_exponent; /* It's a NaN, denorm or zero */
|
||||
enum floatformat_byteorders order;
|
||||
unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];
|
||||
enum float_kind kind;
|
||||
|
||||
gdb_assert (fmt->totalsize
|
||||
<= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
|
||||
|
||||
/* For non-numbers, reuse libiberty's logic to find the correct
|
||||
format. We do not lose any precision in this case by passing
|
||||
through a double. */
|
||||
kind = floatformat_classify (fmt, from);
|
||||
if (kind == float_infinite || kind == float_nan)
|
||||
{
|
||||
double dto;
|
||||
floatformat_to_double (fmt, from, &dto);
|
||||
*to = (DOUBLEST) dto;
|
||||
return;
|
||||
}
|
||||
|
||||
order = floatformat_normalize_byteorder (fmt, ufrom, newfrom);
|
||||
|
||||
if (order != fmt->byteorder)
|
||||
@ -495,9 +508,9 @@ floatformat_is_negative (const struct floatformat *fmt,
|
||||
|
||||
/* Check if VAL is "not a number" (NaN) for FMT. */
|
||||
|
||||
int
|
||||
floatformat_is_nan (const struct floatformat *fmt,
|
||||
const bfd_byte *uval)
|
||||
enum float_kind
|
||||
floatformat_classify (const struct floatformat *fmt,
|
||||
const bfd_byte *uval)
|
||||
{
|
||||
long exponent;
|
||||
unsigned long mant;
|
||||
@ -505,6 +518,7 @@ floatformat_is_nan (const struct floatformat *fmt,
|
||||
int mant_bits_left;
|
||||
enum floatformat_byteorders order;
|
||||
unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];
|
||||
int mant_zero;
|
||||
|
||||
gdb_assert (fmt != NULL);
|
||||
gdb_assert (fmt->totalsize
|
||||
@ -515,18 +529,13 @@ floatformat_is_nan (const struct floatformat *fmt,
|
||||
if (order != fmt->byteorder)
|
||||
uval = newfrom;
|
||||
|
||||
if (! fmt->exp_nan)
|
||||
return 0;
|
||||
|
||||
exponent = get_field (uval, order, fmt->totalsize, fmt->exp_start,
|
||||
fmt->exp_len);
|
||||
|
||||
if (exponent != fmt->exp_nan)
|
||||
return 0;
|
||||
|
||||
mant_bits_left = fmt->man_len;
|
||||
mant_off = fmt->man_start;
|
||||
|
||||
mant_zero = 1;
|
||||
while (mant_bits_left > 0)
|
||||
{
|
||||
mant_bits = min (mant_bits_left, 32);
|
||||
@ -539,13 +548,40 @@ floatformat_is_nan (const struct floatformat *fmt,
|
||||
mant &= ~(1 << (mant_bits - 1));
|
||||
|
||||
if (mant)
|
||||
return 1;
|
||||
{
|
||||
mant_zero = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
mant_off += mant_bits;
|
||||
mant_bits_left -= mant_bits;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* If exp_nan is not set, assume that inf, NaN, and subnormals are not
|
||||
supported. */
|
||||
if (! fmt->exp_nan)
|
||||
{
|
||||
if (mant_zero)
|
||||
return float_zero;
|
||||
else
|
||||
return float_normal;
|
||||
}
|
||||
|
||||
if (exponent == 0 && !mant_zero)
|
||||
return float_subnormal;
|
||||
|
||||
if (exponent == fmt->exp_nan)
|
||||
{
|
||||
if (mant_zero)
|
||||
return float_infinite;
|
||||
else
|
||||
return float_nan;
|
||||
}
|
||||
|
||||
if (mant_zero)
|
||||
return float_zero;
|
||||
|
||||
return float_normal;
|
||||
}
|
||||
|
||||
/* Convert the mantissa of VAL (which is assumed to be a floating
|
||||
|
@ -64,6 +64,17 @@ typedef double DOUBLEST;
|
||||
# undef SCANF_HAS_LONG_DOUBLE
|
||||
#endif
|
||||
|
||||
/* Different kinds of floatformat numbers recognized by
|
||||
floatformat_classify. To avoid portability issues, we use local
|
||||
values instead of the C99 macros (FP_NAN et cetera). */
|
||||
enum float_kind {
|
||||
float_nan,
|
||||
float_infinite,
|
||||
float_zero,
|
||||
float_normal,
|
||||
float_subnormal
|
||||
};
|
||||
|
||||
extern void floatformat_to_doublest (const struct floatformat *,
|
||||
const void *in, DOUBLEST *out);
|
||||
extern void floatformat_from_doublest (const struct floatformat *,
|
||||
@ -71,7 +82,8 @@ extern void floatformat_from_doublest (const struct floatformat *,
|
||||
|
||||
extern int floatformat_is_negative (const struct floatformat *,
|
||||
const bfd_byte *);
|
||||
extern int floatformat_is_nan (const struct floatformat *, const bfd_byte *);
|
||||
extern enum float_kind floatformat_classify (const struct floatformat *,
|
||||
const bfd_byte *);
|
||||
extern const char *floatformat_mantissa (const struct floatformat *,
|
||||
const bfd_byte *);
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
2007-03-30 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* gdb.base/infnan.c, gdb.base/infnan.exp: New files.
|
||||
|
||||
2007-03-30 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* config/netware.exp: Delete file.
|
||||
|
30
gdb/testsuite/gdb.base/infnan.c
Normal file
30
gdb/testsuite/gdb.base/infnan.c
Normal file
@ -0,0 +1,30 @@
|
||||
/* This test file is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
double a = 1.0/0.0;
|
||||
double b = 0.0/0.0;
|
||||
double c;
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
c = a + b;
|
||||
return 0;
|
||||
}
|
36
gdb/testsuite/gdb.base/infnan.exp
Normal file
36
gdb/testsuite/gdb.base/infnan.exp
Normal file
@ -0,0 +1,36 @@
|
||||
# Copyright 2007 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
# Script to test floating point infinities and NaNs.
|
||||
|
||||
set testfile "infnan"
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||
untested infnan.exp
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
runto_main
|
||||
|
||||
gdb_test "print a" "\\\$$decimal = inf"
|
||||
gdb_test "print b" "\\\$$decimal = nan\\(0x.*\\)"
|
@ -442,19 +442,31 @@ print_floating (const gdb_byte *valaddr, struct type *type,
|
||||
int inv;
|
||||
const struct floatformat *fmt = NULL;
|
||||
unsigned len = TYPE_LENGTH (type);
|
||||
enum float_kind kind;
|
||||
|
||||
/* If it is a floating-point, check for obvious problems. */
|
||||
if (TYPE_CODE (type) == TYPE_CODE_FLT)
|
||||
fmt = floatformat_from_type (type);
|
||||
if (fmt != NULL && floatformat_is_nan (fmt, valaddr))
|
||||
if (fmt != NULL)
|
||||
{
|
||||
if (floatformat_is_negative (fmt, valaddr))
|
||||
fprintf_filtered (stream, "-");
|
||||
fprintf_filtered (stream, "nan(");
|
||||
fputs_filtered ("0x", stream);
|
||||
fputs_filtered (floatformat_mantissa (fmt, valaddr), stream);
|
||||
fprintf_filtered (stream, ")");
|
||||
return;
|
||||
kind = floatformat_classify (fmt, valaddr);
|
||||
if (kind == float_nan)
|
||||
{
|
||||
if (floatformat_is_negative (fmt, valaddr))
|
||||
fprintf_filtered (stream, "-");
|
||||
fprintf_filtered (stream, "nan(");
|
||||
fputs_filtered ("0x", stream);
|
||||
fputs_filtered (floatformat_mantissa (fmt, valaddr), stream);
|
||||
fprintf_filtered (stream, ")");
|
||||
return;
|
||||
}
|
||||
else if (kind == float_infinite)
|
||||
{
|
||||
if (floatformat_is_negative (fmt, valaddr))
|
||||
fputs_filtered ("-", stream);
|
||||
fputs_filtered ("inf", stream);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: cagney/2002-01-15: The TYPE passed into print_floating()
|
||||
|
Loading…
Reference in New Issue
Block a user