This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Detecting and printing 128-bit long double values for GDB 6.6


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)
     {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]