microVU: Move VU0 micro flag instance setup to program start

They're only used in micro mode, so no point updating them in a cop2
chain.
This commit is contained in:
Connor McLaughlin 2022-02-26 19:40:40 +10:00 committed by refractionpcsx2
parent d20bfa240d
commit 845e7930d7
3 changed files with 29 additions and 32 deletions

View File

@ -34,6 +34,21 @@ void vu0ResetRegs()
vif0Regs.stat.VEW = false;
}
static __fi u32 vu0DenormalizeMicroStatus(u32 nstatus)
{
// from mVUallocSFLAGd()
return ((nstatus >> 3) & 0x18u) | ((nstatus >> 11) & 0x1800u) | ((nstatus >> 14) & 0x3cf0000u);
}
static __fi void vu0SetMicroFlags(u32* flags, u32 value)
{
#ifdef _M_X86
_mm_store_si128(reinterpret_cast<__m128i*>(flags), _mm_set1_epi32(value));
#else
flags[0] = flags[1] = flags[2] = flags[3] = value;
#endif
}
void __fastcall vu0ExecMicro(u32 addr) {
VUM_LOG("vu0ExecMicro %x", addr);
@ -43,9 +58,20 @@ void __fastcall vu0ExecMicro(u32 addr) {
}
// Need to copy the clip flag back to the interpreter in case COP2 has edited it
VU0.clipflag = VU0.VI[REG_CLIP_FLAG].UL;
VU0.macflag = VU0.VI[REG_MAC_FLAG].UL;
VU0.statusflag = VU0.VI[REG_STATUS_FLAG].UL;
const u32 CLIP = VU0.VI[REG_CLIP_FLAG].UL;
const u32 MAC = VU0.VI[REG_MAC_FLAG].UL;
const u32 STATUS = VU0.VI[REG_STATUS_FLAG].UL;
VU0.clipflag = CLIP;
VU0.macflag = MAC;
VU0.statusflag = STATUS;
// Copy flags to micro instances, since they may be out of sync if COP2 has run.
// We do this at program start time, because COP2 can't execute until the program has completed,
// but long-running program may be interrupted so we can't do it at dispatch time.
vu0SetMicroFlags(VU0.micro_clipflags, CLIP);
vu0SetMicroFlags(VU0.micro_macflags, MAC);
vu0SetMicroFlags(VU0.micro_statusflags, vu0DenormalizeMicroStatus(STATUS));
VU0.VI[REG_VPU_STAT].UL &= ~0xFF;
VU0.VI[REG_VPU_STAT].UL |= 0x01;
VU0.cycle = cpuRegs.cycle;

View File

@ -110,16 +110,6 @@ __fi void mVUallocCFLAGb(mV, const x32& reg, int fInstance)
{
if (fInstance < 4) xMOV(ptr32[&mVU.clipFlag[fInstance]], reg); // microVU
else xMOV(ptr32[&mVU.regs().VI[REG_CLIP_FLAG].UL], reg); // macroVU
// On COP2 modifying the CLIP flag we need to update the microVU version for when it's restored on new program
if (fInstance == 0xff)
{
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
xMOVDZX(xRegisterSSE(t0reg), reg);
xPSHUF.D(xRegisterSSE(t0reg), xRegisterSSE(t0reg), 0);
xMOVDQA(ptr128[&mVU.regs().micro_clipflags], xRegisterSSE(t0reg));
_freeXMMreg(t0reg);
}
}
//------------------------------------------------------------------

View File

@ -102,16 +102,6 @@ void endMacroOp(int mode)
if (mode & 0x10)
{
if (!CHECK_VU_FLAGHACK || (g_pCurInstInfo->info & EEINST_COP2_STATUS_FLAG)) // Status/Mac Flags were Updated
{
// update micro_statusflags
const int t0reg = _allocTempXMMreg(XMMT_INT, -1);
xMOVDZX(xRegisterSSE(t0reg), gprF0);
xSHUF.PS(xRegisterSSE(t0reg), xRegisterSSE(t0reg), 0);
xMOVAPS(ptr128[&microVU0.regs().micro_statusflags], xRegisterSSE(t0reg));
_freeXMMreg(t0reg);
}
if (!CHECK_VU_FLAGHACK || g_pCurInstInfo->info & EEINST_COP2_NORMALIZE_STATUS_FLAG)
{
// Normalize
@ -124,15 +114,6 @@ void endMacroOp(int mode)
// this is fine, because we'll normalize them again before this reg is accessed
xMOV(ptr32[&vuRegs->VI[REG_STATUS_FLAG].UL], gprF0);
}
if (!CHECK_VU_FLAGHACK || (g_pCurInstInfo->info & EEINST_COP2_MAC_FLAG))
{
const int t0reg = _allocTempXMMreg(XMMT_INT, -1);
xMOVDZX(xRegisterSSE(t0reg), ptr32[&vu0Regs.VI[REG_MAC_FLAG].UL]);
xSHUF.PS(xRegisterSSE(t0reg), xRegisterSSE(t0reg), 0);
xMOVAPS(ptr128[&microVU0.regs().micro_macflags], xRegisterSSE(t0reg));
_freeXMMreg(t0reg);
}
}
microVU0.cop2 = 0;