/* 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.
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
#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"
#endif
#ifndef NAN
+#ifdef DBL_QNAN
+#define NAN DBL_QNAN
+#else
#define NAN (0.0 / 0.0)
#endif
+#endif
static unsigned long get_field (const unsigned char *,
enum floatformat_byteorders,
unsigned int,
unsigned int);
static int floatformat_always_valid (const struct floatformat *fmt,
- const char *from);
+ const void *from);
static int
floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED,
- const char *from ATTRIBUTE_UNUSED)
+ const void *from ATTRIBUTE_UNUSED)
{
return 1;
}
floatformat_always_valid
};
-static int floatformat_i387_ext_is_valid (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 (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
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
void
floatformat_to_double (const struct floatformat *fmt,
- const char *from, double *to)
+ 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;
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
/* Handle denormalized numbers. FIXME: What should we do for
non-IEEE formats? */
- if (exponent == 0 && mant != 0)
+ if (special_exponent && exponent == 0 && mant != 0)
dto += ldexp ((double)mant,
(- fmt->exp_bias
- mant_bits
void
floatformat_from_double (const struct floatformat *fmt,
- const double *from, char *to)
+ 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);
/* Return non-zero iff the data at FROM is a valid number in format FMT. */
int
-floatformat_is_valid (const struct floatformat *fmt, const char *from)
+floatformat_is_valid (const struct floatformat *fmt, const void *from)
{
return fmt->is_valid (fmt, from);
}
{
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))