mirror of https://github.com/PCSX2/pcsx2.git
microVU:
- Backing up some changes before I revert... git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1301 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
ebff9ec1c5
commit
28f52a3f12
|
@ -59,7 +59,6 @@
|
||||||
#define tCycles(dest, src) { dest = aMax(dest, src); }
|
#define tCycles(dest, src) { dest = aMax(dest, src); }
|
||||||
#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() { mVUdivSet(mVU); mVUopU(mVU, 1); }
|
|
||||||
#define doLowerOp() { incPC(-1); mVUopL(mVU, 1); incPC(1); }
|
#define doLowerOp() { incPC(-1); mVUopL(mVU, 1); incPC(1); }
|
||||||
#define doIbit() { if (mVUup.iBit) { incPC(-1); MOV32ItoM((uptr)&mVU->regs->VI[REG_I].UL, curI); incPC(1); } }
|
#define doIbit() { if (mVUup.iBit) { incPC(-1); MOV32ItoM((uptr)&mVU->regs->VI[REG_I].UL, curI); incPC(1); } }
|
||||||
|
|
||||||
|
@ -275,10 +274,11 @@ microVUf(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
|
||||||
mVUbranch = 0;
|
mVUbranch = 0;
|
||||||
int x;
|
int x;
|
||||||
for (x = 0; x < (vuIndex ? (0x3fff/8) : (0xfff/8)); x++) {
|
for (x = 0; x < (vuIndex ? (0x3fff/8) : (0xfff/8)); x++) {
|
||||||
|
mVUdivSet(mVU);
|
||||||
if (mVUinfo.isEOB) { x = 0xffff; }
|
if (mVUinfo.isEOB) { x = 0xffff; }
|
||||||
if (mVUlow.isNOP) { incPC(1); doUpperOp(); doIbit(); }
|
if (mVUlow.isNOP) { incPC(1); mVUopU(mVU, 1); doIbit(); }
|
||||||
else if (!mVUinfo.swapOps) { incPC(1); doUpperOp(); doLowerOp(); }
|
else if (!mVUinfo.swapOps) { incPC(1); mVUopU(mVU, 1); doLowerOp(); }
|
||||||
else { mVUopL(mVU, 1); incPC(1); doUpperOp(); }
|
else { mVUopL(mVU, 1); incPC(1); mVUopU(mVU, 1); }
|
||||||
if (mVUinfo.doXGKICK) { mVU_XGKICK_DELAY(mVU, 1); }
|
if (mVUinfo.doXGKICK) { mVU_XGKICK_DELAY(mVU, 1); }
|
||||||
|
|
||||||
if (!mVUinfo.isBdelay) { incPC(1); }
|
if (!mVUinfo.isBdelay) { incPC(1); }
|
||||||
|
@ -373,12 +373,10 @@ eBitTemination:
|
||||||
memset(&mVUinfo, 0, sizeof(mVUinfo));
|
memset(&mVUinfo, 0, sizeof(mVUinfo));
|
||||||
incCycles(100); // Ensures Valid P/Q instances (And sets all cycle data to 0)
|
incCycles(100); // Ensures Valid P/Q instances (And sets all cycle data to 0)
|
||||||
mVUcycles -= 100;
|
mVUcycles -= 100;
|
||||||
/*if (mVUinfo.doDivFlag) {
|
if (mVUinfo.doDivFlag) {
|
||||||
int flagReg;
|
AND32ItoR(gprST, 0xfcf);
|
||||||
getFlagReg(flagReg, lStatus);
|
OR32MtoR (gprST, (uptr)&mVU->divFlag);
|
||||||
AND32ItoR (flagReg, 0x0fcf);
|
}
|
||||||
OR32MtoR (flagReg, (uptr)&mVU->divFlag);
|
|
||||||
}*/
|
|
||||||
if (mVUinfo.doXGKICK) { mVU_XGKICK_DELAY(mVU, 1); }
|
if (mVUinfo.doXGKICK) { mVU_XGKICK_DELAY(mVU, 1); }
|
||||||
|
|
||||||
// Do E-bit end stuff here
|
// Do E-bit end stuff here
|
||||||
|
|
|
@ -42,10 +42,7 @@ microVUt(void) mVUdispatcherA(mV) {
|
||||||
// Load Regs
|
// Load Regs
|
||||||
MOV32ItoR(gprR, Roffset); // Load VI Reg Offset
|
MOV32ItoR(gprR, Roffset); // Load VI Reg Offset
|
||||||
MOV32MtoR(gprST, (uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL);
|
MOV32MtoR(gprST, (uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL);
|
||||||
/*AND32ItoR(gprST, 0xffff);
|
AND32ItoR(gprST, 0xffff);
|
||||||
MOV32RtoR(gprF1, gprST);
|
|
||||||
MOV32RtoR(gprF2, gprST);
|
|
||||||
MOV32RtoR(gprF3, gprST);*/
|
|
||||||
|
|
||||||
SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VI[REG_MAC_FLAG].UL);
|
SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VI[REG_MAC_FLAG].UL);
|
||||||
SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, 0);
|
SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, 0);
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
// Sets FDIV Flags at the proper time
|
// Sets FDIV Flags at the proper time
|
||||||
microVUt(void) mVUdivSet(mV) {
|
microVUt(void) mVUdivSet(mV) {
|
||||||
if (mVUinfo.doDivFlag) {
|
if (mVUinfo.doDivFlag) {
|
||||||
AND32ItoR(gprST, 0xfffcffff); // Clear D/I bits
|
AND32ItoR(gprST, 0xfcf); // Clear D/I bits
|
||||||
OR32MtoR (gprST, (uptr)&mVU->divFlag); // Set DS/IS/D/I bits
|
OR32MtoR (gprST, (uptr)&mVU->divFlag); // Set DS/IS/D/I bits
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
SSE_MOVMSKPS_XMM_to_R32(gprTemp, xmmReg); \
|
SSE_MOVMSKPS_XMM_to_R32(gprTemp, xmmReg); \
|
||||||
TEST32ItoR(gprTemp, 1); /* Check sign bit */ \
|
TEST32ItoR(gprTemp, 1); /* Check sign bit */ \
|
||||||
aJump = JZ8(0); /* Skip if positive */ \
|
aJump = JZ8(0); /* Skip if positive */ \
|
||||||
MOV32ItoM((uptr)&mVU->divFlag, 0x410000); /* Set Invalid Flags */ \
|
MOV32ItoM((uptr)&mVU->divFlag, 0x410); /* Set Invalid Flags */ \
|
||||||
SSE_ANDPS_M128_to_XMM(xmmReg, (uptr)mVU_absclip); /* Abs(xmmReg) */ \
|
SSE_ANDPS_M128_to_XMM(xmmReg, (uptr)mVU_absclip); /* Abs(xmmReg) */ \
|
||||||
x86SetJ8(aJump); \
|
x86SetJ8(aJump); \
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,10 @@ mVUop(mVU_DIV) {
|
||||||
|
|
||||||
testZero(xmmFs, xmmT1, gprT1); // Test if Fs is zero
|
testZero(xmmFs, xmmT1, gprT1); // Test if Fs is zero
|
||||||
ajmp = JZ8(0);
|
ajmp = JZ8(0);
|
||||||
MOV32ItoM((uptr)&mVU->divFlag, 0x410000); // Set invalid flag (0/0)
|
MOV32ItoM((uptr)&mVU->divFlag, 0x410); // Set invalid flag (0/0)
|
||||||
bjmp = JMP8(0);
|
bjmp = JMP8(0);
|
||||||
x86SetJ8(ajmp);
|
x86SetJ8(ajmp);
|
||||||
MOV32ItoM((uptr)&mVU->divFlag, 0x820000); // Zero divide (only when not 0/0)
|
MOV32ItoM((uptr)&mVU->divFlag, 0x820); // Zero divide (only when not 0/0)
|
||||||
x86SetJ8(bjmp);
|
x86SetJ8(bjmp);
|
||||||
|
|
||||||
SSE_XORPS_XMM_to_XMM(xmmFs, xmmFt);
|
SSE_XORPS_XMM_to_XMM(xmmFs, xmmFt);
|
||||||
|
@ -112,10 +112,10 @@ mVUop(mVU_RSQRT) {
|
||||||
|
|
||||||
testZero(xmmFs, xmmT1, gprT1); // Test if Fs is zero
|
testZero(xmmFs, xmmT1, gprT1); // Test if Fs is zero
|
||||||
bjmp = JZ8(0); // Skip if none are
|
bjmp = JZ8(0); // Skip if none are
|
||||||
MOV32ItoM((uptr)&mVU->divFlag, 0x410000); // Set invalid flag (0/0)
|
MOV32ItoM((uptr)&mVU->divFlag, 0x410); // Set invalid flag (0/0)
|
||||||
cjmp = JMP8(0);
|
cjmp = JMP8(0);
|
||||||
x86SetJ8(bjmp);
|
x86SetJ8(bjmp);
|
||||||
MOV32ItoM((uptr)&mVU->divFlag, 0x820000); // Zero divide flag (only when not 0/0)
|
MOV32ItoM((uptr)&mVU->divFlag, 0x820); // Zero divide flag (only when not 0/0)
|
||||||
x86SetJ8(cjmp);
|
x86SetJ8(cjmp);
|
||||||
|
|
||||||
SSE_ANDPS_M128_to_XMM(xmmFs, (uptr)mVU_signbit);
|
SSE_ANDPS_M128_to_XMM(xmmFs, (uptr)mVU_signbit);
|
||||||
|
@ -557,13 +557,9 @@ mVUop(mVU_FSOR) {
|
||||||
mVUop(mVU_FSSET) {
|
mVUop(mVU_FSSET) {
|
||||||
pass1 { mVUanalyzeFSSET(mVU); }
|
pass1 { mVUanalyzeFSSET(mVU); }
|
||||||
pass2 {
|
pass2 {
|
||||||
int mask;
|
int imm = _Imm12_ & 0xfc0;
|
||||||
if (_Imm12_ & 0x800) mask |= 0x800000;
|
AND32ItoR(gprST, 0x3ff);
|
||||||
if (_Imm12_ & 0x400) mask |= 0x400000;
|
if (imm) OR32ItoR(gprST, imm);
|
||||||
if (_Imm12_ & 0x080) mask |= 0x0000f0;
|
|
||||||
if (_Imm12_ & 0xc40) mask |= 0x00000f;
|
|
||||||
AND32ItoR(gprST, 0x30000);
|
|
||||||
if (mask) OR32ItoR(gprST, mask);
|
|
||||||
}
|
}
|
||||||
pass3 { mVUlog("FSSET $%x", _Imm12_); }
|
pass3 { mVUlog("FSSET $%x", _Imm12_); }
|
||||||
pass4 { mVUsFlagHack = 0; }
|
pass4 { mVUsFlagHack = 0; }
|
||||||
|
|
|
@ -137,16 +137,6 @@ declareAllVariables
|
||||||
#define gprT5 6 // Temp?
|
#define gprT5 6 // Temp?
|
||||||
#define gprR 7 // VI Reg Offset
|
#define gprR 7 // VI Reg Offset
|
||||||
#define gprST 3 // Status Sticky Flag
|
#define gprST 3 // Status Sticky Flag
|
||||||
// gprST's Info is Stored as follows:
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//|23 22 21 20||19 18 17 16||15 14 13 12||11 10 09 08||07 06 05 04||03 02 01 00|
|
|
||||||
//|DS|IS| || | D| I|| OS || US || SS || ZS |
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Storing Flags this way eliminates Jumps when updating sticky flags.
|
|
||||||
//
|
|
||||||
// When a Status Flag will be read, gprST is attached with
|
|
||||||
// the current status flag result in mVUupdateFlags. And the complete
|
|
||||||
// Status flag instance is stored in memory (mVU->statusFlag[instance])
|
|
||||||
|
|
||||||
// Function Params
|
// Function Params
|
||||||
#define mP microVU* mVU, int recPass
|
#define mP microVU* mVU, int recPass
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
// Note: If modXYZW is true, then it adjusts XYZW for Single Scalar operations
|
// Note: If modXYZW is true, then it adjusts XYZW for Single Scalar operations
|
||||||
microVUt(void) mVUupdateFlags(mV, int reg, int regT1, int regT2, int xyzw, bool modXYZW) {
|
microVUt(void) mVUupdateFlags(mV, int reg, int regT1, int regT2, int xyzw, bool modXYZW) {
|
||||||
int sReg = gprT3, mReg = gprT1;
|
int /*sReg = gprT3,*/ mReg = gprT1;
|
||||||
static u8 *pjmp, *pjmp2;
|
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};
|
static const u16 flipMask[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
|
||||||
|
|
||||||
|
@ -37,54 +37,39 @@ microVUt(void) mVUupdateFlags(mV, int reg, int regT1, int regT2, int xyzw, bool
|
||||||
if (!mVUup.doFlags || (!sFLAG.doSticky && !sFLAG.doFlag && !mFLAG.doFlag)) { return; }
|
if (!mVUup.doFlags || (!sFLAG.doSticky && !sFLAG.doFlag && !mFLAG.doFlag)) { return; }
|
||||||
if (!mFLAG.doFlag || (_XYZW_SS && modXYZW)) { regT1 = reg; }
|
if (!mFLAG.doFlag || (_XYZW_SS && modXYZW)) { regT1 = reg; }
|
||||||
else { SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); } // Flip wzyx to xyzw
|
else { SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); } // Flip wzyx to xyzw
|
||||||
if (sFLAG.doFlag) { XOR32RtoR(sReg, sReg); }
|
|
||||||
//-------------------------Check for Signed flags------------------------------
|
//-------------------------Check for Signed flags------------------------------
|
||||||
|
|
||||||
// The following code makes sure the Signed Bit isn't set with Negative Zero
|
// The following code makes sure the Signed Bit isn't set with Negative Zero
|
||||||
SSE_XORPS_XMM_to_XMM(regT2, regT2); // Clear regT2
|
SSE_XORPS_XMM_to_XMM(regT2, regT2); // Clear regT2
|
||||||
SSE_CMPEQPS_XMM_to_XMM(regT2, regT1); // Set all F's if each vector is zero
|
SSE_CMPEQPS_XMM_to_XMM(regT2, regT1); // Set all F's if each vector is zero
|
||||||
SSE_MOVMSKPS_XMM_to_R32(gprT2, regT2); // Used for Zero Flag Calculation
|
SSE_MOVMSKPS_XMM_to_R32(gprT2, regT2); // Used for Zero Flag Calculation
|
||||||
SSE_ANDNPS_XMM_to_XMM(regT2, regT1);
|
SSE_ANDNPS_XMM_to_XMM(regT2, regT1);
|
||||||
|
|
||||||
SSE_MOVMSKPS_XMM_to_R32(mReg, regT2); // Move the sign bits of the t1reg
|
SSE_MOVMSKPS_XMM_to_R32(mReg, regT2); // Move the sign bits of the t1reg
|
||||||
|
|
||||||
AND32ItoR(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation
|
AND32ItoR(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation
|
||||||
if (sFLAG.doFlag) pjmp = JZ8(0); // Skip if none are
|
if (sFLAG.doSticky||sFLAG.doFlag) pjmp = JZ8(0); // Skip if none are
|
||||||
if (mFLAG.doFlag || sFLAG.doSticky) SHL32ItoR(mReg, 4 + ADD_XYZW);
|
if (mFLAG.doFlag) SHL32ItoR(mReg, 4 + ADD_XYZW);
|
||||||
if (sFLAG.doFlag) OR32ItoR (sReg, 0x82); // SS, S flags
|
if (sFLAG.doSticky) OR32ItoR (gprST, 0x82); // SS, S flags
|
||||||
if (sFLAG.doFlag && _XYZW_SS) pjmp2 = JMP8(0); // If negative and not Zero, we can skip the Zero Flag checking
|
else if (sFLAG.doFlag) OR32ItoR (gprST, 0x02); // S flag
|
||||||
if (sFLAG.doFlag) x86SetJ8(pjmp);
|
if ((sFLAG.doSticky||sFLAG.doFlag) && _XYZW_SS) pjmp2 = JMP8(0); // If negative and not Zero, we can skip the Zero Flag checking
|
||||||
|
if (sFLAG.doSticky||sFLAG.doFlag) x86SetJ8(pjmp);
|
||||||
|
|
||||||
//-------------------------Check for Zero flags------------------------------
|
//-------------------------Check for Zero flags------------------------------
|
||||||
|
|
||||||
AND32ItoR(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation
|
AND32ItoR(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation
|
||||||
if (sFLAG.doFlag) pjmp = JZ8(0); // Skip if none are
|
if (sFLAG.doSticky||sFLAG.doFlag) pjmp = JZ8(0); // Skip if none are
|
||||||
if (mFLAG.doFlag) { SHIFT_XYZW(gprT2); OR32RtoR(mReg, gprT2); }
|
if (mFLAG.doFlag) { SHIFT_XYZW(gprT2); OR32RtoR(mReg, gprT2); }
|
||||||
if (sFLAG.doSticky && !mFLAG.doFlag) { OR32RtoR(mReg, gprT2); }
|
if (sFLAG.doSticky) { OR32ItoR(gprST, 0x41); } // ZS, Z flags
|
||||||
if (sFLAG.doFlag) { OR32ItoR(sReg, 0x41); } // ZS, Z flags
|
else if (sFLAG.doFlag) { OR32ItoR(gprST, 0x01); } // Z flag
|
||||||
if (sFLAG.doFlag) x86SetJ8(pjmp);
|
if (sFLAG.doSticky||sFLAG.doFlag) x86SetJ8(pjmp);
|
||||||
|
|
||||||
//-------------------------Write back flags------------------------------
|
//-------------------------Write back flags------------------------------
|
||||||
|
|
||||||
if (sFLAG.doFlag && _XYZW_SS) x86SetJ8(pjmp2); // If we skipped the Zero Flag Checking, return here
|
if ((sFLAG.doSticky||sFLAG.doFlag) && _XYZW_SS) x86SetJ8(pjmp2); // If we skipped the Zero Flag Checking, return here
|
||||||
|
|
||||||
if (sFLAG.doSticky) OR32RtoR(gprST, mReg); // Set Sticky Register (gprST)
|
if (mFLAG.doFlag) mVUallocMFLAGb(mVU, mReg, mFLAG.write); // Set Mac Flag
|
||||||
if (mFLAG.doFlag) mVUallocMFLAGb(mVU, mReg, mFLAG.write); // Set Mac Flag
|
if (sFLAG.doFlag) mVUallocSFLAGb(mVU, gprST, mFLAG.write); // Set Status Flag
|
||||||
if (sFLAG.doFlag) { // Attach Sticky Register With sReg
|
|
||||||
TEST32ItoR(gprST, 0x0f);
|
|
||||||
pjmp = JZ8(0); // Set Z bit?
|
|
||||||
OR32ItoR(sReg, 0x40);
|
|
||||||
x86SetJ8(pjmp);
|
|
||||||
TEST32ItoR(gprST, 0xf0);
|
|
||||||
pjmp = JZ8(0); // Set S bit?
|
|
||||||
OR32ItoR(sReg, 0x80);
|
|
||||||
x86SetJ8(pjmp);
|
|
||||||
MOV32RtoR(mReg, gprST); // Backup gprST
|
|
||||||
AND32ItoR(mReg, 0xc30000); // Get D/I Bits
|
|
||||||
SHR32ItoR(mReg, 12); // Shift D/I Bits to proper position
|
|
||||||
OR32RtoR (sReg, mReg); // Set D/I Bits
|
|
||||||
mVUallocSFLAGb(mVU, sReg, sFLAG.write); // Set Status Flag
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue