mirror of https://github.com/PCSX2/pcsx2.git
Vif: Backup and restore non-volatile SSE registers
This commit is contained in:
parent
ea4d988082
commit
bd4a6a10f9
|
@ -100,13 +100,13 @@ void VifUnpackSSE_Dynarec::doMaskWrite(const xRegisterSSE& regX) const
|
||||||
|
|
||||||
if (m5 < 0xf)
|
if (m5 < 0xf)
|
||||||
{
|
{
|
||||||
xPXOR(xmmTemp, xmmTemp);
|
|
||||||
if (doMode == 3)
|
if (doMode == 3)
|
||||||
{
|
{
|
||||||
mVUmergeRegs(xmmRow, regX, m5);
|
mVUmergeRegs(xmmRow, regX, m5);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
xPXOR(xmmTemp, xmmTemp);
|
||||||
mVUmergeRegs(xmmTemp, xmmRow, m5);
|
mVUmergeRegs(xmmTemp, xmmRow, m5);
|
||||||
xPADD.D(regX, xmmTemp);
|
xPADD.D(regX, xmmTemp);
|
||||||
if (doMode == 2)
|
if (doMode == 2)
|
||||||
|
@ -254,11 +254,54 @@ void VifUnpackSSE_Dynarec::CompileRoutine()
|
||||||
|
|
||||||
pxAssume(vCL == 0);
|
pxAssume(vCL == 0);
|
||||||
|
|
||||||
|
// Need a zero register for V2_32/V3 unpacks.
|
||||||
|
const bool needXmmZero = (upkNum >= 8 && upkNum <= 10) || upkNum == 4;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// See SetMasks()
|
||||||
|
const u32 m0 = vB.mask;
|
||||||
|
const u32 m3 = ((m0 & 0xaaaaaaaa) >> 1) & ~m0;
|
||||||
|
const u32 m2 = (m0 & 0x55555555) & (~m0 >> 1);
|
||||||
|
const bool needXmmRow = ((doMask && m2) || doMode);
|
||||||
|
// see doMaskWrite()
|
||||||
|
const u32 m4 = (m0 & ~((m3 << 1) | m2)) & 0x55555555;
|
||||||
|
const u32 m5 = ~(m2 | m3 | m4) & 0x0f0f0f0f;
|
||||||
|
const bool needXmmTemp = doMode && (doMode != 3) && doMask && m5 != 0x0f0f0f0f;
|
||||||
|
|
||||||
|
// Backup non-volatile registers if needed
|
||||||
|
if (needXmmZero || needXmmRow || needXmmTemp)
|
||||||
|
{
|
||||||
|
int toBackup = 0;
|
||||||
|
if (needXmmRow)
|
||||||
|
toBackup++;
|
||||||
|
if (needXmmTemp)
|
||||||
|
toBackup++;
|
||||||
|
if (needXmmZero)
|
||||||
|
toBackup++;
|
||||||
|
|
||||||
|
xSUB(rsp, 8 + 16 * toBackup);
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
if (needXmmRow)
|
||||||
|
{
|
||||||
|
xMOVAPS(ptr128[rsp], xmmRow); // xmm6
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
if (needXmmTemp)
|
||||||
|
{
|
||||||
|
xMOVAPS(ptr128[rsp + 16 * idx], xmmTemp); // xmm7
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
if (needXmmZero)
|
||||||
|
xMOVAPS(ptr128[rsp + 16 * idx], zeroReg); // xmm15
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Value passed determines # of col regs we need to load
|
// Value passed determines # of col regs we need to load
|
||||||
SetMasks(isFill ? blockSize : cycleSize);
|
SetMasks(isFill ? blockSize : cycleSize);
|
||||||
|
|
||||||
// Need a zero register for V2_32/V3 unpacks.
|
|
||||||
if ((upkNum >= 8 && upkNum <= 10) || upkNum == 4)
|
if (needXmmZero)
|
||||||
xXOR.PS(zeroReg, zeroReg);
|
xXOR.PS(zeroReg, zeroReg);
|
||||||
|
|
||||||
while (vNum)
|
while (vNum)
|
||||||
|
@ -307,6 +350,30 @@ void VifUnpackSSE_Dynarec::CompileRoutine()
|
||||||
if (doMode >= 2)
|
if (doMode >= 2)
|
||||||
writeBackRow();
|
writeBackRow();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Restore non-volatile registers
|
||||||
|
if (needXmmZero || needXmmRow || needXmmTemp)
|
||||||
|
{
|
||||||
|
int toRestore = 0;
|
||||||
|
if (needXmmRow)
|
||||||
|
{
|
||||||
|
xMOVAPS(xmmRow, ptr128[rsp]); // xmm6
|
||||||
|
toRestore++;
|
||||||
|
}
|
||||||
|
if (needXmmTemp)
|
||||||
|
{
|
||||||
|
xMOVAPS(xmmTemp, ptr128[rsp + 16 * toRestore]); // xmm7
|
||||||
|
toRestore++;
|
||||||
|
}
|
||||||
|
if (needXmmZero)
|
||||||
|
{
|
||||||
|
xMOVAPS(zeroReg, ptr128[rsp + 16 * toRestore]); // xmm15
|
||||||
|
toRestore++;
|
||||||
|
}
|
||||||
|
xADD(rsp, 8 + 16 * toRestore);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
xRET();
|
xRET();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue