Kevin D. Kissell wrote:
Shane McDonald wrote:
In the following chunk of code from cp1emu.c:
[snip]
value gets set to an initial value of 0x400, and ctx->fcr31
comes in with an initial value of 0x8420.
By the time we hit the if statement around the return SIGFPE, ctx->fcr31
has been set to 0x8400, not the 0x400 I implied.
Ah, well that would rather change things, and you *would* get an
exception there. As written, the code doesn't seem to allow the pending
exception (.._X) bits to be cleared by the CTC.
Nevertheless, that's not the problem.
Maybe it is.
OK, sorry to have been looking at this in fits and starts, but indeed, I
submit that the bug is indeed in that ctc_op: case of the emulator.
The Cause bits (17:12) are supposed to be writable by that instruction,
but the CTC1 emulation won't let them be updated by the instruction. I
don't have the means to generate, test, and submit a proper patch, but I
think that actually if you just completely removed lines 387-388:
value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S |0x03);
Things would work a good deal better. At least, it would be a more
accurate emulation of the architecturally defined FPU. If I wanted to
be really, really
pedantic (which I sometimes do), I'd also protect the reserved bits that
aren't necessarily writable, so we'd nuke those two lines, then have
/* Don't write reserved bits, and convert to ieee library modes */
ctx->fcr31 = (value & ~0x1c0003) | ieee_rm[value & 0x3];
Note that I've changed the existing |= to a direct assignment here.
Hope this helps.
/K.