mirror of https://github.com/PCSX2/pcsx2.git
microVU: Sort out when the Status flag is de/normalized
Properly clear non-stick invalid/zero flags on DIV/SQRT/RSQRT COP2 instructions
This commit is contained in:
parent
4b0dc9c0df
commit
9ebcb3b141
|
@ -97,7 +97,7 @@ void mVUDTendProgram(mV, microFlagCycles* mFC, int isEbit) {
|
|||
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||
xMOVAPS(ptr128[&mVU.regs().micro_macflags], xmmT1);
|
||||
|
||||
xMOVDZX(xmmT1, ptr32[&mVU.regs().VI[REG_STATUS_FLAG].UL]);
|
||||
xMOVDZX(xmmT1, getFlagReg(fStatus));
|
||||
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||
xMOVAPS(ptr128[&mVU.regs().micro_statusflags], xmmT1);
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit) {
|
|||
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||
xMOVAPS(ptr128[&mVU.regs().micro_macflags], xmmT1);
|
||||
|
||||
xMOVDZX(xmmT1, ptr32[&mVU.regs().VI[REG_STATUS_FLAG].UL]);
|
||||
xMOVDZX(xmmT1, getFlagReg(fStatus));
|
||||
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||
xMOVAPS(ptr128[&mVU.regs().micro_statusflags], xmmT1);
|
||||
}
|
||||
|
|
|
@ -95,11 +95,10 @@ void mVUdispatcherCD(mV) {
|
|||
xLDMXCSR(g_sseVUMXCSR);
|
||||
|
||||
mVUrestoreRegs(mVU);
|
||||
|
||||
xMOV(gprF0, ptr32[&mVU.statFlag[0]]);
|
||||
xMOV(gprF1, ptr32[&mVU.statFlag[1]]);
|
||||
xMOV(gprF2, ptr32[&mVU.statFlag[2]]);
|
||||
xMOV(gprF3, ptr32[&mVU.statFlag[3]]);
|
||||
xMOV(gprF0, ptr32[&mVU.regs().micro_statusflags[0]]);
|
||||
xMOV(gprF1, ptr32[&mVU.regs().micro_statusflags[1]]);
|
||||
xMOV(gprF2, ptr32[&mVU.regs().micro_statusflags[2]]);
|
||||
xMOV(gprF3, ptr32[&mVU.regs().micro_statusflags[3]]);
|
||||
|
||||
// Jump to Recompiled Code Block
|
||||
xJMP(ptrNative[&mVU.resumePtrXG]);
|
||||
|
@ -110,10 +109,10 @@ void mVUdispatcherCD(mV) {
|
|||
//xMOV(ptr32[&mVU.resumePtrXG], gprT1);
|
||||
|
||||
// Backup Status Flag (other regs were backed up on xgkick)
|
||||
xMOV(ptr32[&mVU.statFlag[0]], gprF0);
|
||||
xMOV(ptr32[&mVU.statFlag[1]], gprF1);
|
||||
xMOV(ptr32[&mVU.statFlag[2]], gprF2);
|
||||
xMOV(ptr32[&mVU.statFlag[3]], gprF3);
|
||||
xMOV(ptr32[&mVU.regs().micro_statusflags[0]], gprF0);
|
||||
xMOV(ptr32[&mVU.regs().micro_statusflags[1]], gprF1);
|
||||
xMOV(ptr32[&mVU.regs().micro_statusflags[2]], gprF2);
|
||||
xMOV(ptr32[&mVU.regs().micro_statusflags[3]], gprF3);
|
||||
|
||||
// Load EE's MXCSR state
|
||||
xLDMXCSR(g_sseMXCSR);
|
||||
|
|
|
@ -80,7 +80,10 @@ mVUop(mVU_DIV) {
|
|||
writeQreg(Fs, mVUinfo.writeQ);
|
||||
|
||||
if (mVU.cop2)
|
||||
{
|
||||
xAND(gprF0, ~0xc0000);
|
||||
xOR(gprF0, ptr32[&mVU.divFlag]);
|
||||
}
|
||||
|
||||
mVU.regAlloc->clearNeeded(Fs);
|
||||
mVU.regAlloc->clearNeeded(Ft);
|
||||
|
@ -103,7 +106,10 @@ mVUop(mVU_SQRT) {
|
|||
writeQreg(Ft, mVUinfo.writeQ);
|
||||
|
||||
if (mVU.cop2)
|
||||
{
|
||||
xAND(gprF0, ~0xc0000);
|
||||
xOR(gprF0, ptr32[&mVU.divFlag]);
|
||||
}
|
||||
|
||||
mVU.regAlloc->clearNeeded(Ft);
|
||||
mVU.profiler.EmitOp(opSQRT);
|
||||
|
@ -145,7 +151,10 @@ mVUop(mVU_RSQRT) {
|
|||
writeQreg(Fs, mVUinfo.writeQ);
|
||||
|
||||
if (mVU.cop2)
|
||||
{
|
||||
xAND(gprF0, ~0xc0000);
|
||||
xOR(gprF0, ptr32[&mVU.divFlag]);
|
||||
}
|
||||
|
||||
mVU.regAlloc->clearNeeded(Fs);
|
||||
mVU.regAlloc->clearNeeded(Ft);
|
||||
|
|
|
@ -51,8 +51,10 @@ void setupMacroOp(int mode, const char* opName) {
|
|||
microVU0.prog.IRinfo.info[0].sFlag.lastWrite = 0;
|
||||
microVU0.prog.IRinfo.info[0].mFlag.doFlag = true;
|
||||
microVU0.prog.IRinfo.info[0].mFlag.write = 0xff;
|
||||
|
||||
xMOV(gprF0, ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL]);
|
||||
//Denormalize
|
||||
mVUallocSFLAGd(&vu0Regs.VI[REG_STATUS_FLAG].UL);
|
||||
|
||||
xMOV(gprF0, eax);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,12 +63,15 @@ void endMacroOp(int mode) {
|
|||
xMOVSS(ptr32[&vu0Regs.VI[REG_Q].UL], xmmPQ);
|
||||
}
|
||||
if (mode & 0x10) { // Status/Mac Flags were Updated
|
||||
xMOV(ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL], gprF0);
|
||||
// Normalize
|
||||
mVUallocSFLAGc(eax, gprF0, 0);
|
||||
xMOV(ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL], eax);
|
||||
}
|
||||
microVU0.regAlloc->flushAll();
|
||||
|
||||
if (mode & 0x10) { // Update VU0 Status/Mac instances after flush to avoid corrupting anything
|
||||
xMOVDZX(xmmT1, ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL]);
|
||||
mVUallocSFLAGd(&vu0Regs.VI[REG_STATUS_FLAG].UL);
|
||||
xMOVDZX(xmmT1, eax);
|
||||
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||
xMOVAPS(ptr128[µVU0.regs().micro_statusflags], xmmT1);
|
||||
|
||||
|
@ -295,8 +300,7 @@ static void recCFC2() {
|
|||
iFlushCall(FLUSH_EVERYTHING);
|
||||
|
||||
if (_Rd_ == REG_STATUS_FLAG) { // Normalize Status Flag
|
||||
xMOV(gprF0, ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL]);
|
||||
mVUallocSFLAGc(eax, gprF0, 0);
|
||||
xMOV(eax, ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL]);
|
||||
}
|
||||
else xMOV(eax, ptr32[&vu0Regs.VI[_Rd_].UL]);
|
||||
|
||||
|
@ -375,21 +379,20 @@ static void recCTC2() {
|
|||
break;
|
||||
case REG_STATUS_FLAG:
|
||||
{
|
||||
if (_Rt_) { // Denormalizes flag into eax (gprT1)
|
||||
mVUallocSFLAGd(&cpuRegs.GPR.r[_Rt_].UL[0]);
|
||||
xMOV(ptr32[&vu0Regs.VI[_Rd_].UL], eax);
|
||||
if (_Rt_) {
|
||||
xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
|
||||
xAND(eax, 0xFC0);
|
||||
xAND(ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL], 0x3F);
|
||||
xOR(ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL], eax);
|
||||
|
||||
}
|
||||
else xMOV(ptr32[&vu0Regs.VI[_Rd_].UL], 0);
|
||||
__aligned16 static const u32 sticky_flags[4] = { 0xFC0,0xFC0,0xFC0,0xFC0 };
|
||||
__aligned16 static const u32 status_flags[4] = { 0x3F,0x3F,0x3F,0x3F };
|
||||
else xAND(ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL], 0x3F);
|
||||
|
||||
//Need to update the sticky flags for microVU
|
||||
xMOVDZX(xmmT1, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
|
||||
mVUallocSFLAGd(&vu0Regs.VI[REG_STATUS_FLAG].UL);
|
||||
xMOVDZX(xmmT1, eax);
|
||||
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||
xAND.PS(xmmT1, ptr128[&sticky_flags]);
|
||||
xMOVAPS(xmmT2, ptr128[&vu0Regs.micro_statusflags]);
|
||||
xAND.PS(xmmT1, ptr128[&status_flags]);
|
||||
xOR.PS(xmmT1, xmmT2);
|
||||
// Make sure the values are everywhere the need to be
|
||||
xMOVAPS(ptr128[&vu0Regs.micro_statusflags], xmmT1);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue