On 29 November 2017 at 09:59, william lin <wlsai...@gmail.com> wrote: > This bug has been around for 7+ years now. Qemu switched to softfloat and > it did not fix this. I think its most likely caused by Qemu's internal > representation not being accurate enough or accuracy lost during > conversion. However this is basically what is given to us in the bug > report, and I have not been able to make much progress past this point, so > we are asking for help.
Looking at the bug, it seems like inaccuracies in the results of some of the transcendental operations (sin, cos, etc). This is almost certainly the because our implementations of these in target/i386/fpu_helper.c do this: void helper_fsin(CPUX86State *env) { double fptemp = floatx80_to_double(env, ST0); if ((fptemp > MAXTAN) || (fptemp < -MAXTAN)) { env->fpus |= 0x400; } else { ST0 = double_to_floatx80(env, sin(fptemp)); env->fpus &= ~0x400; /* C2 <-- 0 */ /* the above code is for |arg| < 2**53 only */ } } ie convert the 80-bit value in the emulated FPU to a host double, call the host libc sin() function and convert the resulting double to 80-bit. Fixing this to be bit-for-bit accurate will require that we write our own transcendental arithmetic functions that can handle 80-bit precision, which is a bit of a hairy task. (Probably all the functions that call floatx80_to_double() would need to be rewritten. We currently use this approach for the "complicated" operations that the x87 provides but which softfloat doesn't: sin, cos, powers, logs, that sort of thing.) I was going to suggest that we borrow the code to do this from bochs, which does seem to have implemented complete software emulation of these complicated x87 instructions, but unfortunately the relevant files in bochs are under the softfloat-2b license, which isn't (by the QEMU project's reading of the license) compatible with the GPLv2 which we use :-( thanks -- PMM