From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kevin Buettner To: Andrew Cagney , Scott Bambrough Cc: GDB Mailing List Subject: store_floating() rewrite (was Re: bug in arm_push_arguments()) Date: Mon, 28 Feb 2000 11:02:00 -0000 Message-id: <1000228181141.ZM26089@ocotillo.lan> References: <38B6C4A1.7A1461C4@netwinder.org> <38BA642A.6F358273@cygnus.com> X-SW-Source: 2000-02/msg00047.html 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); }