diff options
Diffstat (limited to 'contrib/binutils/libiberty/floatformat.c')
-rw-r--r-- | contrib/binutils/libiberty/floatformat.c | 134 |
1 files changed, 78 insertions, 56 deletions
diff --git a/contrib/binutils/libiberty/floatformat.c b/contrib/binutils/libiberty/floatformat.c index a0f65354e482..bd31efac7c17 100644 --- a/contrib/binutils/libiberty/floatformat.c +++ b/contrib/binutils/libiberty/floatformat.c @@ -1,5 +1,6 @@ /* IEEE floating point support routines, for GDB, the GNU Debugger. - Copyright (C) 1991, 1994, 1999, 2000, 2003 Free Software Foundation, Inc. + Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006 + Free Software Foundation, Inc. This file is part of GDB. @@ -15,7 +16,7 @@ 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. */ +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* This is needed to pick up the NAN macro on some systems. */ #define _GNU_SOURCE @@ -30,6 +31,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <string.h> #endif +/* On some platforms, <float.h> provides DBL_QNAN. */ +#ifdef STDC_HEADERS +#include <float.h> +#endif + #include "ansidecl.h" #include "libiberty.h" #include "floatformat.h" @@ -43,21 +49,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #endif #ifndef NAN +#ifdef DBL_QNAN +#define NAN DBL_QNAN +#else #define NAN (0.0 / 0.0) #endif +#endif -static unsigned long get_field PARAMS ((const unsigned char *, - enum floatformat_byteorders, - unsigned int, - unsigned int, - unsigned int)); -static int floatformat_always_valid PARAMS ((const struct floatformat *fmt, - const char *from)); +static unsigned long get_field (const unsigned char *, + enum floatformat_byteorders, + unsigned int, + unsigned int, + unsigned int); +static int floatformat_always_valid (const struct floatformat *fmt, + const void *from); static int -floatformat_always_valid (fmt, from) - const struct floatformat *fmt ATTRIBUTE_UNUSED; - const char *from ATTRIBUTE_UNUSED; +floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED, + const void *from ATTRIBUTE_UNUSED) { return 1; } @@ -108,12 +117,35 @@ const struct floatformat floatformat_ieee_double_littlebyte_bigword = floatformat_always_valid }; -static int floatformat_i387_ext_is_valid PARAMS ((const struct floatformat *fmt, const char *from)); +/* floatformat for VAX. Not quite IEEE, but close enough. */ + +const struct floatformat floatformat_vax_f = +{ + floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23, + floatformat_intbit_no, + "floatformat_vax_f", + floatformat_always_valid +}; +const struct floatformat floatformat_vax_d = +{ + floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55, + floatformat_intbit_no, + "floatformat_vax_d", + floatformat_always_valid +}; +const struct floatformat floatformat_vax_g = +{ + floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52, + floatformat_intbit_no, + "floatformat_vax_g", + floatformat_always_valid +}; + +static int floatformat_i387_ext_is_valid (const struct floatformat *fmt, + const void *from); static int -floatformat_i387_ext_is_valid (fmt, from) - const struct floatformat *fmt; - const char *from; +floatformat_i387_ext_is_valid (const struct floatformat *fmt, const void *from) { /* In the i387 double-extended format, if the exponent is all ones, then the integer bit must be set. If the exponent is neither 0 @@ -121,12 +153,12 @@ floatformat_i387_ext_is_valid (fmt, from) zero can it be zero, and then it must be zero. */ unsigned long exponent, int_bit; const unsigned char *ufrom = (const unsigned char *) from; - + exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len); int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->man_start, 1); - + if ((exponent == 0) != (int_bit == 0)) return 0; else @@ -220,12 +252,8 @@ const struct floatformat floatformat_ia64_quad_little = /* Extract a field which starts at START and is LEN bits long. DATA and TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ static unsigned long -get_field (data, order, total_len, start, len) - const unsigned char *data; - enum floatformat_byteorders order; - unsigned int total_len; - unsigned int start; - unsigned int len; +get_field (const unsigned char *data, enum floatformat_byteorders order, + unsigned int total_len, unsigned int start, unsigned int len) { unsigned long result; unsigned int cur_byte; @@ -273,12 +301,10 @@ get_field (data, order, total_len, start, len) Store the double in *TO. */ void -floatformat_to_double (fmt, from, to) - const struct floatformat *fmt; - const char *from; - double *to; +floatformat_to_double (const struct floatformat *fmt, + const void *from, double *to) { - const unsigned char *ufrom = (const unsigned char *)from; + const unsigned char *ufrom = (const unsigned char *) from; double dto; long exponent; unsigned long mant; @@ -315,6 +341,13 @@ floatformat_to_double (fmt, from, to) mant_bits_left -= mant_bits; } + /* On certain systems (such as GNU/Linux), the use of the + INFINITY macro below may generate a warning that can not be + silenced due to a bug in GCC (PR preprocessor/11931). The + preprocessor fails to recognise the __extension__ keyword in + conjunction with the GNU/C99 extension for hexadecimal + floating point constants and will issue a warning when + compiling with -pedantic. */ if (nan) dto = NAN; else @@ -381,22 +414,18 @@ floatformat_to_double (fmt, from, to) *to = dto; } -static void put_field PARAMS ((unsigned char *, enum floatformat_byteorders, - unsigned int, - unsigned int, - unsigned int, - unsigned long)); +static void put_field (unsigned char *, enum floatformat_byteorders, + unsigned int, + unsigned int, + unsigned int, + unsigned long); /* Set a field which starts at START and is LEN bits long. DATA and TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ static void -put_field (data, order, total_len, start, len, stuff_to_put) - unsigned char *data; - enum floatformat_byteorders order; - unsigned int total_len; - unsigned int start; - unsigned int len; - unsigned long stuff_to_put; +put_field (unsigned char *data, enum floatformat_byteorders order, + unsigned int total_len, unsigned int start, unsigned int len, + unsigned long stuff_to_put) { unsigned int cur_byte; int cur_bitshift; @@ -443,17 +472,15 @@ put_field (data, order, total_len, start, len, stuff_to_put) restrictions. */ void -floatformat_from_double (fmt, from, to) - const struct floatformat *fmt; - const double *from; - char *to; +floatformat_from_double (const struct floatformat *fmt, + const double *from, void *to) { double dfrom; int exponent; double mant; unsigned int mant_bits, mant_off; int mant_bits_left; - unsigned char *uto = (unsigned char *)to; + unsigned char *uto = (unsigned char *) to; dfrom = *from; memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT); @@ -541,9 +568,7 @@ floatformat_from_double (fmt, from, to) /* Return non-zero iff the data at FROM is a valid number in format FMT. */ int -floatformat_is_valid (fmt, from) - const struct floatformat *fmt; - const char *from; +floatformat_is_valid (const struct floatformat *fmt, const void *from) { return fmt->is_valid (fmt, from); } @@ -556,20 +581,17 @@ floatformat_is_valid (fmt, from) /* This is to be run on a host which uses IEEE floating point. */ void -ieee_test (n) - double n; +ieee_test (double n) { double result; - floatformat_to_double (&floatformat_ieee_double_little, (char *) &n, - &result); + floatformat_to_double (&floatformat_ieee_double_little, &n, &result); if ((n != result && (! isnan (n) || ! isnan (result))) || (n < 0 && result >= 0) || (n >= 0 && result < 0)) printf ("Differ(to): %.20g -> %.20g\n", n, result); - floatformat_from_double (&floatformat_ieee_double_little, &n, - (char *) &result); + floatformat_from_double (&floatformat_ieee_double_little, &n, &result); if ((n != result && (! isnan (n) || ! isnan (result))) || (n < 0 && result >= 0) || (n >= 0 && result < 0)) @@ -597,7 +619,7 @@ ieee_test (n) } int -main () +main (void) { ieee_test (0.0); ieee_test (0.5); |