This is the mail archive of the
gdb@sourceware.cygnus.com
mailing list for the GDB project.
store_floating() rewrite (was Re: bug in arm_push_arguments())
- To: Andrew Cagney <ac131313 at cygnus dot com>, Scott Bambrough <scottb at netwinder dot org>
- Subject: store_floating() rewrite (was Re: bug in arm_push_arguments())
- From: Kevin Buettner <kevinb at cygnus dot com>
- Date: Mon, 28 Feb 2000 11:11:42 -0700
- Cc: GDB Mailing List <gdb at sourceware dot cygnus dot com>
- References: <38B6C4A1.7A1461C4@netwinder.org> <38BA642A.6F358273@cygnus.com>
On Feb 28, 11:03pm, Andrew Cagney wrote:
> Kevin Buttner wrote:
> > It seems to me that you should be able to use store_floating() to do
> > what you want. It'll handle both the conversion and the byte swapping.
>
> Yes, that looks correct. I'm just not 100% sure on it working - would
> one of those if()'s before the TARGET_EXTRACT_FLOATING() get in the way?
^^^^^^^^^^^^^^^^^^^^^^^
Did you mean TARGET_STORE_FLOATING?
The part that bothers me about the way that store_floating() is
implemented is that we're comparing the size of the thing we're trying
to store into (on the target) against sizes of the host formats. I.e,
the following lines bother me.
if (len == sizeof (float))
else if (len == sizeof (double))
else if (len == sizeof (DOUBLEST))
I think we should be comparing against the sizes of the target formats.
Suppose, for example, that we have the following configuration
host float: 32 bits
host double 64 bits
target float 64 bits
target double 128 bits
and that we enter store_floating with len == 8.
This'll cause us to wind up in the following code:
else if (len == sizeof (double))
{
if (HOST_DOUBLE_FORMAT == TARGET_DOUBLE_FORMAT)
{
double doubleval = val;
memcpy (addr, &doubleval, sizeof (doubleval));
}
else
floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &val, addr);
}
Because the sizes of the doubles are different, HOST_DOUBLE_FORMAT
will not be the same as TARGET_DOUBLE_FORMAT. This means that we'll
execute the floatformat_from_doublest call which attempts to store a
(target) double.
But this is wrong since the size of a target double is 16 bytes and we
were attempting to store a floating point value whose size is 8 bytes.
Here is my rewrite of this function:
void
store_floating (void *addr, int len, DOUBLEST val)
{
if (HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT)
{
float floatval = val;
memcpy (addr, &floatval, sizeof (floatval));
}
else if (HOST_DOUBLE_FORMAT == TARGET_DOUBLE_FORMAT)
{
double doubleval = val;
memcpy (addr, &doubleval, sizeof (doubleval));
}
else if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
memcpy (addr, &val, sizeof (val));
else if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
floatformat_from_doublest (TARGET_FLOAT_FORMAT, &val, addr);
else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &val, addr);
else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
floatformat_from_doublest (TARGET_LONG_DOUBLE_FORMAT, &val, addr);
#ifdef TARGET_STORE_FLOATING
else if (TARGET_STORE_FLOATING (addr, len, val))
return;
#endif
else
error ("Can't deal with a floating point number of %d bytes.", len);
}