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);
|
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||||
xMOVAPS(ptr128[&mVU.regs().micro_macflags], xmmT1);
|
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);
|
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||||
xMOVAPS(ptr128[&mVU.regs().micro_statusflags], xmmT1);
|
xMOVAPS(ptr128[&mVU.regs().micro_statusflags], xmmT1);
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit) {
|
||||||
xSHUF.PS(xmmT1, xmmT1, 0);
|
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||||
xMOVAPS(ptr128[&mVU.regs().micro_macflags], xmmT1);
|
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);
|
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||||
xMOVAPS(ptr128[&mVU.regs().micro_statusflags], xmmT1);
|
xMOVAPS(ptr128[&mVU.regs().micro_statusflags], xmmT1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,11 +95,10 @@ void mVUdispatcherCD(mV) {
|
||||||
xLDMXCSR(g_sseVUMXCSR);
|
xLDMXCSR(g_sseVUMXCSR);
|
||||||
|
|
||||||
mVUrestoreRegs(mVU);
|
mVUrestoreRegs(mVU);
|
||||||
|
xMOV(gprF0, ptr32[&mVU.regs().micro_statusflags[0]]);
|
||||||
xMOV(gprF0, ptr32[&mVU.statFlag[0]]);
|
xMOV(gprF1, ptr32[&mVU.regs().micro_statusflags[1]]);
|
||||||
xMOV(gprF1, ptr32[&mVU.statFlag[1]]);
|
xMOV(gprF2, ptr32[&mVU.regs().micro_statusflags[2]]);
|
||||||
xMOV(gprF2, ptr32[&mVU.statFlag[2]]);
|
xMOV(gprF3, ptr32[&mVU.regs().micro_statusflags[3]]);
|
||||||
xMOV(gprF3, ptr32[&mVU.statFlag[3]]);
|
|
||||||
|
|
||||||
// Jump to Recompiled Code Block
|
// Jump to Recompiled Code Block
|
||||||
xJMP(ptrNative[&mVU.resumePtrXG]);
|
xJMP(ptrNative[&mVU.resumePtrXG]);
|
||||||
|
@ -110,10 +109,10 @@ void mVUdispatcherCD(mV) {
|
||||||
//xMOV(ptr32[&mVU.resumePtrXG], gprT1);
|
//xMOV(ptr32[&mVU.resumePtrXG], gprT1);
|
||||||
|
|
||||||
// Backup Status Flag (other regs were backed up on xgkick)
|
// Backup Status Flag (other regs were backed up on xgkick)
|
||||||
xMOV(ptr32[&mVU.statFlag[0]], gprF0);
|
xMOV(ptr32[&mVU.regs().micro_statusflags[0]], gprF0);
|
||||||
xMOV(ptr32[&mVU.statFlag[1]], gprF1);
|
xMOV(ptr32[&mVU.regs().micro_statusflags[1]], gprF1);
|
||||||
xMOV(ptr32[&mVU.statFlag[2]], gprF2);
|
xMOV(ptr32[&mVU.regs().micro_statusflags[2]], gprF2);
|
||||||
xMOV(ptr32[&mVU.statFlag[3]], gprF3);
|
xMOV(ptr32[&mVU.regs().micro_statusflags[3]], gprF3);
|
||||||
|
|
||||||
// Load EE's MXCSR state
|
// Load EE's MXCSR state
|
||||||
xLDMXCSR(g_sseMXCSR);
|
xLDMXCSR(g_sseMXCSR);
|
||||||
|
|
|
@ -80,7 +80,10 @@ mVUop(mVU_DIV) {
|
||||||
writeQreg(Fs, mVUinfo.writeQ);
|
writeQreg(Fs, mVUinfo.writeQ);
|
||||||
|
|
||||||
if (mVU.cop2)
|
if (mVU.cop2)
|
||||||
|
{
|
||||||
|
xAND(gprF0, ~0xc0000);
|
||||||
xOR(gprF0, ptr32[&mVU.divFlag]);
|
xOR(gprF0, ptr32[&mVU.divFlag]);
|
||||||
|
}
|
||||||
|
|
||||||
mVU.regAlloc->clearNeeded(Fs);
|
mVU.regAlloc->clearNeeded(Fs);
|
||||||
mVU.regAlloc->clearNeeded(Ft);
|
mVU.regAlloc->clearNeeded(Ft);
|
||||||
|
@ -103,7 +106,10 @@ mVUop(mVU_SQRT) {
|
||||||
writeQreg(Ft, mVUinfo.writeQ);
|
writeQreg(Ft, mVUinfo.writeQ);
|
||||||
|
|
||||||
if (mVU.cop2)
|
if (mVU.cop2)
|
||||||
|
{
|
||||||
|
xAND(gprF0, ~0xc0000);
|
||||||
xOR(gprF0, ptr32[&mVU.divFlag]);
|
xOR(gprF0, ptr32[&mVU.divFlag]);
|
||||||
|
}
|
||||||
|
|
||||||
mVU.regAlloc->clearNeeded(Ft);
|
mVU.regAlloc->clearNeeded(Ft);
|
||||||
mVU.profiler.EmitOp(opSQRT);
|
mVU.profiler.EmitOp(opSQRT);
|
||||||
|
@ -145,7 +151,10 @@ mVUop(mVU_RSQRT) {
|
||||||
writeQreg(Fs, mVUinfo.writeQ);
|
writeQreg(Fs, mVUinfo.writeQ);
|
||||||
|
|
||||||
if (mVU.cop2)
|
if (mVU.cop2)
|
||||||
|
{
|
||||||
|
xAND(gprF0, ~0xc0000);
|
||||||
xOR(gprF0, ptr32[&mVU.divFlag]);
|
xOR(gprF0, ptr32[&mVU.divFlag]);
|
||||||
|
}
|
||||||
|
|
||||||
mVU.regAlloc->clearNeeded(Fs);
|
mVU.regAlloc->clearNeeded(Fs);
|
||||||
mVU.regAlloc->clearNeeded(Ft);
|
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].sFlag.lastWrite = 0;
|
||||||
microVU0.prog.IRinfo.info[0].mFlag.doFlag = true;
|
microVU0.prog.IRinfo.info[0].mFlag.doFlag = true;
|
||||||
microVU0.prog.IRinfo.info[0].mFlag.write = 0xff;
|
microVU0.prog.IRinfo.info[0].mFlag.write = 0xff;
|
||||||
|
//Denormalize
|
||||||
xMOV(gprF0, ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL]);
|
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);
|
xMOVSS(ptr32[&vu0Regs.VI[REG_Q].UL], xmmPQ);
|
||||||
}
|
}
|
||||||
if (mode & 0x10) { // Status/Mac Flags were Updated
|
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();
|
microVU0.regAlloc->flushAll();
|
||||||
|
|
||||||
if (mode & 0x10) { // Update VU0 Status/Mac instances after flush to avoid corrupting anything
|
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);
|
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||||
xMOVAPS(ptr128[µVU0.regs().micro_statusflags], xmmT1);
|
xMOVAPS(ptr128[µVU0.regs().micro_statusflags], xmmT1);
|
||||||
|
|
||||||
|
@ -295,8 +300,7 @@ static void recCFC2() {
|
||||||
iFlushCall(FLUSH_EVERYTHING);
|
iFlushCall(FLUSH_EVERYTHING);
|
||||||
|
|
||||||
if (_Rd_ == REG_STATUS_FLAG) { // Normalize Status Flag
|
if (_Rd_ == REG_STATUS_FLAG) { // Normalize Status Flag
|
||||||
xMOV(gprF0, ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL]);
|
xMOV(eax, ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL]);
|
||||||
mVUallocSFLAGc(eax, gprF0, 0);
|
|
||||||
}
|
}
|
||||||
else xMOV(eax, ptr32[&vu0Regs.VI[_Rd_].UL]);
|
else xMOV(eax, ptr32[&vu0Regs.VI[_Rd_].UL]);
|
||||||
|
|
||||||
|
@ -375,21 +379,20 @@ static void recCTC2() {
|
||||||
break;
|
break;
|
||||||
case REG_STATUS_FLAG:
|
case REG_STATUS_FLAG:
|
||||||
{
|
{
|
||||||
if (_Rt_) { // Denormalizes flag into eax (gprT1)
|
if (_Rt_) {
|
||||||
mVUallocSFLAGd(&cpuRegs.GPR.r[_Rt_].UL[0]);
|
xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
|
||||||
xMOV(ptr32[&vu0Regs.VI[_Rd_].UL], eax);
|
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);
|
else xAND(ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL], 0x3F);
|
||||||
__aligned16 static const u32 sticky_flags[4] = { 0xFC0,0xFC0,0xFC0,0xFC0 };
|
|
||||||
__aligned16 static const u32 status_flags[4] = { 0x3F,0x3F,0x3F,0x3F };
|
|
||||||
|
|
||||||
//Need to update the sticky flags for microVU
|
//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);
|
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||||
xAND.PS(xmmT1, ptr128[&sticky_flags]);
|
// Make sure the values are everywhere the need to be
|
||||||
xMOVAPS(xmmT2, ptr128[&vu0Regs.micro_statusflags]);
|
|
||||||
xAND.PS(xmmT1, ptr128[&status_flags]);
|
|
||||||
xOR.PS(xmmT1, xmmT2);
|
|
||||||
xMOVAPS(ptr128[&vu0Regs.micro_statusflags], xmmT1);
|
xMOVAPS(ptr128[&vu0Regs.micro_statusflags], xmmT1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue