On Mon, Aug 19, 2013 at 09:53:14AM -0600, Tom Tromey wrote: > >>>>> "Alan" == Alan Modra <amo...@gmail.com> writes: > > Alan> This teaches gdb about little-endian IBM long double. Like big-endian > Alan> IBM long double, the little-endian version is an array of two doubles. > > Alan> The patch also deletes some unused code I found in doublest.c. OK to > Alan> apply? > > The gdb bits look fine to me, but the libiberty bits will have to be > sent to the GCC patch list for approval.
Repost to gcc. As far as I know, the libiberty files I'm touching below are only used by gdb. 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 element 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 element 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 element 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