miscellaneous microVU changes...

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@860 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-03-30 01:00:38 +00:00
parent 99b0019d1b
commit e0c3ecbc8f
7 changed files with 46 additions and 58 deletions

View File

@ -89,7 +89,7 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,65,252,10
CONTROL "VU Clip Hack - Fixes missing ground geometry in Persona.",IDC_GAMEFIX4,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,79,238,10
CONTROL "FPU Mul Hack - Special fix for Tales of Destiny (possibly other games).",IDC_GAMEFIX5,
CONTROL "FPU Mul Hack - Special fix for Tales of Destiny.",IDC_GAMEFIX5,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,50,249,10
END

View File

@ -266,13 +266,13 @@ __declspec(naked) void __fastcall endVU0(u32 startPC, u32 cycles) {
}
}
#else
extern "C"
{
extern void __fastcall startVU0(u32 startPC, u32 cycles);
extern void __fastcall startVU1(u32 startPC, u32 cycles);
extern void __fastcall endVU0(u32 startPC, u32 cycles);
extern "C" {
extern void __fastcall startVU0(u32 startPC, u32 cycles);
extern void __fastcall startVU1(u32 startPC, u32 cycles);
extern void __fastcall endVU0(u32 startPC, u32 cycles);
}
#endif
//------------------------------------------------------------------
// Wrapper Functions - Called by other parts of the Emu
//------------------------------------------------------------------

View File

@ -125,7 +125,7 @@ struct microVU {
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[2]; // 2 Instances of I/D flags
u32 divFlag; // 1 instance of I/D flags
/*
uptr x86eax; // Accumulator register. Used in arithmetic operations.

View File

@ -508,10 +508,6 @@ microVUt(void) mVUallocFMAC17a(int& Fs, int& Ft) {
getReg9(Ft, _Ft_);
}
microVUt(void) mVUallocFMAC17b(int& ACC, int& Fs) {
//mVUallocFMAC4b<vuIndex>(ACC, Fs);
}
//------------------------------------------------------------------
// FMAC18 - OPMULA FMAC Opcode
//------------------------------------------------------------------
@ -678,20 +674,10 @@ microVUt(void) mVUallocFMAC26b(int& ACCw, int& ACCr) {
} \
}
microVUt(void) mVUallocSFLAGa(int reg, int fInstance, bool mergeDivFlag) {
microVUt(void) mVUallocSFLAGa(int reg, int fInstance) {
microVU* mVU = mVUx;
getFlagReg(fInstance, fInstance);
MOVZX32R16toR(reg, fInstance);
if (mergeDivFlag) {
if (mVUdivFlag && !mVUdivFlagT) {
AND32ItoR(reg, 0xc00);
if (mVUdivFlag > 1) { OR32ItoR(reg, (u32)((mVUdivFlag << 9) & 0xc00)); }
}
else {
AND32ItoR(reg, 0x30);
OR32MtoR(reg, (uptr)&mVU->divFlag[readQ]);
}
}
}
microVUt(void) mVUallocSFLAGb(int reg, int fInstance) {
@ -722,19 +708,19 @@ microVUt(void) mVUallocCFLAGb(int reg, int fInstance) {
microVU* mVU = mVUx;
MOV32RtoM(mVU->clipFlag[fInstance], reg);
}
/*
microVUt(void) mVUallocDFLAGa(int reg) {
microVU* mVU = mVUx;
if (!mVUdivFlag) { MOV32MtoR(reg, (uptr)&mVU->divFlag[readQ]); AND32ItoR(reg, 0xc00); }
else if (mVUdivFlag & 1) { XOR32RtoR(reg, reg); }
else { MOV32ItoR(reg, (u32)((mVUdivFlag << 9) & 0xc00)); }
//if (!mVUdivFlag) { MOV32MtoR(reg, (uptr)&mVU->divFlag[readQ]); AND32ItoR(reg, 0xc00); }
//else if (mVUdivFlag & 1) { XOR32RtoR(reg, reg); }
//else { MOV32ItoR(reg, (u32)((mVUdivFlag << 9) & 0xc00)); }
}
microVUt(void) mVUallocDFLAGb(int reg) {
microVU* mVU = mVUx;
MOV32RtoM((uptr)&mVU->divFlag[writeQ], reg);
//MOV32RtoM((uptr)&mVU->divFlag[writeQ], reg);
}
*/
//------------------------------------------------------------------
// VI Reg Allocators
//------------------------------------------------------------------

View File

@ -57,6 +57,7 @@ microVUt(void) mVUsetCycles() {
microVUx(void) mVUcompile(u32 startPC, u32 pipelineState, microRegInfo* pState, u8* x86ptrStart) {
microVU* mVU = mVUx;
microBlock block;
int branch;
iPC = startPC / 4;
// Searches for Existing Compiled Block (if found, then returns; else, compile)
@ -65,30 +66,32 @@ microVUx(void) mVUcompile(u32 startPC, u32 pipelineState, microRegInfo* pState,
// First Pass
setCode();
branch = 0;
mVUbranch = 0;
mVUcycles = 1; // Skips "M" phase, and starts counting cycles at "T" stage
for (;;) {
startLoop();
mVUopU<vuIndex, 0>();
if (curI & _Ebit_) { mVUbranch = 5; }
if (curI & _MDTbit_) { mVUbranch = 4; }
if (curI & _Ibit_) { incPC(1); mVUinfo |= _isNOP; }
else { incPC(1); mVUopL<vuIndex, 0>(); }
if (curI & _Ebit_) { branch = 1; }
if (curI & _MDTbit_) { branch = 2; }
if (curI & _Ibit_) { incPC(1); mVUinfo |= _isNOP; }
else { incPC(1); mVUopL<vuIndex, 0>(); }
mVUsetCycles<vuIndex>();
if (mVUbranch == 4) { mVUbranch = 0; mVUinfo |= _isEOB; break; }
else if (mVUbranch == 5) { mVUbranch = 4; }
else if (mVUbranch) { mVUbranch = 4; mVUinfo |= _isBranch; }
if (branch >= 2) { mVUinfo |= _isEOB | ((branch == 3) ? _isBdelay : 0); if (mVUbranch) { Console::Error("microVU Warning: Branch in E-bit/Branch delay slot!"); mVUinfo |= _isNOP; } break; }
else if (branch == 1) { branch = 2; }
if (mVUbranch) { branch = 3; mVUbranch = 0; mVUinfo |= _isBranch; }
incPC(1);
}
// Second Pass
iPC = startPC;
setCode();
for (bool x = 1; x==1; ) {
for (bool x = 1; x; ) {
if (isEOB) { x = 0; }
else if (isBranch) { mVUopU<vuIndex, 1>(); incPC(2); }
mVUopU<vuIndex, 1>();
if (isNop) { incPC(1); }
if (isNop) { if (curI & _Ibit_) { incPC(1); mVU->iReg = curI; } else { incPC(1); } }
else { incPC(1); mVUopL<vuIndex, 1>(); }
if (!isBdelay) { incPC(1); }
else {

View File

@ -32,7 +32,6 @@ microVUf(void) mVU_DIV() {
getReg5(xmmFs, _Fs_, _Fsf_);
getReg5(xmmFt, _Ft_, _Ftf_);
mVUallocDFLAGa<vuIndex>(gprT2); // Get DS/IS flags
// FT can be zero here! so we need to check if its zero and set the correct flag.
SSE_XORPS_XMM_to_XMM(xmmT1, xmmT1); // Clear xmmT1
@ -47,10 +46,10 @@ microVUf(void) mVU_DIV() {
AND32ItoR(gprT1, 1); // Grab "Is Zero" bits from the previous calculation
pjmp = JZ8(0);
OR32ItoR(gprT2, 0x410); // Set invalid flag (0/0)
MOV32ItoM((uptr)&mVU->divFlag, 0x410); // Set invalid flag (0/0)
pjmp1 = JMP8(0);
x86SetJ8(pjmp);
OR32ItoR(gprT2, 0x820); // Zero divide (only when not 0/0)
MOV32ItoM((uptr)&mVU->divFlag, 0x820); // Zero divide (only when not 0/0)
x86SetJ8(pjmp1);
SSE_XORPS_XMM_to_XMM(xmmFs, xmmFt);
@ -60,6 +59,7 @@ microVUf(void) mVU_DIV() {
bjmp32 = JMP32(0);
x86SetJ32(ajmp32);
MOV32ItoM((uptr)&mVU->divFlag, 0); // Clear I/D flags
SSE_DIVSS_XMM_to_XMM(xmmFs, xmmFt);
mVUclamp1<vuIndex>(xmmFs, xmmFt, 8);
@ -67,7 +67,6 @@ microVUf(void) mVU_DIV() {
mVUunpack_xyzw<vuIndex>(xmmFs, xmmFs, 0);
mVUmergeRegs<vuIndex>(xmmPQ, xmmFs, writeQ ? 4 : 8);
mVUallocDFLAGb<vuIndex>(gprT2);
}
}
microVUf(void) mVU_SQRT() {
@ -478,7 +477,7 @@ microVUf(void) mVU_FSAND() {
microVU* mVU = mVUx;
if (!recPass) {}
else {
mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance, !!(_Imm12_ & 0xc30));
mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance);
AND16ItoR(gprT1, _Imm12_);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
@ -487,7 +486,7 @@ microVUf(void) mVU_FSEQ() {
microVU* mVU = mVUx;
if (!recPass) {}
else {
mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance, 1);
mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance);
XOR16ItoR(gprT1, _Imm12_);
SUB16ItoR(gprT1, 1);
SHR16ItoR(gprT1, 15);
@ -498,21 +497,21 @@ microVUf(void) mVU_FSOR() {
microVU* mVU = mVUx;
if (!recPass) {}
else {
mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance, !!((_Imm12_ & 0xc30) == 0xc30));
mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance);
OR16ItoR(gprT1, _Imm12_);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
}
microVUf(void) mVU_FSSET() {
microVU* mVU = mVUx;
if (!recPass) { mVUdivFlagT = 4; }
if (!recPass) {}
else {
int flagReg;
getFlagReg(flagReg, fsInstance);
MOV16ItoR(gprT1, (_Imm12_ & 0xfc0));
if (_Imm12_ & 0xc00) { mVUdivFlag = _Imm12_ >> 9; }
else { mVUdivFlag = 1; }
mVUdivFlagT = 4;
//if (_Imm12_ & 0xc00) { mVUdivFlag = _Imm12_ >> 9; }
//else { mVUdivFlag = 1; }
//mVUdivFlagT = 4;
}
}

View File

@ -22,7 +22,9 @@
// mVUupdateFlags() - Updates status/mac flags
//------------------------------------------------------------------
#define AND_XYZW ((_XYZW_SS && modXYZW) ? (1) : (doMac ? (_X_Y_Z_W) : (flipMask[_X_Y_Z_W])))
#define AND_XYZW ((_XYZW_SS && modXYZW) ? (1) : (doMac ? (_X_Y_Z_W) : (flipMask[_X_Y_Z_W])))
#define ADD_XYZW ((_XYZW_SS && modXYZW) ? (_X ? 3 : (_Y ? 2 : (_Z ? 1 : 0))) : 0)
#define SHIFT_XYZW(gprReg) { if (_XYZW_SS && modXYZW && !_W) { SHL16ItoR(gprReg, ADD_XYZW); } }
// Note: If modXYZW is true, then it adjusts XYZW for Single Scalar operations
microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modXYZW) {
@ -31,14 +33,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
static u8 *pjmp, *pjmp2;
static const int flipMask[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
//SysPrintf ("mVUupdateFlags\n");
if( !(doFlags) ) return;
if (!doFlags) return;
if (!doMac) { 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 (doStatus) {
getFlagReg(sReg, fsInstance); // Set sReg to valid GPR by Cur Flag Instance
mVUallocSFLAGa<vuIndex>(sReg, fpsInstance, 0); // Get Prev Status Flag
mVUallocSFLAGa<vuIndex>(sReg, fpsInstance); // Get Prev Status Flag
AND16ItoR(sReg, 0xff0); // Keep Sticky and D/I flags
}
@ -54,7 +54,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
AND16ItoR(mReg, AND_XYZW ); // Grab "Is Signed" bits from the previous calculation
pjmp = JZ8(0); // Skip if none are
if (doMac) SHL16ItoR(mReg, 4);
if (doMac) SHL16ItoR(mReg, 4 + ADD_XYZW);
if (doStatus) OR16ItoR(sReg, 0x82); // SS, S flags
if (_XYZW_SS) pjmp2 = JMP8(0); // If negative and not Zero, we can skip the Zero Flag checking
x86SetJ8(pjmp);
@ -63,11 +63,11 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
AND16ItoR(gprT2, AND_XYZW ); // Grab "Is Zero" bits from the previous calculation
pjmp = JZ8(0); // Skip if none are
if (doMac) OR32RtoR(mReg, gprT2);
if (doStatus) OR16ItoR(sReg, 0x41); // ZS, Z flags
if (doMac) { SHIFT_XYZW(gprT2); OR32RtoR(mReg, gprT2); }
if (doStatus) { OR16ItoR(sReg, 0x41); } // ZS, Z flags
x86SetJ8(pjmp);
//-------------------------Finally: Send the Flags to the Mac Flag Address------------------------------
//-------------------------Write back flags------------------------------
if (_XYZW_SS) x86SetJ8(pjmp2); // If we skipped the Zero Flag Checking, return here