This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFC] Detecting and printing 128-bit long double values for PPC
- From: Luis Machado <luisgpm at linux dot vnet dot ibm dot com>
- To: gdb-patches ml <gdb-patches at sourceware dot org>
- Date: Sat, 28 Apr 2007 02:38:24 -0300
- Subject: [RFC] Detecting and printing 128-bit long double values for PPC
- Reply-to: luisgpm at linux dot vnet dot ibm dot com
Hi,
Follows attached the patch for detecting and printing 128-bit long
double values on GDB for PPC.
This patch was originally written by Pete Carr some time ago. Since its
discussion didn't go much further, i've refreshed it to cleanly apply on
HEAD. The original message with the patch can be found here:
(http://sourceware.org/ml/gdb-patches/2006-07/msg00098.html)
I've modified some bits and pieces suggested by Mark Kettenis and
Daniel Jacobowitz on these mailing list entries.
http://sourceware.org/ml/gdb-patches/2006-07/msg00103.html
http://sourceware.org/ml/gdb-patches/2006-07/msg00107.html
Comments are welcome.
Best regards,
Luis
2007-04-26 Pete Carr <pecarr@us.ibm.com>
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.
* ppc-linux-tdep.c (ppc_linux_init_abi): Remove code that sets long double
size to 8 bytes.
* 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.
* gdbtypes.h : Added new type struct floatformats_ppc64_long_double
declaration
* gdbtypes.c : Added new type struct floatformats_ppc64_long_double
Index: gdb/configure.host
===================================================================
--- gdb/configure.host.orig 2007-04-27 21:05:28.000000000 -0700
+++ gdb/configure.host 2007-04-27 21:05:32.000000000 -0700
@@ -198,6 +198,11 @@
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/ppc-linux-tdep.c
===================================================================
--- gdb/ppc-linux-tdep.c.orig 2007-04-27 21:05:28.000000000 -0700
+++ gdb/ppc-linux-tdep.c 2007-04-27 21:12:29.000000000 -0700
@@ -1028,16 +1028,6 @@
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- /* NOTE: jimb/2004-03-26: The System V ABI PowerPC Processor
- Supplement says that long doubles are sixteen bytes long.
- However, as one of the known warts of its ABI, PPC GNU/Linux uses
- eight-byte long doubles. GCC only recently got 128-bit long
- double support on PPC, so it may be changing soon. The
- 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. */
- set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
-
if (tdep->wordsize == 4)
{
/* Until November 2001, gcc did not comply with the 32 bit SysV
Index: gdb/rs6000-tdep.c
===================================================================
--- gdb/rs6000-tdep.c.orig 2007-04-27 21:05:28.000000000 -0700
+++ gdb/rs6000-tdep.c 2007-04-27 21:05:32.000000000 -0700
@@ -3425,7 +3425,13 @@
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);
+
+ set_gdbarch_long_double_format(gdbarch, floatformats_ppc64_long_double);
+
+ 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 2007-04-27 21:05:28.000000000 -0700
+++ include/floatformat.h 2007-04-27 21:05:32.000000000 -0700
@@ -118,6 +118,9 @@
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 2007-04-27 21:05:28.000000000 -0700
+++ libiberty/floatformat.c 2007-04-27 21:05:32.000000000 -0700
@@ -106,6 +106,25 @@
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/gdbtypes.c
===================================================================
--- gdb/gdbtypes.c.orig 2007-04-27 21:05:28.000000000 -0700
+++ gdb/gdbtypes.c 2007-04-27 21:06:00.000000000 -0700
@@ -112,6 +112,11 @@
&floatformat_ieee_double_big,
&floatformat_ieee_double_littlebyte_bigword
};
+const struct floatformat *floatformats_ppc64_long_double[BFD_ENDIAN_UNKNOWN] =
+{
+ &floatformat_ppc64_long_double_big,
+ &floatformat_ppc64_long_double_little
+};
const struct floatformat *floatformats_i387_ext[BFD_ENDIAN_UNKNOWN] = {
&floatformat_i387_ext,
&floatformat_i387_ext
Index: gdb/gdbtypes.h
===================================================================
--- gdb/gdbtypes.h.orig 2007-04-27 21:05:28.000000000 -0700
+++ gdb/gdbtypes.h 2007-04-27 21:05:32.000000000 -0700
@@ -1118,6 +1118,7 @@
extern const struct floatformat *floatformats_ieee_single[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_ieee_double[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_ieee_double_littlebyte_bigword[BFD_ENDIAN_UNKNOWN];
+extern const struct floatformat *floatformats_ppc64_long_double[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_i387_ext[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_m68881_ext[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_arm_ext[BFD_ENDIAN_UNKNOWN];