* [RFC] Support alternate 'long double' size.
@ 2003-02-17 16:54 Pierre Muller
2003-02-18 19:46 ` Andrew Cagney
0 siblings, 1 reply; 4+ messages in thread
From: Pierre Muller @ 2003-02-17 16:54 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1995 bytes --]
The i387 floting point unit handles 'long double' float type
with 80 bits, but GCC and most compilers pretend that this
type is 96 bit long (mainly for alignment purposes).
Nevertheless, at least Free Pascal does use 80 bit size for this type.
As GDB does not recognize this size, the stabs output has been
twisted to simulate 96 bit 'long double' type, so that normal
'extended' (the Free Pascal name of this float type) variables
can be inspected correctly.
Nevertheless, this leads to a very bad situation when we try to inspect
Free Pascal arrays of extended, because GDB searches the second element
at offset 12 (in bytes) relative to the first address, when it is in fact at offset 10.
To avoid GDB from outputing non-sense, I added
an explicit size specific to the stabs output, this leads
CVS head GDB to claim about the fact that it does not know
how to handle 10 byte long floats.
The following patch add a new variable to the gdbarch vector:
long_double_bit_alternate
which can be used to accept a second size for
the same type 'long double'.
The default value is 0, which renders it useless unless
explicitly set.
It is then set to 80 bit in i386-tdep.c
The addition of long_double_bit_alternate variable leads to
the creation of the new macro
TARGET_LONG_DOUBLE_BIT_ALTERNATE
that is used in function floatformat_from_length
to return the same type as for TARGET_LONG_DOUBLE_BIT.
This simple patch allows to correctly display
arrays of extended in Free Pascal compiled code.
I don't know really if this is used in other compilers,
but I suspect that it could be also used in
x86-64-tdep.c or ia64-tdep.c.
ChangeLog entry:
2003-02-17 Pierre Muller <muller@ics.u-strasbg.fr>
* gdbarch.sh: Add long_double_bit_alternate variable.
* gdbarch.h, gdbarch.c: Re-genarate.
* doublest.c (floatformat_from_length): Accept also
long_double_bit_alternate length for 'long double' type.
* i386-tdep.c (i386_gdbarch_init ): Set long_double_bit_alternate to 80.
[-- Attachment #2: Type: text/plain, Size: 6915 bytes --]
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.181
diff -u -p -r1.181 gdbarch.c
--- gdbarch.c 29 Jan 2003 18:07:06 -0000 1.181
+++ gdbarch.c 17 Feb 2003 16:07:19 -0000
@@ -140,6 +140,7 @@ struct gdbarch
int float_bit;
int double_bit;
int long_double_bit;
+ int long_double_bit_alternate;
int ptr_bit;
int addr_bit;
int bfd_vma_bit;
@@ -304,6 +305,7 @@ struct gdbarch startup_gdbarch =
8 * sizeof (float),
8 * sizeof (double),
8 * sizeof (long double),
+ 0,
8 * sizeof (void*),
8 * sizeof (void*),
8 * sizeof (void*),
@@ -491,6 +493,7 @@ gdbarch_alloc (const struct gdbarch_info
current_gdbarch->float_bit = 4*TARGET_CHAR_BIT;
current_gdbarch->double_bit = 8*TARGET_CHAR_BIT;
current_gdbarch->long_double_bit = 8*TARGET_CHAR_BIT;
+ current_gdbarch->long_double_bit_alternate = 0;
current_gdbarch->ptr_bit = TARGET_INT_BIT;
current_gdbarch->bfd_vma_bit = TARGET_ARCHITECTURE->bits_per_address;
current_gdbarch->char_signed = -1;
@@ -621,6 +624,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of float_bit, invalid_p == 0 */
/* Skip verify of double_bit, invalid_p == 0 */
/* Skip verify of long_double_bit, invalid_p == 0 */
+ /* Skip verify of long_double_bit_alternate, invalid_p == 0 */
/* Skip verify of ptr_bit, invalid_p == 0 */
if (gdbarch->addr_bit == 0)
gdbarch->addr_bit = TARGET_PTR_BIT;
@@ -2404,6 +2408,14 @@ gdbarch_dump (struct gdbarch *gdbarch, s
"gdbarch_dump: TARGET_LONG_DOUBLE_BIT = %d\n",
TARGET_LONG_DOUBLE_BIT);
#endif
+#ifdef TARGET_LONG_DOUBLE_BIT_ALTERNATE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_LONG_DOUBLE_BIT_ALTERNATE # %s\n",
+ XSTRING (TARGET_LONG_DOUBLE_BIT_ALTERNATE));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_LONG_DOUBLE_BIT_ALTERNATE = %d\n",
+ TARGET_LONG_DOUBLE_BIT_ALTERNATE);
+#endif
#ifdef TARGET_LONG_DOUBLE_FORMAT
fprintf_unfiltered (file,
"gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT # %s\n",
@@ -2712,6 +2724,23 @@ set_gdbarch_long_double_bit (struct gdba
int long_double_bit)
{
gdbarch->long_double_bit = long_double_bit;
+}
+
+int
+gdbarch_long_double_bit_alternate (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of long_double_bit_alternate, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_long_double_bit_alternate called\n");
+ return gdbarch->long_double_bit_alternate;
+}
+
+void
+set_gdbarch_long_double_bit_alternate (struct gdbarch *gdbarch,
+ int long_double_bit_alternate)
+{
+ gdbarch->long_double_bit_alternate = long_double_bit_alternate;
}
int
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.142
diff -u -p -r1.142 gdbarch.h
--- gdbarch.h 2 Feb 2003 03:16:44 -0000 1.142
+++ gdbarch.h 17 Feb 2003 16:07:19 -0000
@@ -240,6 +240,24 @@ extern void set_gdbarch_long_double_bit
#endif
#endif
+/* Alternate number of bits in a long double for the target machine. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_LONG_DOUBLE_BIT_ALTERNATE)
+#define TARGET_LONG_DOUBLE_BIT_ALTERNATE (8*TARGET_CHAR_BIT)
+#endif
+
+extern int gdbarch_long_double_bit_alternate (struct gdbarch *gdbarch);
+extern void set_gdbarch_long_double_bit_alternate (struct gdbarch *gdbarch, int long_double_bit_alternate);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_LONG_DOUBLE_BIT_ALTERNATE)
+#error "Non multi-arch definition of TARGET_LONG_DOUBLE_BIT_ALTERNATE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_LONG_DOUBLE_BIT_ALTERNATE)
+#define TARGET_LONG_DOUBLE_BIT_ALTERNATE (gdbarch_long_double_bit_alternate (current_gdbarch))
+#endif
+#endif
+
/* For most targets, a pointer on the target and its representation as an
address in GDB have the same size and "look the same". For such a
target, you need only set TARGET_PTR_BIT / ptr_bit and TARGET_ADDR_BIT
@@ -2429,7 +2447,7 @@ extern void set_gdbarch_addr_bits_remove
#endif
#endif
-/* It is not at all clear why SMASH_TEXT_ADDRESS is not folded into
+/* It is not at all clear why SMASH_TEXT_ADDRESS is not folded into
ADDR_BITS_REMOVE. */
/* Default (function) for non- multi-arch platforms. */
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.194
diff -u -p -r1.194 gdbarch.sh
--- gdbarch.sh 2 Feb 2003 03:16:44 -0000 1.194
+++ gdbarch.sh 17 Feb 2003 16:07:19 -0000
@@ -408,6 +408,8 @@ v:2:TARGET_FLOAT_BIT:int:float_bit::::8
v:2:TARGET_DOUBLE_BIT:int:double_bit::::8 * sizeof (double):8*TARGET_CHAR_BIT::0
# Number of bits in a long double for the target machine.
v:2:TARGET_LONG_DOUBLE_BIT:int:long_double_bit::::8 * sizeof (long double):8*TARGET_CHAR_BIT::0
+# Alternate number of bits in a long double for the target machine.
+v:2:TARGET_LONG_DOUBLE_BIT_ALTERNATE:int:long_double_bit_alternate::::0:0::0
# For most targets, a pointer on the target and its representation as an
# address in GDB have the same size and "look the same". For such a
# target, you need only set TARGET_PTR_BIT / ptr_bit and TARGET_ADDR_BIT
Index: doublest.c
===================================================================
RCS file: /cvs/src/src/gdb/doublest.c,v
retrieving revision 1.11
diff -u -p -r1.11 doublest.c
--- doublest.c 4 Dec 2002 05:40:40 -0000 1.11
+++ doublest.c 17 Feb 2003 16:07:19 -0000
@@ -633,6 +633,8 @@ floatformat_from_length (int len)
return TARGET_DOUBLE_FORMAT;
else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
return TARGET_LONG_DOUBLE_FORMAT;
+ else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT_ALTERNATE)
+ return TARGET_LONG_DOUBLE_FORMAT;
return NULL;
}
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.111
diff -u -p -r1.111 i386-tdep.c
--- i386-tdep.c 8 Jan 2003 15:56:36 -0000 1.111
+++ i386-tdep.c 17 Feb 2003 16:07:19 -0000
@@ -1533,6 +1533,9 @@ i386_gdbarch_init (struct gdbarch_info i
bits, a `long double' actually takes up 96, probably to enforce
alignment. */
set_gdbarch_long_double_bit (gdbarch, 96);
+ /* Allow also recognition of floating-point that has a size
+ of 80 bits. */
+ set_gdbarch_long_double_bit_alternate (gdbarch, 80);
/* NOTE: tm-i386aix.h, tm-i386bsd.h, tm-i386os9k.h, tm-ptx.h,
tm-symmetry.h currently override this. Sigh. */
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [RFC] Support alternate 'long double' size.
2003-02-17 16:54 [RFC] Support alternate 'long double' size Pierre Muller
@ 2003-02-18 19:46 ` Andrew Cagney
2003-03-11 12:21 ` [RFA] Support true " Pierre Muller
0 siblings, 1 reply; 4+ messages in thread
From: Andrew Cagney @ 2003-02-18 19:46 UTC (permalink / raw)
To: Pierre Muller; +Cc: gdb-patches
> Index: doublest.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/doublest.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 doublest.c
> --- doublest.c 4 Dec 2002 05:40:40 -0000 1.11
> +++ doublest.c 17 Feb 2003 16:07:19 -0000
> @@ -633,6 +633,8 @@ floatformat_from_length (int len)
> return TARGET_DOUBLE_FORMAT;
> else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
> return TARGET_LONG_DOUBLE_FORMAT;
> + else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT_ALTERNATE)
> + return TARGET_LONG_DOUBLE_FORMAT;
>
> return NULL;
> }
Would simply adding:
else if (TARGET_LONG_DOUBLE_FORMAT != NULL
&& len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_FORMAT->totalsize)
..
to the end of that if() chain work? (and the other alternatives as well
of course).
Otherwize, yes, I can't see any other way of handling this problem :-(
Andrew
^ permalink raw reply [flat|nested] 4+ messages in thread* [RFA] Support true 'long double' size.
2003-02-18 19:46 ` Andrew Cagney
@ 2003-03-11 12:21 ` Pierre Muller
[not found] ` <3E6DF2A2.8030609@redhat.com>
0 siblings, 1 reply; 4+ messages in thread
From: Pierre Muller @ 2003-03-11 12:21 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
At 20:51 18/02/2003, Andrew Cagney wrote:
>>Index: doublest.c
>>===================================================================
>>RCS file: /cvs/src/src/gdb/doublest.c,v
>>retrieving revision 1.11
>>diff -u -p -r1.11 doublest.c
>>--- doublest.c 4 Dec 2002 05:40:40 -0000 1.11
>>+++ doublest.c 17 Feb 2003 16:07:19 -0000
>>@@ -633,6 +633,8 @@ floatformat_from_length (int len)
>> return TARGET_DOUBLE_FORMAT;
>> else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
>> return TARGET_LONG_DOUBLE_FORMAT;
>>+ else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT_ALTERNATE)
>>+ return TARGET_LONG_DOUBLE_FORMAT;
>>
>> return NULL;
>> }
>
>Would simply adding:
>
>else if (TARGET_LONG_DOUBLE_FORMAT != NULL
> && len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_FORMAT->totalsize)
> ..
>
>to the end of that if() chain work? (and the other alternatives as well of course).
Yes this works and has the same functionality
for the i386 specific problem.
>Otherwize, yes, I can't see any other way of handling this problem :-(
The old patch might still be usefull for other processors,
but I am not sure about that.
So here is a new simplified patch proposal:
ChangeLog entry:
2003-03-11 Pierre Muller <muller@ics.u-strasbg.fr>
* doublest.c (floatformat_from_length): Accept also
the real size of 'long double' type.
Index: doublest.c
===================================================================
RCS file: /cvs/src/src/gdb/doublest.c,v
retrieving revision 1.12
diff -p -u -r1.12 doublest.c
--- doublest.c 27 Feb 2003 18:08:25 -0000 1.12
+++ doublest.c 11 Mar 2003 12:17:52 -0000
@@ -633,6 +633,14 @@ floatformat_from_length (int len)
return TARGET_DOUBLE_FORMAT;
else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
return TARGET_LONG_DOUBLE_FORMAT;
+ /* On i386 the 'long double' type takes 96 bits,
+ while the real number of used bits is only 80,
+ both in processor and in memory.
+ The code below accepts the real bit size. */
+ else if ((TARGET_LONG_DOUBLE_FORMAT)
+ && (len * TARGET_CHAR_BIT ==
+ TARGET_LONG_DOUBLE_FORMAT->totalsize))
+ return TARGET_LONG_DOUBLE_FORMAT;
return NULL;
}
Pierre Muller
Institut Charles Sadron
6,rue Boussingault
F 67083 STRASBOURG CEDEX (France)
mailto:muller@ics.u-strasbg.fr
Phone : (33)-3-88-41-40-07 Fax : (33)-3-88-41-40-99
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2003-03-11 16:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-17 16:54 [RFC] Support alternate 'long double' size Pierre Muller
2003-02-18 19:46 ` Andrew Cagney
2003-03-11 12:21 ` [RFA] Support true " Pierre Muller
[not found] ` <3E6DF2A2.8030609@redhat.com>
2003-03-11 16:39 ` Pierre Muller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox