microVU: more flag stuff (div/sqrt/rsqrt flags set at proper time)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@960 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-04-12 10:23:25 +00:00
parent 5b0d9b6723
commit a3c1669024
5 changed files with 40 additions and 26 deletions

View File

@ -54,6 +54,7 @@ struct microAllocInfo {
microTempRegInfo regsTemp; // Temp Pipeline info (used so that new pipeline info isn't conflicting between upper and lower instructions in the same cycle) microTempRegInfo regsTemp; // Temp Pipeline info (used so that new pipeline info isn't conflicting between upper and lower instructions in the same cycle)
u8 branch; // 0 = No Branch, 1 = B. 2 = BAL, 3~8 = Conditional Branches, 9 = JALR, 10 = JR u8 branch; // 0 = No Branch, 1 = B. 2 = BAL, 3~8 = Conditional Branches, 9 = JALR, 10 = JR
//u8 maxStall; // Helps in computing stalls (stores the max amount of cycles to stall for the current opcodes) //u8 maxStall; // Helps in computing stalls (stores the max amount of cycles to stall for the current opcodes)
//u8 divFlag;
u32 cycles; // Cycles for current block u32 cycles; // Cycles for current block
u32 count; // Number of VU 64bit instructions ran (starts at 0 for each block) u32 count; // Number of VU 64bit instructions ran (starts at 0 for each block)
u32 curPC; // Current PC u32 curPC; // Current PC

View File

@ -665,13 +665,13 @@ microVUt(void) mVUallocFMAC26b(int& ACCw, int& ACCr) {
// Flag Allocators // Flag Allocators
//------------------------------------------------------------------ //------------------------------------------------------------------
#define getFlagReg(regX, fInst) { \ #define getFlagReg(regX, fInst) { \
switch (fInst) { \ switch (fInst) { \
case 0: regX = gprF0; break; \ case 0: regX = gprF0; break; \
case 1: regX = gprF1; break; \ case 1: regX = gprF1; break; \
case 2: regX = gprF2; break; \ case 2: regX = gprF2; break; \
case 3: regX = gprF3; break; \ case 3: regX = gprF3; break; \
} \ } \
} }
microVUt(void) mVUallocSFLAGa(int reg, int fInstance) { microVUt(void) mVUallocSFLAGa(int reg, int fInstance) {

View File

@ -49,6 +49,7 @@
#define calcCycles(reg, x) { reg = ((reg > x) ? (reg - x) : 0); } #define calcCycles(reg, x) { reg = ((reg > x) ? (reg - x) : 0); }
#define incP() { mVU->p = (mVU->p+1) & 1; } #define incP() { mVU->p = (mVU->p+1) & 1; }
#define incQ() { mVU->q = (mVU->q+1) & 1; } #define incQ() { mVU->q = (mVU->q+1) & 1; }
#define doUpperOp() { mVUopU<vuIndex, 1>(); mVUdivSet<vuIndex>(); }
//------------------------------------------------------------------ //------------------------------------------------------------------
// Helper Functions // Helper Functions
@ -59,7 +60,7 @@ microVUt(void) mVUstatusFlagOp() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
int curPC = iPC; int curPC = iPC;
int i = mVUcount; int i = mVUcount;
if (doStatus) { mVUinfo |= _isSflag; } if (doStatus) { mVUinfo |= _isSflag; }
else { else {
for (; i > 0; i--) { for (; i > 0; i--) {
incPC2(-2); incPC2(-2);
@ -69,7 +70,7 @@ microVUt(void) mVUstatusFlagOp() {
for (; i > 0; i--) { for (; i > 0; i--) {
incPC2(-2); incPC2(-2);
if (isSflag) break; if (isSflag) break;
mVUinfo &= ~_doStatus; mVUinfo &= ~(_doStatus|_doDivFlag);
} }
iPC = curPC; iPC = curPC;
} }
@ -96,14 +97,14 @@ microVUt(void) mVUsetFlags(int* bStatus, int* bMac) {
iPC = mVUstartPC; iPC = mVUstartPC;
for (int i = 0; i < xCount; i++) { for (int i = 0; i < xCount; i++) {
if ((xCount - i) > aCount) mVUstatusFlagOp<vuIndex>(); // Don't Optimize out on the last ~4+ instructions if ((xCount - i) > aCount) mVUstatusFlagOp<vuIndex>(); // Don't Optimize out on the last ~4+ instructions
if (doStatus||isFSSET) { mVUinfo |= xStatus << 12; } // _fsInstance if (doStatus||isFSSET||doDivFlag) { mVUinfo |= xStatus << 12; } // _fsInstance
if (doMac) { mVUinfo |= xMac << 10; } // _fmInstance if (doMac) { mVUinfo |= xMac << 10; } // _fmInstance
pStatus = (xStatus + ((mVUstall > 3) ? 3 : mVUstall)) & 3; pStatus = (xStatus + ((mVUstall > 3) ? 3 : mVUstall)) & 3;
pMac = (xMac + ((mVUstall > 3) ? 3 : mVUstall)) & 3; pMac = (xMac + ((mVUstall > 3) ? 3 : mVUstall)) & 3;
mVUinfo |= pStatus << 18; // _fvsInstance mVUinfo |= pStatus << 18; // _fvsInstance
mVUinfo |= pMac << 16; // _fvmInstance mVUinfo |= pMac << 16; // _fvmInstance
if (doStatus||isFSSET) { xStatus = (xStatus+1) & 3; } if (doStatus||isFSSET||doDivFlag) { xStatus = (xStatus+1) & 3; }
if (doMac) { xMac = (xMac+1) & 3; } if (doMac) { xMac = (xMac+1) & 3; }
incPC2(2); incPC2(2);
} }
mVUcount = xCount; // Restore count mVUcount = xCount; // Restore count
@ -111,7 +112,7 @@ microVUt(void) mVUsetFlags(int* bStatus, int* bMac) {
// Setup Last 4 instances of Status/Mac flags (needed for accurate block linking) // Setup Last 4 instances of Status/Mac flags (needed for accurate block linking)
iPC = endPC; iPC = endPC;
for (int i = 3, int j = 3, int ii = 1, int jj = 3; aCount > 0; ii++, aCount--) { for (int i = 3, int j = 3, int ii = 1, int jj = 3; aCount > 0; ii++, aCount--) {
if (doStatus && (i >= 0)) { if ((doStatus||isFSSET||doDivFlag) && (i >= 0)) {
for (; (ii > 0 && i >= 0); ii--) { xStatus = (xStatus-1) & 3; bStatus[i] = xStatus; i--; } for (; (ii > 0 && i >= 0); ii--) { xStatus = (xStatus-1) & 3; bStatus[i] = xStatus; i--; }
} }
if (doMac && (j >= 0)) { if (doMac && (j >= 0)) {
@ -172,8 +173,9 @@ microVUt(void) mVUincCycles(int x) {
calcCycles(mVUregs.VI[z], x); calcCycles(mVUregs.VI[z], x);
} }
if (mVUregs.q) { if (mVUregs.q) {
calcCycles(mVUregs.q, x); if (mVUregs.q > 4) { calcCycles(mVUregs.q, x); if (mVUregs.q <= 4) { mVUinfo |= _doDivFlag; } }
if (!mVUregs.q) { incQ(); } // Do Status Flag Merging Stuff? else { calcCycles(mVUregs.q, x); }
if (!mVUregs.q) { incQ(); }
} }
if (mVUregs.p) { if (mVUregs.p) {
calcCycles(mVUregs.p, x); calcCycles(mVUregs.p, x);
@ -202,6 +204,15 @@ microVUt(void) mVUsetCycles() {
mVUregs.xgkick = mVUregsTemp.xgkick; mVUregs.xgkick = mVUregsTemp.xgkick;
} }
microVUt(void) mVUdivSet() {
microVU* mVU = mVUx;
int flagReg1, flagReg2;
getFlagReg(flagReg1, fsInstance);
if (!doStatus) { getFlagReg(flagReg2, fpsInstance); MOV16RtoR(flagReg1, flagReg2); }
AND16ItoR(flagReg1, 0xfcf);
OR16MtoR (flagReg1, (uptr)&mVU->divFlag);
}
//------------------------------------------------------------------ //------------------------------------------------------------------
// Recompiler // Recompiler
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -254,9 +265,9 @@ microVUx(void*) mVUcompile(u32 startPC, u32 pipelineState, microRegInfo* pState,
if (isEOB) { x = 0; } if (isEOB) { x = 0; }
//if (isBranch2) { mVUopU<vuIndex, 1>(); incPC(2); } //if (isBranch2) { mVUopU<vuIndex, 1>(); incPC(2); }
if (isNop) { mVUopU<vuIndex, 1>(); if (curI & _Ibit_) { incPC(1); mVU->iReg = curI; } else { incPC(1); } } if (isNop) { doUpperOp(); if (curI & _Ibit_) { incPC(1); mVU->iReg = curI; } else { incPC(1); } }
else if (!swapOps) { mVUopU<vuIndex, 1>(); incPC(1); mVUopL<vuIndex, 1>(); } else if (!swapOps) { doUpperOp(); incPC(1); mVUopL<vuIndex, 1>(); }
else { incPC(1); mVUopL<vuIndex, 1>(); incPC(-1); mVUopU<vuIndex, 1>(); incPC(1); } else { incPC(1); mVUopL<vuIndex, 1>(); incPC(-1); doUpperOp(); incPC(1); }
if (!isBdelay) { incPC(1); } if (!isBdelay) { incPC(1); }
else { else {

View File

@ -474,7 +474,7 @@ microVUf(void) mVU_FCSET() {
microVUf(void) mVU_FMAND() { microVUf(void) mVU_FMAND() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) {} if (!recPass) { mVUanalyzeMflag<vuIndex>(_Fs_, _Ft_); }
else { else {
mVUallocMFLAGa<vuIndex>(gprT1, fvmInstance); mVUallocMFLAGa<vuIndex>(gprT1, fvmInstance);
mVUallocVIa<vuIndex>(gprT2, _Fs_); mVUallocVIa<vuIndex>(gprT2, _Fs_);
@ -485,7 +485,7 @@ microVUf(void) mVU_FMAND() {
microVUf(void) mVU_FMEQ() { microVUf(void) mVU_FMEQ() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) {} if (!recPass) { mVUanalyzeMflag<vuIndex>(_Fs_, _Ft_); }
else { else {
mVUallocMFLAGa<vuIndex>(gprT1, fvmInstance); mVUallocMFLAGa<vuIndex>(gprT1, fvmInstance);
mVUallocVIa<vuIndex>(gprT2, _Fs_); mVUallocVIa<vuIndex>(gprT2, _Fs_);
@ -498,7 +498,7 @@ microVUf(void) mVU_FMEQ() {
microVUf(void) mVU_FMOR() { microVUf(void) mVU_FMOR() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) {} if (!recPass) { mVUanalyzeMflag<vuIndex>(_Fs_, _Ft_); }
else { else {
mVUallocMFLAGa<vuIndex>(gprT1, fvmInstance); mVUallocMFLAGa<vuIndex>(gprT1, fvmInstance);
mVUallocVIa<vuIndex>(gprT2, _Fs_); mVUallocVIa<vuIndex>(gprT2, _Fs_);
@ -547,12 +547,11 @@ microVUf(void) mVU_FSSET() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) { mVUanalyzeFSSET<vuIndex>(); } if (!recPass) { mVUanalyzeFSSET<vuIndex>(); }
else { else {
int flagReg = gprT1; int flagReg1, flagReg2;
if (doStatus) { getFlagReg(flagReg, fsInstance); } // Get status result from upper instruction getFlagReg(flagReg1, fsInstance);
else { mVUallocSFLAGa<vuIndex>(flagReg, fpsInstance); } // Get status result from last status setting instruction if (!(doStatus||doDivFlag)) { getFlagReg(flagReg2, fpsInstance); MOV16RtoR(flagReg1, flagReg2); } // Get status result from last status setting instruction
AND16ItoR(flagReg, 0x03f); // Remember not to modify upper 16 bits because of mac flag AND16ItoR(flagReg1, 0x03f); // Remember not to modify upper 16 bits because of mac flag
OR16ItoR(flagReg, (_Imm12_ & 0xfc0)); OR16ItoR (flagReg1, (_Imm12_ & 0xfc0));
if (!doStatus) { mVUallocSFLAGb<vuIndex>(flagReg, fsInstance); }
} }
} }

View File

@ -185,7 +185,9 @@ declareAllVariables
#define _writesVI (1<<25) // Current Instruction writes to VI #define _writesVI (1<<25) // Current Instruction writes to VI
#define _swapOps (1<<26) // Runs Lower Instruction Before Upper Instruction #define _swapOps (1<<26) // Runs Lower Instruction Before Upper Instruction
#define _isFSSSET (1<<27) // Cur Instruction is FSSET #define _isFSSSET (1<<27) // Cur Instruction is FSSET
//#define _isBranch2 (1<<28) // Cur Instruction is a Branch that writes VI regs (BAL/JALR) #define _doDivFlag (1<<28) // Transfer Div flag to Status Flag
//#define _isBranch2 (1<<31) // Cur Instruction is a Branch that writes VI regs (BAL/JALR)
#define isNOP (mVUinfo & (1<<0)) #define isNOP (mVUinfo & (1<<0))
#define isBranch (mVUinfo & (1<<1)) #define isBranch (mVUinfo & (1<<1))
@ -214,7 +216,8 @@ declareAllVariables
#define writesVI (mVUinfo & (1<<25)) #define writesVI (mVUinfo & (1<<25))
#define swapOps (mVUinfo & (1<<26)) #define swapOps (mVUinfo & (1<<26))
#define isFSSET (mVUinfo & (1<<27)) #define isFSSET (mVUinfo & (1<<27))
//#define isBranch2 (mVUinfo & (1<<28)) #define doDivFlag (mVUinfo & (1<<28))
//#define isBranch2 (mVUinfo & (1<<31))
#define isMMX(_VIreg_) (_VIreg_ >= 1 && _VIreg_ <=9) #define isMMX(_VIreg_) (_VIreg_ >= 1 && _VIreg_ <=9)
#define mmVI(_VIreg_) (_VIreg_ - 1) #define mmVI(_VIreg_) (_VIreg_ - 1)