mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
5b0d9b6723
commit
a3c1669024
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -69,7 +70,7 @@ microVUt(void) mVUstatusFlagOp() {
|
|||
for (; i > 0; i--) {
|
||||
incPC2(-2);
|
||||
if (isSflag) break;
|
||||
mVUinfo &= ~_doStatus;
|
||||
mVUinfo &= ~(_doStatus|_doDivFlag);
|
||||
}
|
||||
iPC = curPC;
|
||||
}
|
||||
|
@ -96,13 +97,13 @@ 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 (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 (doStatus||isFSSET||doDivFlag) { xStatus = (xStatus+1) & 3; }
|
||||
if (doMac) { xMac = (xMac+1) & 3; }
|
||||
incPC2(2);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue