/* Floating point routines for GDB, the GNU debugger.
- Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1986, 1988-2001, 2003-2005, 2007-2012 Free Software
+ Foundation, Inc.
This file is part of GDB.
{
/* We start counting from the other end (i.e, from the high bytes
rather than the low bytes). As such, we need to be concerned
- with what happens if bit 0 doesn't start on a byte boundary.
+ with what happens if bit 0 doesn't start on a byte boundary.
I.e, we need to properly handle the case where total_len is
not evenly divisible by 8. So we compute ``excess'' which
represents the number of bits from the end of our starting
- byte needed to get to bit 0. */
+ byte needed to get to bit 0. */
int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
+
cur_byte = (total_len / FLOATFORMAT_CHAR_BIT)
- ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT)
}
}
if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT)
- /* Mask out bits which are not part of the field */
+ /* Mask out bits which are not part of the field. */
result &= ((1UL << len) - 1);
return result;
}
unsigned long mant;
unsigned int mant_bits, mant_off;
int mant_bits_left;
- int special_exponent; /* It's a NaN, denorm or zero */
+ int special_exponent; /* It's a NaN, denorm or zero. */
enum floatformat_byteorders order;
unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];
enum float_kind kind;
if (kind == float_infinite || kind == float_nan)
{
double dto;
+
floatformat_to_double (fmt, from, &dto);
*to = (DOUBLEST) dto;
return;
if (fmt->split_half)
{
DOUBLEST dtop, dbot;
+
floatformat_to_doublest (fmt->split_half, ufrom, &dtop);
/* Preserve the sign of 0, which is the sign of the top
half. */
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. Note the cast
- to int; exp_bias is unsigned, so it's important to make sure the
- operation is done in signed arithmetic. */
+ /* 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)
exponent = 1 - fmt->exp_bias;
/* Build the result algebraically. Might go infinite, underflow, etc;
- who cares. */
+ 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. */
*to = dto;
}
\f
-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 bytes long. DATA and
TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
static void
if (order == floatformat_little)
{
int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
+
cur_byte = (total_len / FLOATFORMAT_CHAR_BIT)
- ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT)
long double tmp;
int exp;
- /* Unfortunately, there are no portable functions for extracting the exponent
- of a long double, so we have to do it iteratively by multiplying or dividing
- by two until the fraction is between 0.5 and 1.0. */
+ /* Unfortunately, there are no portable functions for extracting the
+ exponent of a long double, so we have to do it iteratively by
+ multiplying or dividing by two until the fraction is between 0.5
+ and 1.0. */
if (value < 0.0l)
value = -value;
the result of converting to double. */
static volatile double dtop, dbot;
DOUBLEST dtopnv, dbotnv;
+
dtop = (double) dfrom;
/* If the rounded top half is Inf, the bottom must be 0 not NaN
or Inf. */
/* From is NaN */
put_field (uto, order, fmt->totalsize, fmt->exp_start,
fmt->exp_len, fmt->exp_nan);
- /* Be sure it's not infinity, but NaN value is irrel */
+ /* Be sure it's not infinity, but NaN value is irrel. */
put_field (uto, order, fmt->totalsize, fmt->man_start,
- 32, 1);
+ fmt->man_len, 1);
goto finalize_byteorder;
}
dfrom = -dfrom;
}
- if (dfrom + dfrom == dfrom && dfrom != 0.0) /* Result is Infinity */
+ if (dfrom + dfrom == dfrom && dfrom != 0.0) /* Result is Infinity. */
{
/* Infinity exponent is same as NaN's. */
put_field (uto, order, fmt->totalsize, fmt->exp_start,
while (mant_bits_left > 0)
{
unsigned long mant_long;
+
mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
mant *= 4294967296.0;
static const struct floatformat *host_float_format = GDB_HOST_FLOAT_FORMAT;
static const struct floatformat *host_double_format = GDB_HOST_DOUBLE_FORMAT;
-static const struct floatformat *host_long_double_format = GDB_HOST_LONG_DOUBLE_FORMAT;
+static const struct floatformat *host_long_double_format
+ = GDB_HOST_LONG_DOUBLE_FORMAT;
void
floatformat_to_doublest (const struct floatformat *fmt,
if (fmt == host_float_format)
{
float val;
+
memcpy (&val, in, sizeof (val));
*out = val;
}
else if (fmt == host_double_format)
{
double val;
+
memcpy (&val, in, sizeof (val));
*out = val;
}
else if (fmt == host_long_double_format)
{
long double val;
+
memcpy (&val, in, sizeof (val));
*out = val;
}
if (fmt == host_float_format)
{
float val = *in;
+
memcpy (out, &val, sizeof (val));
}
else if (fmt == host_double_format)
{
double val = *in;
+
memcpy (out, &val, sizeof (val));
}
else if (fmt == host_long_double_format)
{
long double val = *in;
+
memcpy (out, &val, sizeof (val));
}
else
floatformat_from_length (struct gdbarch *gdbarch, int len)
{
const struct floatformat *format;
- if (len * TARGET_CHAR_BIT == gdbarch_float_bit (gdbarch))
+
+ if (len * TARGET_CHAR_BIT == gdbarch_half_bit (gdbarch))
+ format = gdbarch_half_format (gdbarch)
+ [gdbarch_byte_order (gdbarch)];
+ else if (len * TARGET_CHAR_BIT == gdbarch_float_bit (gdbarch))
format = gdbarch_float_format (gdbarch)
[gdbarch_byte_order (gdbarch)];
else if (len * TARGET_CHAR_BIT == gdbarch_double_bit (gdbarch))
[gdbarch_byte_order (gdbarch)];
/* 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.
+ both in processor and in memory.
The code below accepts the real bit size. */
else if ((gdbarch_long_double_format (gdbarch) != NULL)
&& (len * TARGET_CHAR_BIT
floatformat_from_type (const struct type *type)
{
struct gdbarch *gdbarch = get_type_arch (type);
+
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
if (TYPE_FLOATFORMAT (type) != NULL)
return TYPE_FLOATFORMAT (type)[gdbarch_byte_order (gdbarch)];
floatformat_ieee_single[BFD_ENDIAN_BIG] = &floatformat_ieee_single_big;
floatformat_ieee_double[BFD_ENDIAN_LITTLE] = &floatformat_ieee_double_little;
floatformat_ieee_double[BFD_ENDIAN_BIG] = &floatformat_ieee_double_big;
- floatformat_arm_ext[BFD_ENDIAN_LITTLE] = &floatformat_arm_ext_littlebyte_bigword;
+ floatformat_arm_ext[BFD_ENDIAN_LITTLE]
+ = &floatformat_arm_ext_littlebyte_bigword;
floatformat_arm_ext[BFD_ENDIAN_BIG] = &floatformat_arm_ext_big;
floatformat_ia64_spill[BFD_ENDIAN_LITTLE] = &floatformat_ia64_spill_little;
floatformat_ia64_spill[BFD_ENDIAN_BIG] = &floatformat_ia64_spill_big;