This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
IBM long double little-endian
- From: Alan Modra <amodra at gmail dot com>
- To: gdb-patches at sourceware dot org
- Date: Mon, 19 Aug 2013 10:09:48 +0930
- Subject: IBM long double little-endian
This teaches gdb about little-endian IBM long double. Like big-endian
IBM long double, the little-endian version is an array of two doubles.
The patch also deletes some unused code I found in doublest.c. OK to
apply?
include/
* floatformat.h (floatformat_ibm_long_double): Delete.
(floatformat_ibm_long_double_big): Declare.
(floatformat_ibm_long_double_little): Declare.
libiberty/
* floatformat.c (floatformat_ibm_long_double): Rename to..
(floatformat_ibm_long_double_big): ..this.
(floatformat_ibm_long_double_little): New.
gdb/
* doublest.c (convert_floatformat_to_doublest): Use fmt->split_half
for IBM long double nan and inf.
(floatformat_is_negative, floatformat_classify,
floatformat_mantissa): Similarly.
(floatformat_ieee_single, floatformat_ieee_double,
floatformat_ieee_quad, floatformat_arm_ext,
floatformat_ia64_spill): Delete unused vars.
(_initialize_doublest): Delete unused function.
* gdbtypes.c (floatformats_ibm_long_double): Use new big- and
little-endian variants of floatformat_ibm_long_double.
Index: include/floatformat.h
===================================================================
RCS file: /cvs/src/src/include/floatformat.h,v
retrieving revision 1.16
diff -u -p -r1.16 floatformat.h
--- include/floatformat.h 3 Jan 2011 21:05:50 -0000 1.16
+++ include/floatformat.h 16 Aug 2013 06:46:24 -0000
@@ -128,7 +128,8 @@ extern const struct floatformat floatfor
extern const struct floatformat floatformat_ia64_quad_big;
extern const struct floatformat floatformat_ia64_quad_little;
/* IBM long double (double+double). */
-extern const struct floatformat floatformat_ibm_long_double;
+extern const struct floatformat floatformat_ibm_long_double_big;
+extern const struct floatformat floatformat_ibm_long_double_little;
/* Convert from FMT to a double.
FROM is the address of the extended float.
Index: libiberty/floatformat.c
===================================================================
RCS file: /cvs/src/src/libiberty/floatformat.c,v
retrieving revision 1.28
diff -u -p -r1.28 floatformat.c
--- libiberty/floatformat.c 17 Aug 2012 21:59:31 -0000 1.28
+++ libiberty/floatformat.c 16 Aug 2013 06:46:25 -0000
@@ -371,14 +371,23 @@ floatformat_ibm_long_double_is_valid (co
}
}
-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_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
Index: gdb/doublest.c
===================================================================
RCS file: /cvs/src/src/gdb/doublest.c,v
retrieving revision 1.54
diff -u -p -r1.54 doublest.c
--- gdb/doublest.c 21 Jun 2013 16:24:14 -0000 1.54
+++ gdb/doublest.c 16 Aug 2013 06:46:22 -0000
@@ -190,7 +190,8 @@ convert_floatformat_to_doublest (const s
{
double dto;
- floatformat_to_double (fmt, from, &dto);
+ floatformat_to_double (fmt->split_half ? fmt->split_half : fmt,
+ from, &dto);
*to = (DOUBLEST) dto;
return;
}
@@ -514,6 +515,11 @@ floatformat_is_negative (const struct fl
gdb_assert (fmt->totalsize
<= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
+ /* An IBM long double (a two byte array of double) always takes the
+ sign of the first double. */
+ if (fmt->split_half)
+ fmt = fmt->split_half;
+
order = floatformat_normalize_byteorder (fmt, uval, newfrom);
if (order != fmt->byteorder)
@@ -540,6 +546,13 @@ floatformat_classify (const struct float
gdb_assert (fmt->totalsize
<= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
+ /* An IBM long double (a two byte array of double) can be classified
+ by looking at the first double. inf and nan are specified as
+ ignoring the second double. zero and subnormal will always have
+ the second double 0.0 if the long double is correctly rounded. */
+ if (fmt->split_half)
+ fmt = fmt->split_half;
+
order = floatformat_normalize_byteorder (fmt, uval, newfrom);
if (order != fmt->byteorder)
@@ -622,6 +635,16 @@ floatformat_mantissa (const struct float
gdb_assert (fmt->totalsize
<= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
+ /* For IBM long double (a two byte array of double), return the
+ mantissa of the first double. The problem with returning the
+ actual mantissa from both doubles is that there can be an
+ arbitrary number of implied 0's or 1's between the mantissas
+ of the first and second double. In any case, this function
+ is only used for dumping out nans, and a nan is specified to
+ ignore the value in the second double. */
+ if (fmt->split_half)
+ fmt = fmt->split_half;
+
order = floatformat_normalize_byteorder (fmt, uval, newfrom);
if (order != fmt->byteorder)
@@ -879,27 +902,3 @@ convert_typed_floating (const void *from
floatformat_from_doublest (to_fmt, &d, to);
}
}
-
-const struct floatformat *floatformat_ieee_single[BFD_ENDIAN_UNKNOWN];
-const struct floatformat *floatformat_ieee_double[BFD_ENDIAN_UNKNOWN];
-const struct floatformat *floatformat_ieee_quad[BFD_ENDIAN_UNKNOWN];
-const struct floatformat *floatformat_arm_ext[BFD_ENDIAN_UNKNOWN];
-const struct floatformat *floatformat_ia64_spill[BFD_ENDIAN_UNKNOWN];
-
-extern void _initialize_doublest (void);
-
-extern void
-_initialize_doublest (void)
-{
- floatformat_ieee_single[BFD_ENDIAN_LITTLE] = &floatformat_ieee_single_little;
- 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_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;
- floatformat_ieee_quad[BFD_ENDIAN_LITTLE] = &floatformat_ia64_quad_little;
- floatformat_ieee_quad[BFD_ENDIAN_BIG] = &floatformat_ia64_quad_big;
-}
Index: gdb/gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.251
diff -u -p -r1.251 gdbtypes.c
--- gdb/gdbtypes.c 15 Apr 2013 17:30:36 -0000 1.251
+++ gdb/gdbtypes.c 16 Aug 2013 06:46:22 -0000
@@ -108,8 +108,8 @@ const struct floatformat *floatformats_v
&floatformat_vax_d
};
const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN] = {
- &floatformat_ibm_long_double,
- &floatformat_ibm_long_double
+ &floatformat_ibm_long_double_big,
+ &floatformat_ibm_long_double_little
};
/* Should opaque types be resolved? */
--
Alan Modra
Australia Development Lab, IBM