diff options
author | Mark Kettenis <kettenis@gnu.org> | 2001-03-07 16:09:03 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2001-03-07 16:09:03 +0000 |
commit | 39424bef9143202f0b7fc25b73c81db580eb253c (patch) | |
tree | b0005bf91d34da2269e757c75722bbd9ed51139f /gdb/utils.c | |
parent | bcdd92f3e09bfbb42f46281bab7619f8c40d10a3 (diff) | |
download | gdb-39424bef9143202f0b7fc25b73c81db580eb253c.zip gdb-39424bef9143202f0b7fc25b73c81db580eb253c.tar.gz gdb-39424bef9143202f0b7fc25b73c81db580eb253c.tar.bz2 |
* defs.h: Provide prototypes for floatformat_is_negative,
floatformat_is_nan and floatformat_mantissa.
* utils.c: Include "gdb_assert.h".
(floatformat_is_negative): New function.
(floatformat_is_nan): New function.
(floatformat_mantissa): New function.
* valprint.c: Include "floatformat.h".
(print_floating): Get rid of the Linux-specific
TARGET_ANALYZE_FLOATING macro and rewrite NaN detection with the
help these new functions. Print NaN's in a format conforming to
ISO C99.
Diffstat (limited to 'gdb/utils.c')
-rw-r--r-- | gdb/utils.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/gdb/utils.c b/gdb/utils.c index df6046a..5ece78d 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "gdb_assert.h" #include <ctype.h> #include "gdb_string.h" #include "event-top.h" @@ -2741,6 +2742,106 @@ floatformat_from_doublest (CONST struct floatformat *fmt, DOUBLEST *from, } } +/* Check if VAL (which is assumed to be a floating point number whose + format is described by FMT) is negative. */ + +int +floatformat_is_negative (const struct floatformat *fmt, char *val) +{ + unsigned char *uval = (unsigned char *) val; + + return get_field (uval, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1); +} + +/* Check if VAL is "not a number" (NaN) for FMT. */ + +int +floatformat_is_nan (const struct floatformat *fmt, char *val) +{ + unsigned char *uval = (unsigned char *) val; + long exponent; + unsigned long mant; + unsigned int mant_bits, mant_off; + int mant_bits_left; + + if (! fmt->exp_nan) + return 0; + + exponent = get_field (uval, fmt->byteorder, 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; + + while (mant_bits_left > 0) + { + mant_bits = min (mant_bits_left, 32); + + mant = get_field (uval, fmt->byteorder, fmt->totalsize, + mant_off, mant_bits); + + /* If there is an explicit integer bit, mask it off. */ + if (mant_off == fmt->man_start + && fmt->intbit == floatformat_intbit_yes) + mant &= ~(1 << (mant_bits - 1)); + + if (mant) + return 1; + + mant_off += mant_bits; + mant_bits_left -= mant_bits; + } + + return 0; +} + +/* Convert the mantissa of VAL (which is assumed to be a floating + point number whose format is described by FMT) into a hexadecimal + and store it in a static string. Return a pointer to that string. */ + +char * +floatformat_mantissa (const struct floatformat *fmt, char *val) +{ + unsigned char *uval = (unsigned char *) val; + unsigned long mant; + unsigned int mant_bits, mant_off; + int mant_bits_left; + static char res[50]; + char buf[9]; + + /* Make sure we have enough room to store the mantissa. */ + gdb_assert (sizeof res > ((fmt->man_len + 7) / 8) * 2); + + mant_off = fmt->man_start; + mant_bits_left = fmt->man_len; + mant_bits = (mant_bits_left % 32) > 0 ? mant_bits_left % 32 : 32; + + mant = get_field (uval, fmt->byteorder, fmt->totalsize, + mant_off, mant_bits); + + sprintf (res, "%lx", mant); + + mant_off += mant_bits; + mant_bits_left -= mant_bits; + + while (mant_bits_left > 0) + { + mant = get_field (uval, fmt->byteorder, fmt->totalsize, + mant_off, 32); + + sprintf (buf, "%08lx", mant); + strcat (res, buf); + + mant_off += 32; + mant_bits_left -= 32; + } + + return res; +} + /* print routines to handle variable size regs, etc. */ /* temporary storage using circular buffer */ |