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)
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 divFlag;
u32 cycles; // Cycles for current block
u32 count; // Number of VU 64bit instructions ran (starts at 0 for each block)
u32 curPC; // Current PC

View File

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

View File

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

View File

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

View File

@ -185,7 +185,9 @@ declareAllVariables
#define _writesVI (1<<25) // Current Instruction writes to VI
#define _swapOps (1<<26) // Runs Lower Instruction Before Upper Instruction
#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 isBranch (mVUinfo & (1<<1))
@ -214,7 +216,8 @@ declareAllVariables
#define writesVI (mVUinfo & (1<<25))
#define swapOps (mVUinfo & (1<<26))
#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 mmVI(_VIreg_) (_VIreg_ - 1)