X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=libiberty%2Ffloatformat.c;h=9190e1469d9fdf4587a5ed600197489a684148d9;hb=8b8c7c9f49992750f66f81b4601d593a3858d98c;hp=07af7264df499c932b3d07662513a4a86304cc14;hpb=f4c43811f70f34738c0ee211903fdfc25fac1ef6;p=deliverable%2Fbinutils-gdb.git diff --git a/libiberty/floatformat.c b/libiberty/floatformat.c index 07af7264df..9190e1469d 100644 --- a/libiberty/floatformat.c +++ b/libiberty/floatformat.c @@ -1,5 +1,5 @@ /* IEEE floating point support routines, for GDB, the GNU Debugger. - Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006 + Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006, 2010, 2012, 2015 Free Software Foundation, Inc. This file is part of GDB. @@ -19,7 +19,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* This is needed to pick up the NAN macro on some systems. */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #ifdef HAVE_CONFIG_H #include "config.h" @@ -77,7 +79,23 @@ floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED, a system header, what we do if not, etc. */ #define FLOATFORMAT_CHAR_BIT 8 -/* floatformats for IEEE single and double, big and little endian. */ +/* floatformats for IEEE half, single and double, big and little endian. */ +const struct floatformat floatformat_ieee_half_big = +{ + floatformat_big, 16, 0, 1, 5, 15, 31, 6, 10, + floatformat_intbit_no, + "floatformat_ieee_half_big", + floatformat_always_valid, + NULL +}; +const struct floatformat floatformat_ieee_half_little = +{ + floatformat_little, 16, 0, 1, 5, 15, 31, 6, 10, + floatformat_intbit_no, + "floatformat_ieee_half_little", + floatformat_always_valid, + NULL +}; const struct floatformat floatformat_ieee_single_big = { floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23, @@ -283,7 +301,7 @@ floatformat_ibm_long_double_is_valid (const struct floatformat *fmt, bot_exp = get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize, hfmt->exp_start, hfmt->exp_len); - if (top_exp == hfmt->exp_nan) + if ((unsigned long) top_exp == hfmt->exp_nan) top_nan = mant_bits_set (hfmt, ufrom); /* A NaN is valid with any low part. */ @@ -292,11 +310,8 @@ floatformat_ibm_long_double_is_valid (const struct floatformat *fmt, /* An infinity, zero or denormal requires low part 0 (positive or negative). */ - if (top_exp == hfmt->exp_nan || top_exp == 0) + if ((unsigned long) top_exp == hfmt->exp_nan || top_exp == 0) { - unsigned int mant_bits, mant_off; - int mant_bits_left; - if (bot_exp != 0) return 0; @@ -318,7 +333,7 @@ floatformat_ibm_long_double_is_valid (const struct floatformat *fmt, /* The bottom part is 0 or denormal. Determine which, and if denormal the first two set bits. */ int first_bit = -1, second_bit = -1, cur_bit; - for (cur_bit = 0; cur_bit < hfmt->man_len; cur_bit++) + for (cur_bit = 0; (unsigned int) cur_bit < hfmt->man_len; cur_bit++) if (get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize, hfmt->man_start + cur_bit, 1)) { @@ -358,14 +373,23 @@ floatformat_ibm_long_double_is_valid (const struct floatformat *fmt, } } -const struct floatformat floatformat_ibm_long_double = +const struct floatformat floatformat_ibm_long_double_big = { floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52, floatformat_intbit_no, - "floatformat_ibm_long_double", - floatformat_always_valid, + "floatformat_ibm_long_double_big", + floatformat_ibm_long_double_is_valid, &floatformat_ieee_double_big }; + +const struct floatformat floatformat_ibm_long_double_little = +{ + floatformat_little, 128, 0, 1, 11, 1023, 2047, 12, 52, + floatformat_intbit_no, + "floatformat_ibm_long_double_little", + floatformat_ibm_long_double_is_valid, + &floatformat_ieee_double_little +}; #ifndef min @@ -450,7 +474,6 @@ floatformat_to_double (const struct floatformat *fmt, unsigned long mant; unsigned int mant_bits, mant_off; int mant_bits_left; - int special_exponent; /* It's a NaN, denorm or zero */ /* Split values are not handled specially, since the top half has the correctly rounded double value (in the only supported case of @@ -490,20 +513,20 @@ floatformat_to_double (const struct floatformat *fmt, mant_off = fmt->man_start; dto = 0.0; - special_exponent = exponent == 0 || (unsigned long) exponent == fmt->exp_nan; - - /* Don't bias zero's, denorms or NaNs. */ - if (!special_exponent) - exponent -= fmt->exp_bias; - /* Build the result algebraically. Might go infinite, underflow, etc; who cares. */ - /* If this format uses a hidden bit, explicitly add it in now. Otherwise, - increment the exponent by one to account for the integer bit. */ - - if (!special_exponent) + /* For denorms use minimum exponent. */ + if (exponent == 0) + exponent = 1 - fmt->exp_bias; + else { + exponent -= fmt->exp_bias; + + /* If this format uses a hidden bit, explicitly add it in now. + Otherwise, increment the exponent by one to account for the + integer bit. */ + if (fmt->intbit == floatformat_intbit_no) dto = ldexp (1.0, exponent); else @@ -517,18 +540,8 @@ floatformat_to_double (const struct floatformat *fmt, mant = get_field (ufrom, fmt->byteorder, fmt->totalsize, mant_off, mant_bits); - /* Handle denormalized numbers. FIXME: What should we do for - non-IEEE formats? */ - if (special_exponent && exponent == 0 && mant != 0) - dto += ldexp ((double)mant, - (- fmt->exp_bias - - mant_bits - - (mant_off - fmt->man_start) - + 1)); - else - dto += ldexp ((double)mant, exponent - mant_bits); - if (exponent != 0) - exponent -= mant_bits; + dto += ldexp ((double) mant, exponent - mant_bits); + exponent -= mant_bits; mant_off += mant_bits; mant_bits_left -= mant_bits; } @@ -743,6 +756,7 @@ main (void) { ieee_test (0.0); ieee_test (0.5); + ieee_test (1.1); ieee_test (256.0); ieee_test (0.12345); ieee_test (234235.78907234);