Re: [hatari-devel] Bug in FPU code |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/hatari-devel Archives
]
Hi,
On maanantai 05 maaliskuu 2012, Andreas Grabher wrote:
> While working on Previous i found a bug in the FPU code and fixed it.
> This makes the FPU pass NeXT's power-on test using 68040 with its
> internal FPU. 68030/68882 still not working but getting to the next
> stage now.
>
> I appended the patch to this message.
> As i am still new to coding, please check the code before applying the
> patch.
>
> diff -crB /Users/andi/Desktop/branch_scsiold/src/cpu/md-fpp.h
> /Users/andi/Desktop/branch_scsi/src/cpu/md-fpp.h ***
....
> STATIC_INLINE void from_exten(long double src, uae_u32 * wrd1, uae_u32
> * wrd2, uae_u32 * wrd3) {
> register uae_u32 *longarray = (uae_u32 *)&src;
> ! // register uae_u16 *finalword = (uae_u16 *)(&src + 8);
>
> ! // *wrd1 = ((uae_u32)*finalword)<<16;
> ! *wrd1 = (longarray[2] & 0xffff)<<16;
> *wrd2 = longarray[1];
> *wrd3 = longarray[0]; // little endian
> }
Both the original and new code make non-portable assumptions about the sizes
of long doubles. Long doubles can be 8, 12 or 16 bytes depending on
platform:
http://en.wikipedia.org/wiki/C_data_types
Original code is completely broken as it took a pointer to long double
argument and converted data at +8*sizeof(long double) offset of that long
double to something else. I.e. it went way past the size of long double
and probably had some random data in wrd1.
New code is better. It takes low word from long at +2*4 bytes offset in
long double and shifts that to high word. It may actually do something
valid with certain long double sizes. I guess it's intended to work right
with 12-byte long doubles... Andreas?
With 16-byte long doubles it may come up with wrong result and with 8-byte
long doubles wrd1 still gets random garbage.
On my machine (which runs 32-bit Linux), long doubles seem to be 12-bytes,
so maybe it's a good default at least... Compiler could give a warning
if FPU emulation is enabled with "wrong" sized long doubles.
- Eero
#include <stdio.h>
int main() {
printf("sizeof(long double) = %d\n", sizeof(long double));
return 0;
}