This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch] Detecting and printing 128-bit long double values for GDB 6.6
- From: Luis Machado <luisgpm at linux dot vnet dot ibm dot com>
- To: gdb-patches ml <gdb-patches at sourceware dot org>
- Date: Mon, 23 Apr 2007 15:19:26 -0300
- Subject: [patch] Detecting and printing 128-bit long double values for GDB 6.6
- Reply-to: luisgpm at linux dot vnet dot ibm dot com
Hi folks,
Attached is the patch previously written by Pete Carr for correcting the
issue where GDB is unable to print the value of a 128-bit long double
variable. This patch makes GDB recognize that data type and also makes
it print the correct value with its full precision. I refreshed this
patch for GDB 6.6, in case users of this version would like to use it.
A version of the patch for GDB HEAD is being worked on and will be
submitted soon, since it requires some code changes due to a
modification in the handling of Big endian/Little endian values.
Best regards,
Luis
2007-04-23 Luis Machado <luisgpm@br.ibm.com>
* rs6000-tdep.c (rs6000_gdbarch_init): Set the long double format for
powerpc64.
* configure.host : Set the host long double format for powerpc64 to be
a 128-bit type defined in libiberty/floatformat.c.
* floatformat.c : Introduce default floatformat structs to describe the
128-bit long double found on the powerpc64. Description does not fully
describe this format which is actually a pair of 64-bit doubles. However
we are relying on floatformat_to_doublest() recognizing that this is
also the default host floatformat.
* floatformat.h : Default floatformat structs for powerpc64 128-bit
long doubles.
Index: gdb/configure.host
===================================================================
--- gdb/configure.host.orig
+++ gdb/configure.host
@@ -188,6 +188,11 @@ m68*-*-*)
gdb_host_double_format="&floatformat_ieee_double_big"
gdb_host_long_double_format="&floatformat_m68881_ext"
;;
+powerpc64-*-*)
+ gdb_host_float_format=0
+ gdb_host_double_format=0
+ gdb_host_long_double_format="&floatformat_ppc64_long_double_big"
+ ;;
*)
gdb_host_float_format=0
gdb_host_double_format=0
Index: gdb/rs6000-tdep.c
===================================================================
--- gdb/rs6000-tdep.c.orig
+++ gdb/rs6000-tdep.c
@@ -3391,7 +3391,19 @@ rs6000_gdbarch_init (struct gdbarch_info
set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
if (sysv_abi)
- set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
+ {
+ int byte_order = gdbarch_byte_order (gdbarch);
+
+ if (byte_order == BFD_ENDIAN_BIG)
+ set_gdbarch_long_double_format (gdbarch, &floatformat_ppc64_long_double_big);
+ else if (byte_order == BFD_ENDIAN_LITTLE)
+ set_gdbarch_long_double_format (gdbarch, &floatformat_ppc64_long_double_little);
+ else
+ internal_error (__FILE__, __LINE__,
+ _("rs6000_gdbarch_init: "
+ "bad byte order"));
+ set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
+ }
else
set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
set_gdbarch_char_signed (gdbarch, 0);
Index: include/floatformat.h
===================================================================
--- include/floatformat.h.orig
+++ include/floatformat.h
@@ -118,6 +118,9 @@ extern const struct floatformat floatfor
extern const struct floatformat floatformat_ia64_spill_little;
extern const struct floatformat floatformat_ia64_quad_big;
extern const struct floatformat floatformat_ia64_quad_little;
+/* ppc64 long double implemented as 2 doubles */
+extern const struct floatformat floatformat_ppc64_long_double_big;
+extern const struct floatformat floatformat_ppc64_long_double_little;
/* Convert from FMT to a double.
FROM is the address of the extended float.
Index: libiberty/floatformat.c
===================================================================
--- libiberty/floatformat.c.orig
+++ libiberty/floatformat.c
@@ -106,6 +106,25 @@ const struct floatformat floatformat_iee
floatformat_always_valid
};
+/* floatformats for ppc64 long double, big and little endian. */
+/* The layout is a pair of doubles. Don't use this description to pass */
+/* information to get_field(). The bit size is the important thing. */
+const struct floatformat floatformat_ppc64_long_double_big =
+{
+ floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52,
+ floatformat_intbit_no,
+ "floatformat_ppc64_long_double_big",
+ floatformat_always_valid
+};
+
+const struct floatformat floatformat_ppc64_long_double_little =
+{
+ floatformat_little, 128, 0, 1, 11, 1023, 2047, 12, 52,
+ floatformat_intbit_no,
+ "floatformat_ppc64_long_double_little",
+ floatformat_always_valid
+};
+
/* floatformat for IEEE double, little endian byte order, with big endian word
ordering, as on the ARM. */
Index: gdb/ppc-linux-tdep.c
===================================================================
--- gdb/ppc-linux-tdep.c.orig
+++ gdb/ppc-linux-tdep.c
@@ -1036,7 +1036,9 @@ ppc_linux_init_abi (struct gdbarch_info
Linux[sic] Standards Base says that programs that use 'long
double' on PPC GNU/Linux are non-conformant. */
/* NOTE: cagney/2005-01-25: True for both 32- and 64-bit. */
+#if 0
set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+#endif
if (tdep->wordsize == 4)
{