aboutsummaryrefslogtreecommitdiff
path: root/gdb/doublest.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2007-11-08 00:08:48 +0000
committerJoseph Myers <joseph@codesourcery.com>2007-11-08 00:08:48 +0000
commitb14d30e141e438bf7caebb1925569510eae049d7 (patch)
tree61e4f7993a702a3ec527bda64b5ccda54ca8ee7f /gdb/doublest.c
parent5d324c3ec4090c667b24441e3a5653f1dfd8e261 (diff)
downloadgdb-b14d30e141e438bf7caebb1925569510eae049d7.zip
gdb-b14d30e141e438bf7caebb1925569510eae049d7.tar.gz
gdb-b14d30e141e438bf7caebb1925569510eae049d7.tar.bz2
include:
2007-11-07 Joseph Myers <joseph@codesourcery.com> Daniel Jacobowitz <dan@codesourcery.com> * floatformat.h (struct floatformat): Add split_half field. (floatformat_ibm_long_double): New. libiberty: 2007-11-07 Joseph Myers <joseph@codesourcery.com> Daniel Jacobowitz <dan@codesourcery.com> * floatformat.c (mant_bits_set): New. (floatformat_to_double): Use it. Note no special handling of split formats. (floatformat_from_double): Note no special handing of split formats. (floatformat_ibm_long_double_is_valid, floatformat_ibm_long_double): New. (floatformat_ieee_single_big, floatformat_ieee_single_little, floatformat_ieee_double_big, floatformat_ieee_double_little, floatformat_ieee_double_littlebyte_bigword, floatformat_vax_f, floatformat_vax_d, floatformat_vax_g, floatformat_i387_ext, floatformat_m68881_ext, floatformat_i960_ext, floatformat_m88110_ext, floatformat_m88110_harris_ext, floatformat_arm_ext_big, floatformat_arm_ext_littlebyte_bigword, floatformat_ia64_spill_big, floatformat_ia64_spill_little, floatformat_ia64_quad_big, floatformat_ia64_quad_little): Update for addition of split_half field. gdb: 2007-11-07 Joseph Myers <joseph@codesourcery.com> Daniel Jacobowitz <dan@codesourcery.com> * gdbtypes.c (floatformats_ibm_long_double): New. * gdbtypes.h (floatformats_ibm_long_double): Declare. * ia64-tdep.c (floatformat_ia64_ext): Update for addition of split_half field. * mips-tdep.c (n32n64_floatformat_always_valid, floatformat_n32n64_long_double_big, floatformats_n32n64_long): Remove. (mips_gdbarch_init): Use floatformats_ibm_long_double instead of floatformats_n32n64_long. * ppc-linux-tdep.c (ppc_linux_init_abi): Use 128-bit IBM long double. * doublest.c (convert_floatformat_to_doublest, convert_doublest_to_floatformat): Handle split floating-point formats. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call): Handle IBM long double arguments. (ppc64_sysv_abi_push_dummy_call): Likewise. (do_ppc_sysv_return_value): Handle IBM long double return.
Diffstat (limited to 'gdb/doublest.c')
-rw-r--r--gdb/doublest.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/gdb/doublest.c b/gdb/doublest.c
index c7ca993..3ec6dd3 100644
--- a/gdb/doublest.c
+++ b/gdb/doublest.c
@@ -200,6 +200,24 @@ convert_floatformat_to_doublest (const struct floatformat *fmt,
if (order != fmt->byteorder)
ufrom = newfrom;
+ if (fmt->split_half)
+ {
+ double dtop, dbot;
+ floatformat_to_double (fmt->split_half, ufrom, &dtop);
+ /* Preserve the sign of 0, which is the sign of the top
+ half. */
+ if (dtop == 0.0)
+ {
+ *to = (DOUBLEST) dtop;
+ return;
+ }
+ floatformat_to_double (fmt->split_half,
+ ufrom + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2,
+ &dbot);
+ *to = (DOUBLEST) dtop + (DOUBLEST) dbot;
+ return;
+ }
+
exponent = get_field (ufrom, order, fmt->totalsize, fmt->exp_start,
fmt->exp_len);
/* Note that if exponent indicates a NaN, we can't really do anything useful
@@ -392,6 +410,30 @@ convert_doublest_to_floatformat (CONST struct floatformat *fmt,
memcpy (&dfrom, from, sizeof (dfrom));
memset (uto, 0, (fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1)
/ FLOATFORMAT_CHAR_BIT);
+
+ if (fmt->split_half)
+ {
+ /* Use static volatile to ensure that any excess precision is
+ removed via storing in memory, and so the top half really is
+ the result of converting to double. */
+ static volatile double dtop, dbot;
+ double dtopnv, dbotnv;
+ dtop = (double) dfrom;
+ /* If the rounded top half is Inf, the bottom must be 0 not NaN
+ or Inf. */
+ if (dtop + dtop == dtop && dtop != 0.0)
+ dbot = 0.0;
+ else
+ dbot = (double) (dfrom - (DOUBLEST) dtop);
+ dtopnv = dtop;
+ dbotnv = dbot;
+ floatformat_from_double (fmt->split_half, &dtopnv, uto);
+ floatformat_from_double (fmt->split_half, &dbotnv,
+ (uto
+ + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2));
+ return;
+ }
+
if (dfrom == 0)
return; /* Result is zero */
if (dfrom != dfrom) /* Result is NaN */