mirror of https://github.com/PCSX2/pcsx2.git
microVU:
- mac flags now stored memory instead of in upper 16 bits of GPRs. - minor changes... git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1159 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
85c8e4c4af
commit
f4c3560c75
|
@ -102,7 +102,6 @@ struct microVU {
|
|||
u8* exitFunct; // Ptr Function to the Exit code for recompiled programs
|
||||
u32 code; // Contains the current Instruction
|
||||
u32 iReg; // iReg (only used in recompilation, not execution)
|
||||
u32 clipFlag[4]; // 4 instances of clip flag (used in execution)
|
||||
u32 divFlag; // 1 instance of I/D flags
|
||||
u32 VIbackup[2]; // Holds a backup of a VI reg if modified before a branch
|
||||
u32 branch; // Holds branch compare result (IBxx) OR Holds address to Jump to (JALR/JR)
|
||||
|
@ -112,6 +111,8 @@ struct microVU {
|
|||
u32 totalCycles;
|
||||
u32 cycles;
|
||||
|
||||
PCSX2_ALIGNED16(u32 macFlag[4]); // 4 instances of mac flag (used in execution)
|
||||
PCSX2_ALIGNED16(u32 clipFlag[4]); // 4 instances of clip flag (used in execution)
|
||||
PCSX2_ALIGNED16(u32 xmmPQb[4]); // Backup for xmmPQ
|
||||
};
|
||||
|
||||
|
|
|
@ -679,27 +679,25 @@ microVUt(void) mVUallocFMAC26b(int& ACCw, int& ACCr) {
|
|||
}
|
||||
|
||||
microVUt(void) mVUallocSFLAGa(int reg, int fInstance) {
|
||||
microVU* mVU = mVUx;
|
||||
getFlagReg(fInstance, fInstance);
|
||||
MOVZX32R16toR(reg, fInstance);
|
||||
}
|
||||
|
||||
microVUt(void) mVUallocSFLAGb(int reg, int fInstance) {
|
||||
getFlagReg(fInstance, fInstance);
|
||||
MOV16RtoR(fInstance, reg);
|
||||
//AND32ItoR(reg, 0xffff);
|
||||
MOV32RtoR(fInstance, reg);
|
||||
}
|
||||
|
||||
microVUt(void) mVUallocMFLAGa(int reg, int fInstance) {
|
||||
getFlagReg(fInstance, fInstance);
|
||||
MOV32RtoR(reg, fInstance);
|
||||
SHR32ItoR(reg, 16);
|
||||
microVU* mVU = mVUx;
|
||||
MOVZX32M16toR(reg, (uptr)&mVU->macFlag[fInstance]);
|
||||
}
|
||||
|
||||
microVUt(void) mVUallocMFLAGb(int reg, int fInstance) {
|
||||
getFlagReg(fInstance, fInstance);
|
||||
AND32ItoR(fInstance, 0xffff);
|
||||
SHL32ItoR(reg, 16);
|
||||
OR32RtoR(fInstance, reg);
|
||||
microVU* mVU = mVUx;
|
||||
//AND32ItoR(reg, 0xffff);
|
||||
MOV32RtoM((uptr)&mVU->macFlag[fInstance], reg);
|
||||
}
|
||||
|
||||
microVUt(void) mVUallocCFLAGa(int reg, int fInstance) {
|
||||
|
|
|
@ -120,12 +120,9 @@ microVUt(void) mVUendProgram(int fStatus, int fMac) {
|
|||
|
||||
// Save Flag Instances
|
||||
getFlagReg(fStatus, fStatus);
|
||||
getFlagReg(fMac, fMac);
|
||||
MOV32RtoR(gprT1, fStatus);
|
||||
AND32ItoR(gprT1, 0xffff);
|
||||
SHR32ItoR(fMac, 16);
|
||||
MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, gprT1);
|
||||
MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, fMac);
|
||||
mVUallocMFLAGa<vuIndex>(gprT1, fMac);
|
||||
MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, fStatus);
|
||||
MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprT1);
|
||||
|
||||
//memcpy_fast(&pBlock->pStateEnd, &mVUregs, sizeof(microRegInfo));
|
||||
//MOV32ItoM((uptr)&mVU->prog.lpState, (int)&mVUblock.pState); // Save pipeline state (clipflag instance)
|
||||
|
|
|
@ -48,17 +48,14 @@ microVUt(void) mVUdispatcherA() {
|
|||
// Load Regs
|
||||
MOV32MtoR(gprR, (uptr)&mVU->regs->VI[REG_R].UL);
|
||||
MOV32MtoR(gprF0, (uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL);
|
||||
MOV32MtoR(gprF1, (uptr)&mVU->regs->VI[REG_MAC_FLAG].UL);
|
||||
SHL32ItoR(gprF0, 16);
|
||||
AND32ItoR(gprF1, 0xffff);
|
||||
OR32RtoR (gprF0, gprF1);
|
||||
AND32ItoR(gprF0, 0xffff);
|
||||
MOV32RtoR(gprF1, gprF0);
|
||||
MOV32RtoR(gprF2, gprF0);
|
||||
MOV32RtoR(gprF3, gprF0);
|
||||
|
||||
for (int i = 1; i < 16; i++) {
|
||||
if (isMMX(i)) { MOVQMtoR(mmVI(i), (uptr)&mVU->regs->VI[i].UL); }
|
||||
}
|
||||
SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VI[REG_MAC_FLAG].UL);
|
||||
SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, 0);
|
||||
SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, xmmT1);
|
||||
|
||||
SSE_MOVAPS_M128_to_XMM(xmmACC, (uptr)&mVU->regs->ACC.UL[0]);
|
||||
SSE_MOVAPS_M128_to_XMM(xmmMax, (uptr)mVU_maxvals);
|
||||
|
@ -67,10 +64,14 @@ microVUt(void) mVUdispatcherA() {
|
|||
SSE_MOVAPS_M128_to_XMM(xmmPQ, (uptr)&mVU->regs->VI[REG_Q].UL);
|
||||
SSE_SHUFPS_XMM_to_XMM(xmmPQ, xmmT1, 0); // wzyx = PPQQ
|
||||
|
||||
for (int i = 1; i < 16; i++) {
|
||||
if (isMMX(i)) { MOVQMtoR(mmVI(i), (uptr)&mVU->regs->VI[i].UL); }
|
||||
}
|
||||
|
||||
//PUSH32R(EAX);
|
||||
//CALLFunc((uptr)testFunction);
|
||||
//POP32R(EAX);
|
||||
//write8(0xcc);
|
||||
//POP32R(EAX);
|
||||
|
||||
// Jump to Recompiled Code Block
|
||||
JMPR(EAX);
|
||||
|
@ -140,7 +141,9 @@ microVUt(void) mVUcleanUp() {
|
|||
//mVUprint("microVU: VI0 = %x", params mVU->regs->VI[0].UL);
|
||||
mVUcurProg.x86ptr = x86Ptr;
|
||||
mVUcacheCheck(x86Ptr, mVUcurProg.x86start, (uptr)(mVUcurProg.x86end - mVUcurProg.x86start));
|
||||
mVU->regs->cycle += mVU->totalCycles - mVU->cycles;
|
||||
mVU->cycles = mVU->totalCycles - mVU->cycles;
|
||||
mVU->regs->cycle += mVU->cycles;
|
||||
cpuRegs.cycle += ((mVU->cycles < 3000) ? mVU->cycles : 3000) * Config.Hacks.VUCycleSteal;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -39,7 +39,7 @@ microVUt(void) mVUdivSet() {
|
|||
int flagReg1, flagReg2;
|
||||
if (doDivFlag) {
|
||||
getFlagReg(flagReg1, fsInstance);
|
||||
if (!doStatus) { getFlagReg(flagReg2, fpsInstance); MOV16RtoR(flagReg1, flagReg2); }
|
||||
if (!doStatus) { getFlagReg(flagReg2, fpsInstance); MOV32RtoR(flagReg1, flagReg2); }
|
||||
AND16ItoR(flagReg1, 0x0fcf);
|
||||
OR32MtoR (flagReg1, (uptr)&mVU->divFlag);
|
||||
}
|
||||
|
@ -134,42 +134,25 @@ microVUt(void) mVUsetFlags(int* bStatus, int* bMac) {
|
|||
}
|
||||
|
||||
#define getFlagReg1(x) ((x == 3) ? gprF3 : ((x == 2) ? gprF2 : ((x == 1) ? gprF1 : gprF0)))
|
||||
#define getFlagReg2(x) ((x == bStatus[3]) ? gprESP : ((x == bStatus[2]) ? gprR : ((x == bStatus[1]) ? gprT2 : gprT1)))
|
||||
#define shuffleMac ((bMac[3]<<6)|(bMac[2]<<4)|(bMac[1]<<2)|bMac[0])
|
||||
|
||||
// Recompiles Code for Proper Flags on Block Linkings
|
||||
microVUt(void) mVUsetupFlags(int* bStatus, int* bMac) {
|
||||
microVU* mVU = mVUx;
|
||||
|
||||
PUSH32R(gprR); // Backup gprR
|
||||
MOV32RtoM((uptr)&mVU->espBackup, gprESP);
|
||||
|
||||
MOV32RtoR(gprT1, getFlagReg1(bStatus[0]));
|
||||
MOV32RtoR(gprT2, getFlagReg1(bStatus[1]));
|
||||
MOV32RtoR(gprR, getFlagReg1(bStatus[2]));
|
||||
MOV32RtoR(gprESP, getFlagReg1(bStatus[3]));
|
||||
|
||||
MOV32RtoR(gprF3, getFlagReg1(bStatus[3]));
|
||||
MOV32RtoR(gprF0, gprT1);
|
||||
MOV32RtoR(gprF1, gprT2);
|
||||
MOV32RtoR(gprF2, gprR);
|
||||
MOV32RtoR(gprF3, gprESP);
|
||||
|
||||
AND32ItoR(gprT1, 0xffff0000);
|
||||
AND32ItoR(gprT2, 0xffff0000);
|
||||
AND32ItoR(gprR, 0xffff0000);
|
||||
AND32ItoR(gprESP, 0xffff0000);
|
||||
|
||||
AND32ItoR(gprF0, 0x0000ffff);
|
||||
AND32ItoR(gprF1, 0x0000ffff);
|
||||
AND32ItoR(gprF2, 0x0000ffff);
|
||||
AND32ItoR(gprF3, 0x0000ffff);
|
||||
|
||||
OR32RtoR(gprF0, getFlagReg2(bMac[0]));
|
||||
OR32RtoR(gprF1, getFlagReg2(bMac[1]));
|
||||
OR32RtoR(gprF2, getFlagReg2(bMac[2]));
|
||||
OR32RtoR(gprF3, getFlagReg2(bMac[3]));
|
||||
|
||||
MOV32MtoR(gprESP, (uptr)&mVU->espBackup);
|
||||
POP32R(gprR); // Restore gprR
|
||||
|
||||
SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)mVU->macFlag);
|
||||
SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, shuffleMac);
|
||||
SSE_MOVAPS_XMM_to_M128((uptr)mVU->macFlag, xmmT1);
|
||||
}
|
||||
|
||||
#endif //PCSX2_MICROVU
|
|
@ -576,7 +576,7 @@ microVUf(void) mVU_FSSET() {
|
|||
pass2 {
|
||||
int flagReg1, flagReg2;
|
||||
getFlagReg(flagReg1, fsInstance);
|
||||
if (!(doStatus||doDivFlag)) { getFlagReg(flagReg2, fpsInstance); MOV16RtoR(flagReg1, flagReg2); } // Get status result from last status setting instruction
|
||||
if (!(doStatus||doDivFlag)) { getFlagReg(flagReg2, fpsInstance); MOV32RtoR(flagReg1, flagReg2); } // Get status result from last status setting instruction
|
||||
AND16ItoR(flagReg1, 0x03f); // Remember not to modify upper 16 bits because of mac flag
|
||||
OR16ItoR (flagReg1, (_Imm12_ & 0xfc0));
|
||||
}
|
||||
|
|
|
@ -129,11 +129,11 @@ declareAllVariables
|
|||
#define gprT1 0 // Temp Reg
|
||||
#define gprT2 1 // Temp Reg
|
||||
#define gprR 2 // R Reg
|
||||
#define gprF0 3 // MAC Flag::Status Flag 0
|
||||
#define gprF0 3 // Status Flag 0
|
||||
#define gprESP 4 // Don't use?
|
||||
#define gprF1 5 // MAC Flag::Status Flag 1
|
||||
#define gprF2 6 // MAC Flag::Status Flag 2
|
||||
#define gprF3 7 // MAC Flag::Status Flag 3
|
||||
#define gprF1 5 // Status Flag 1
|
||||
#define gprF2 6 // Status Flag 2
|
||||
#define gprF3 7 // Status Flag 3
|
||||
|
||||
// Template Stuff
|
||||
#define mVUx (vuIndex ? µVU1 : µVU0)
|
||||
|
|
|
@ -105,20 +105,20 @@ microVUx(void) mVUsaveReg(int reg, uptr offset, int xyzw, bool modXYZW) {
|
|||
return;*/
|
||||
|
||||
switch ( xyzw ) {
|
||||
case 5: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xe1); //WZXY
|
||||
case 5: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xe1); //WZXY
|
||||
SSE_MOVSS_XMM_to_M32(offset+4, reg);
|
||||
SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xff); //WWWW
|
||||
SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xff); //WWWW
|
||||
SSE_MOVSS_XMM_to_M32(offset+12, reg);
|
||||
break; // YW
|
||||
case 6: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xc9);
|
||||
case 6: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xc9);
|
||||
SSE_MOVLPS_XMM_to_M64(offset+4, reg);
|
||||
break; // YZ
|
||||
case 7: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0x93); //ZYXW
|
||||
case 7: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x93); //ZYXW
|
||||
SSE_MOVHPS_XMM_to_M64(offset+4, reg);
|
||||
SSE_MOVSS_XMM_to_M32(offset+12, reg);
|
||||
break; // YZW
|
||||
case 9: SSE_MOVSS_XMM_to_M32(offset, reg);
|
||||
SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xff); //WWWW
|
||||
SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xff); //WWWW
|
||||
SSE_MOVSS_XMM_to_M32(offset+12, reg);
|
||||
break; // XW
|
||||
case 10: SSE_MOVSS_XMM_to_M32(offset, reg);
|
||||
|
@ -128,7 +128,7 @@ microVUx(void) mVUsaveReg(int reg, uptr offset, int xyzw, bool modXYZW) {
|
|||
case 11: SSE_MOVSS_XMM_to_M32(offset, reg);
|
||||
SSE_MOVHPS_XMM_to_M64(offset+8, reg);
|
||||
break; //XZW
|
||||
case 13: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0x4b); //YXZW
|
||||
case 13: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x4b); //YXZW
|
||||
SSE_MOVHPS_XMM_to_M64(offset, reg);
|
||||
SSE_MOVSS_XMM_to_M32(offset+12, reg);
|
||||
break; // XYW
|
||||
|
@ -163,20 +163,20 @@ microVUx(void) mVUsaveReg2(int reg, int gprReg, u32 offset, int xyzw) {
|
|||
return;*/
|
||||
|
||||
switch ( xyzw ) {
|
||||
case 5: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xe1); //WZXY
|
||||
case 5: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xe1); //WZXY
|
||||
SSE_MOVSS_XMM_to_Rm(gprReg, reg, offset+4);
|
||||
SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xff); //WWWW
|
||||
SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xff); //WWWW
|
||||
SSE_MOVSS_XMM_to_Rm(gprReg, reg, offset+12);
|
||||
break; // YW
|
||||
case 6: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xc9);
|
||||
case 6: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xc9);
|
||||
SSE_MOVLPS_XMM_to_Rm(gprReg, reg, offset+4);
|
||||
break; // YZ
|
||||
case 7: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0x93); //ZYXW
|
||||
case 7: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x93); //ZYXW
|
||||
SSE_MOVHPS_XMM_to_Rm(gprReg, reg, offset+4);
|
||||
SSE_MOVSS_XMM_to_Rm(gprReg, reg, offset+12);
|
||||
break; // YZW
|
||||
case 9: SSE_MOVSS_XMM_to_Rm(gprReg, reg, offset);
|
||||
SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xff); //WWWW
|
||||
SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xff); //WWWW
|
||||
SSE_MOVSS_XMM_to_Rm(gprReg, reg, offset+12);
|
||||
break; // XW
|
||||
case 10: SSE_MOVSS_XMM_to_Rm(gprReg, reg, offset);
|
||||
|
@ -186,7 +186,7 @@ microVUx(void) mVUsaveReg2(int reg, int gprReg, u32 offset, int xyzw) {
|
|||
case 11: SSE_MOVSS_XMM_to_Rm(gprReg, reg, offset);
|
||||
SSE_MOVHPS_XMM_to_Rm(gprReg, reg, offset+8);
|
||||
break; //XZW
|
||||
case 13: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0x4b); //YXZW
|
||||
case 13: SSE_SHUFPS_XMM_to_XMM(reg, reg, 0x4b); //YXZW
|
||||
SSE_MOVHPS_XMM_to_Rm(gprReg, reg, offset);
|
||||
SSE_MOVSS_XMM_to_Rm(gprReg, reg, offset+12);
|
||||
break; // XYW
|
||||
|
|
|
@ -34,13 +34,14 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
|
|||
static u8 *pjmp, *pjmp2;
|
||||
static const u16 flipMask[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
|
||||
|
||||
//SysPrintf("doStatus = %d; doMac = %d\n", doStatus>>9, doMac>>8);
|
||||
if (!doFlags) return;
|
||||
if (!doMac) { regT1 = reg; }
|
||||
else { SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); } // Flip wzyx to xyzw
|
||||
if (doStatus) {
|
||||
getFlagReg(sReg, fsInstance); // Set sReg to valid GPR by Cur Flag Instance
|
||||
mVUallocSFLAGa<vuIndex>(sReg, fpsInstance); // Get Prev Status Flag
|
||||
AND16ItoR(sReg, 0xff0); // Keep Sticky and D/I flags
|
||||
AND32ItoR(sReg, 0xff0); // Keep Sticky and D/I flags
|
||||
}
|
||||
|
||||
//-------------------------Check for Signed flags------------------------------
|
||||
|
@ -53,7 +54,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
|
|||
|
||||
SSE_MOVMSKPS_XMM_to_R32(mReg, regT2); // Move the sign bits of the t1reg
|
||||
|
||||
AND16ItoR(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation
|
||||
AND32ItoR(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation
|
||||
pjmp = JZ8(0); // Skip if none are
|
||||
if (doMac) SHL16ItoR(mReg, 4 + ADD_XYZW);
|
||||
if (doStatus) OR16ItoR(sReg, 0x82); // SS, S flags
|
||||
|
@ -62,7 +63,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
|
|||
|
||||
//-------------------------Check for Zero flags------------------------------
|
||||
|
||||
AND16ItoR(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation
|
||||
AND32ItoR(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation
|
||||
pjmp = JZ8(0); // Skip if none are
|
||||
if (doMac) { SHIFT_XYZW(gprT2); OR32RtoR(mReg, gprT2); }
|
||||
if (doStatus) { OR16ItoR(sReg, 0x41); } // ZS, Z flags
|
||||
|
|
Loading…
Reference in New Issue