X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdoublest.c;h=3f283e13ffa55842eba72b08a4515b52fe0ca38e;hb=44e1a9eb2556723d464e53f3bf2fd34b6cf5aa13;hp=083a50a98aa1f2dc4570f2a9c6d1ec64b2f95bc4;hpb=43686d6411284a401e84ab2f0227b0b51c2aab21;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/doublest.c b/gdb/doublest.c index 083a50a98a..3f283e13ff 100644 --- a/gdb/doublest.c +++ b/gdb/doublest.c @@ -1,7 +1,8 @@ /* Floating point routines for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, + Inc. This file is part of GDB. @@ -172,8 +173,10 @@ convert_floatformat_to_doublest (const struct floatformat *fmt, special_exponent = exponent == 0 || exponent == fmt->exp_nan; -/* Don't bias NaNs. Use minimum exponent for denorms. For simplicity, - we don't check for zero as the exponent doesn't matter. */ + /* Don't bias NaNs. Use minimum exponent for denorms. For simplicity, + we don't check for zero as the exponent doesn't matter. Note the cast + to int; exp_bias is unsigned, so it's important to make sure the + operation is done in signed arithmetic. */ if (!special_exponent) exponent -= fmt->exp_bias; else if (exponent == 0) @@ -401,7 +404,15 @@ convert_doublest_to_floatformat (CONST struct floatformat *fmt, { mant_long <<= 1; mant_long &= 0xffffffffL; - mant_bits -= 1; + /* If we are processing the top 32 mantissa bits of a doublest + so as to convert to a float value with implied integer bit, + we will only be putting 31 of those 32 bits into the + final value due to the discarding of the top bit. In the + case of a small float value where the number of mantissa + bits is less than 32, discarding the top bit does not alter + the number of bits we will be adding to the result. */ + if (mant_bits == 32) + mant_bits -= 1; } if (mant_bits < 32) @@ -439,7 +450,7 @@ int floatformat_is_negative (const struct floatformat *fmt, char *val) { unsigned char *uval = (unsigned char *) val; - + gdb_assert (fmt != NULL); return get_field (uval, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1); } @@ -454,6 +465,8 @@ floatformat_is_nan (const struct floatformat *fmt, char *val) unsigned int mant_bits, mant_off; int mant_bits_left; + gdb_assert (fmt != NULL); + if (! fmt->exp_nan) return 0; @@ -503,6 +516,7 @@ floatformat_mantissa (const struct floatformat *fmt, char *val) char buf[9]; /* Make sure we have enough room to store the mantissa. */ + gdb_assert (fmt != NULL); gdb_assert (sizeof res > ((fmt->man_len + 7) / 8) * 2); mant_off = fmt->man_start; @@ -628,10 +642,28 @@ floatformat_from_length (int len) return TARGET_DOUBLE_FORMAT; else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT) return TARGET_LONG_DOUBLE_FORMAT; + /* On i386 the 'long double' type takes 96 bits, + while the real number of used bits is only 80, + both in processor and in memory. + The code below accepts the real bit size. */ + else if ((TARGET_LONG_DOUBLE_FORMAT != NULL) + && (len * TARGET_CHAR_BIT == + TARGET_LONG_DOUBLE_FORMAT->totalsize)) + return TARGET_LONG_DOUBLE_FORMAT; return NULL; } +const struct floatformat * +floatformat_from_type (const struct type *type) +{ + gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); + if (TYPE_FLOATFORMAT (type) != NULL) + return TYPE_FLOATFORMAT (type); + else + return floatformat_from_length (TYPE_LENGTH (type)); +} + /* If the host doesn't define NAN, use zero instead. */ #ifndef NAN #define NAN 0.0 @@ -640,15 +672,15 @@ floatformat_from_length (int len) /* 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) +static DOUBLEST +extract_floating_by_length (const void *addr, int len) { const struct floatformat *fmt = floatformat_from_length (len); DOUBLEST val; if (fmt == NULL) { - warning ("Can't store a floating-point number of %d bytes.", len); + warning ("Can't extract a floating-point number of %d bytes.", len); return NAN; } @@ -656,11 +688,17 @@ extract_floating (const void *addr, int len) return val; } +DOUBLEST +deprecated_extract_floating (const void *addr, int len) +{ + return extract_floating_by_length (addr, len); +} + /* 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) +static void +store_floating_by_length (void *addr, int len, DOUBLEST val) { const struct floatformat *fmt = floatformat_from_length (len); @@ -668,11 +706,18 @@ store_floating (void *addr, int len, DOUBLEST val) { warning ("Can't store a floating-point number of %d bytes.", len); memset (addr, 0, len); + return; } floatformat_from_doublest (fmt, &val, addr); } +void +deprecated_store_floating (void *addr, int len, DOUBLEST val) +{ + store_floating_by_length (addr, len, val); +} + /* Extract a floating-point number of type TYPE from a target-order byte-stream at ADDR. Returns the value as type DOUBLEST. */ @@ -684,7 +729,9 @@ extract_typed_floating (const void *addr, const struct type *type) gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); if (TYPE_FLOATFORMAT (type) == NULL) - return extract_floating (addr, TYPE_LENGTH (type)); + /* Not all code remembers to set the FLOATFORMAT (language + specific code? stabs?) so handle that here as a special case. */ + return extract_floating_by_length (addr, TYPE_LENGTH (type)); floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval); return retval; @@ -719,9 +766,11 @@ store_typed_floating (void *addr, const struct type *type, DOUBLEST val) memset (addr, 0, TYPE_LENGTH (type)); if (TYPE_FLOATFORMAT (type) == NULL) - return store_floating (addr, TYPE_LENGTH (type), val); - - floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr); + /* Not all code remembers to set the FLOATFORMAT (language + specific code? stabs?) so handle that here as a special case. */ + store_floating_by_length (addr, TYPE_LENGTH (type), val); + else + floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr); } /* Convert a floating-point number of type FROM_TYPE from a @@ -732,19 +781,12 @@ void convert_typed_floating (const void *from, const struct type *from_type, void *to, const struct type *to_type) { - const struct floatformat *from_fmt = TYPE_FLOATFORMAT (from_type); - const struct floatformat *to_fmt = TYPE_FLOATFORMAT (to_type); + const struct floatformat *from_fmt = floatformat_from_type (from_type); + const struct floatformat *to_fmt = floatformat_from_type (to_type); gdb_assert (TYPE_CODE (from_type) == TYPE_CODE_FLT); gdb_assert (TYPE_CODE (to_type) == TYPE_CODE_FLT); - /* If the floating-point format of FROM_TYPE or TO_TYPE isn't known, - try to guess it from the type's length. */ - if (from_fmt == NULL) - from_fmt = floatformat_from_length (TYPE_LENGTH (from_type)); - if (to_fmt == NULL) - to_fmt = floatformat_from_length (TYPE_LENGTH (to_type)); - if (from_fmt == NULL || to_fmt == NULL) { /* If we don't know the floating-point format of FROM_TYPE or