diff --git a/common/include/Pcsx2Config.h b/common/include/Pcsx2Config.h
index d99f47debe..2da21f9f11 100644
--- a/common/include/Pcsx2Config.h
+++ b/common/include/Pcsx2Config.h
@@ -44,7 +44,8 @@ extern SessionOverrideFlags g_Session;
//////////////////////////////////////////////////////////////////////////
// Pcsx2 User Configuration Options!
-//#define PCSX2_MICROVU // Use Micro VU recs instead of Zero VU Recs
+//#define PCSX2_MICROVU // Use Micro VU recs instead of Zero VU Recs
+//#define PCSX2_MICROVU_ // Fully enable Micro VU recs (temporary option for now)
#define PCSX2_GSMULTITHREAD 1 // uses multi-threaded gs
#define PCSX2_EEREC 0x10
#define PCSX2_VU0REC 0x20
diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
index b013011d39..ba2df10aca 100644
--- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
+++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
@@ -2506,6 +2506,10 @@
RelativePath="..\..\x86\microVU_Compile.inl"
>
+
+
diff --git a/pcsx2/x86/iVU0micro.cpp b/pcsx2/x86/iVU0micro.cpp
index 2dfaac7669..55af7a5c54 100644
--- a/pcsx2/x86/iVU0micro.cpp
+++ b/pcsx2/x86/iVU0micro.cpp
@@ -83,8 +83,10 @@ namespace VU0micro
if((VU0.VI[REG_VPU_STAT].UL & 1) == 0) return;
FreezeXMMRegs(1);
+ FreezeMMXRegs(1);
runVUrec(VU0.VI[REG_TPC].UL & 0xfff, 0xffffffff, 0);
FreezeXMMRegs(0);
+ FreezeMMXRegs(0);
}
}
diff --git a/pcsx2/x86/iVU1micro.cpp b/pcsx2/x86/iVU1micro.cpp
index 87f3099d7b..7debdcfa8e 100644
--- a/pcsx2/x86/iVU1micro.cpp
+++ b/pcsx2/x86/iVU1micro.cpp
@@ -142,8 +142,10 @@ namespace VU1micro
assert( (VU1.VI[REG_TPC].UL&7) == 0 );
FreezeXMMRegs(1);
+ FreezeMMXRegs(0);
runVUrec(VU1.VI[REG_TPC].UL & 0x3fff, 0xffffffff, 1);
FreezeXMMRegs(0);
+ FreezeMMXRegs(0);
}
}
#endif
diff --git a/pcsx2/x86/ix86/ix86_cpudetect.cpp b/pcsx2/x86/ix86/ix86_cpudetect.cpp
index 7e3323e4a7..b1fc04a96e 100644
--- a/pcsx2/x86/ix86/ix86_cpudetect.cpp
+++ b/pcsx2/x86/ix86/ix86_cpudetect.cpp
@@ -398,6 +398,7 @@ void cpudetectInit()
cpudetectSSE3(recSSE);
HostSys::Munmap( recSSE, 0x1000 );
}
+ else { Console::Error("Error: Failed to allocate memory for SSE3 State detection."); }
//////////////////////////////////////
// Core Counting!
diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp
index 0e537472e6..d2aef9b3bd 100644
--- a/pcsx2/x86/microVU.cpp
+++ b/pcsx2/x86/microVU.cpp
@@ -64,7 +64,12 @@ microVUt(void) mVUreset() {
// Dynarec Cache
mVU->cache = SysMmapEx(mVU->cacheAddr, mVU->cacheSize, 0, (vuIndex ? "Micro VU1" : "Micro VU0"));
if ( mVU->cache == NULL ) throw Exception::OutOfMemory(fmt_string( "microVU Error: Failed to allocate recompiler memory! (addr: 0x%x)", params (u32)mVU->cache));
-
+ mVU->ptr = mVU->cache;
+
+ // Setup Entrance/Exit Points
+ mVUdispatcherA();
+ mVUdispatcherB();
+
// Other Variables
memset(&mVU->prog, 0, sizeof(mVU->prog));
mVU->prog.finished = 1;
@@ -99,33 +104,6 @@ microVUt(void) mVUclear(u32 addr, u32 size) {
// that its probably not worth it...
}
-// Executes for number of cycles
-microVUt(void*) __fastcall mVUexecute(u32 startPC, u32 cycles) {
-/*
- Pseudocode: (ToDo: implement # of cycles)
- 1) Search for existing program
- 2) If program not found, goto 5
- 3) Search for recompiled block
- 4) If recompiled block found, goto 6
- 5) Recompile as much blocks as possible
- 6) Return start execution address of block
-*/
- microVU* mVU = mVUx;
- if ( mVUsearchProg(mVU) ) { // Found Program
- //microBlock* block = mVU->prog.prog[mVU->prog.cur].block[startPC]->search(mVU->prog.lastPipelineState);
- //if (block) return block->x86ptrStart; // Found Block
- }
- // Recompile code
- return NULL;
-}
-
-void* __fastcall mVUexecuteVU0(u32 startPC, u32 cycles) {
- return mVUexecute<0>(startPC, cycles);
-}
-void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles) {
- return mVUexecute<1>(startPC, cycles);
-}
-
//------------------------------------------------------------------
// Micro VU - Private Functions
//------------------------------------------------------------------
@@ -206,73 +184,6 @@ __forceinline void mVUinvalidateBlock(microVU* mVU, u32 addr, u32 size) {
}
}
-//------------------------------------------------------------------
-// Dispatcher Functions
-//------------------------------------------------------------------
-
-#ifdef _MSC_VER
-// Runs VU0 for number of cycles
-__declspec(naked) void __fastcall startVU0(u32 startPC, u32 cycles) {
- __asm {
- // __fastcall = The first two DWORD or smaller arguments are passed in ECX and EDX registers; all other arguments are passed right to left.
- call mVUexecuteVU0
-
- /*backup cpu state*/
- push ebx;
- push ebp;
- push esi;
- push edi;
-
- ldmxcsr g_sseVUMXCSR
- /* Should set xmmZ? */
- jmp eax
- }
-}
-
-// Runs VU1 for number of cycles
-__declspec(naked) void __fastcall startVU1(u32 startPC, u32 cycles) {
- __asm {
-
- call mVUexecuteVU1
-
- /*backup cpu state*/
- push ebx;
- push ebp;
- push esi;
- push edi;
-
- ldmxcsr g_sseVUMXCSR
-
- jmp eax
- }
-}
-
-// Exit point
-__declspec(naked) void __fastcall endVU0(u32 startPC, u32 cycles) {
- __asm {
-
- //call mVUcleanUpVU0
-
- /*restore cpu state*/
- pop edi;
- pop esi;
- pop ebp;
- pop ebx;
-
- ldmxcsr g_sseMXCSR
- emms
-
- ret
- }
-}
-#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);
-}
-#endif
-
//------------------------------------------------------------------
// Wrapper Functions - Called by other parts of the Emu
//------------------------------------------------------------------
diff --git a/pcsx2/x86/microVU.h b/pcsx2/x86/microVU.h
index 049520d255..41412f70bf 100644
--- a/pcsx2/x86/microVU.h
+++ b/pcsx2/x86/microVU.h
@@ -125,17 +125,7 @@ struct microVU {
u32 iReg; // iReg (only used in recompilation, not execution)
u32 clipFlag[4]; // 4 instances of clip flag (used in execution)
u32 divFlag; // 1 instance of I/D flags
-
-/*
- uptr x86eax; // Accumulator register. Used in arithmetic operations.
- uptr x86ecx; // Counter register. Used in shift/rotate instructions.
- uptr x86edx; // Data register. Used in arithmetic operations and I/O operations.
- uptr x86ebx; // Base register. Used as a pointer to data (located in DS in segmented mode).
- uptr x86esp; // Stack Pointer register. Pointer to the top of the stack.
- uptr x86ebp; // Stack Base Pointer register. Used to point to the base of the stack.
- uptr x86esi; // Source register. Used as a pointer to a source in stream operations.
- uptr x86edi; // Destination register. Used as a pointer to a destination in stream operations.
-*/
+ u32 VIbackup[2]; // Holds a backup of a VI reg if modified before a branch
};
// microVU rec structs
@@ -146,14 +136,24 @@ extern PCSX2_ALIGNED16(microVU microVU1);
extern void (*mVU_UPPER_OPCODE[64])( VURegs* VU, s32 info );
extern void (*mVU_LOWER_OPCODE[128])( VURegs* VU, s32 info );
+// Main Functions
+microVUt(void) mVUinit(VURegs*);
+microVUt(void) mVUreset();
+microVUt(void) mVUclose();
+microVUt(void) mVUclear(u32, u32);
+
+// Private Functions
__forceinline void mVUclearProg(microVU* mVU, int progIndex);
__forceinline int mVUfindLeastUsedProg(microVU* mVU);
__forceinline int mVUsearchProg(microVU* mVU);
__forceinline void mVUcacheProg(microVU* mVU, int progIndex);
+void* __fastcall mVUexecuteVU0(u32 startPC, u32 cycles);
+void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles);
-#ifdef __LINUX__
-microVUt(void) mVUreset();
-microVUt(void) mVUclose();
+#ifndef __LINUX__
+typedef void (__fastcall *mVUrecCall)(u32, u32);
+#else
+typedef void (*mVUrecCall)(u32, u32) __attribute__((__fastcall)); // Not sure if this is correct syntax (should be close xD)
#endif
// Include all the *.inl files (Needed because C++ sucks with templates and *.cpp files)
@@ -162,3 +162,4 @@ microVUt(void) mVUclose();
#include "microVU_Alloc.inl"
#include "microVU_Tables.inl"
#include "microVU_Compile.inl"
+#include "microVU_Execute.inl"
diff --git a/pcsx2/x86/microVU_Alloc.inl b/pcsx2/x86/microVU_Alloc.inl
index 3316d7360c..dee76e8f92 100644
--- a/pcsx2/x86/microVU_Alloc.inl
+++ b/pcsx2/x86/microVU_Alloc.inl
@@ -708,19 +708,7 @@ 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)); }
-}
-microVUt(void) mVUallocDFLAGb(int reg) {
- microVU* mVU = mVUx;
- //MOV32RtoM((uptr)&mVU->divFlag[writeQ], reg);
-}
-*/
//------------------------------------------------------------------
// VI Reg Allocators
//------------------------------------------------------------------
@@ -734,6 +722,12 @@ microVUt(void) mVUallocVIa(int GPRreg, int _reg_) {
microVUt(void) mVUallocVIb(int GPRreg, int _reg_) {
microVU* mVU = mVUx;
+ if (backupVI) { // Backs up reg to memory (used when VI is modified b4 a branch)
+ MOV32RtoM((uptr)&mVU->VIbackup[1], GPRreg);
+ mVUallocVIa(GPRreg, _reg_);
+ MOV32RtoM((uptr)&mVU->VIbackup[0], GPRreg);
+ MOV32MtoR(GPRreg, (uptr)&mVU->VIbackup[1]);
+ }
if (_reg_ == 0) { return; }
else if (_reg_ < 9) { MOVD32RtoMMX(mmVI(_reg_), GPRreg); }
else { MOV16RtoM((uptr)&mVU->regs->VI[_reg_].UL, GPRreg); }
diff --git a/pcsx2/x86/microVU_Analyze.inl b/pcsx2/x86/microVU_Analyze.inl
index dd5918cdf0..6768153aee 100644
--- a/pcsx2/x86/microVU_Analyze.inl
+++ b/pcsx2/x86/microVU_Analyze.inl
@@ -143,6 +143,32 @@ microVUt(void) mVUanalyzeEFU2(int Fs, u8 xCycles) {
analyzePreg(xCycles);
}
+//------------------------------------------------------------------
+// LQx - LQ/LQD/LQI Opcodes
+//------------------------------------------------------------------
+
+#define analyzeVIreg1(reg) { if (reg) { mVUstall = aMax(mVUstall, mVUregs.VI[reg]); } }
+#define analyzeVIreg2(reg, aCycles) { if (reg) { mVUregsTemp.VIreg = reg; mVUregsTemp.VI = aCycles; mVUinfo |= _writesVI; mVU->VIbackup[0] = reg; } }
+
+microVUt(void) mVUanalyzeLQ(int Ft, int Is, bool writeIs) {
+ microVU* mVU = mVUx;
+ analyzeVIreg1(Is);
+ analyzeReg2(Ft);
+ if (!Ft) { mVUinfo |= (writeIs && Is) ? _noWriteVF : _isNOP; }
+ if (writeIs) { analyzeVIreg2(Is, 1); }
+}
+
+//------------------------------------------------------------------
+// SQx - SQ/SQD/SQI Opcodes
+//------------------------------------------------------------------
+
+microVUt(void) mVUanalyzeSQ(int Fs, int It, bool writeIt) {
+ microVU* mVU = mVUx;
+ analyzeReg1(Fs);
+ analyzeVIreg1(It);
+ if (writeIt) { analyzeVIreg2(It, 1); }
+}
+
//------------------------------------------------------------------
// R*** - R Reg Opcodes
//------------------------------------------------------------------
@@ -166,9 +192,6 @@ microVUt(void) mVUanalyzeR2(int Ft, bool canBeNOP) {
// Sflag - Status Flag Opcodes
//------------------------------------------------------------------
-#define analyzeVIreg1(reg) { if (reg) { mVUstall = aMax(mVUstall, mVUregs.VI[reg]); } }
-#define analyzeVIreg2(reg, aCycles) { if (reg) { mVUregsTemp.VIreg = reg; mVUregsTemp.VI = aCycles; } }
-
microVUt(void) mVUanalyzeSflag(int It) {
microVU* mVU = mVUx;
if (!It) { mVUinfo |= _isNOP; return; }
@@ -190,4 +213,32 @@ microVUt(void) mVUanalyzeXGkick(int Fs, int xCycles) {
analyzeXGkick2(xCycles);
}
+//------------------------------------------------------------------
+// Branches - Branch Opcodes
+//------------------------------------------------------------------
+
+#define analyzeBranchVI(reg, infoVal) { \
+ if (reg && (mVUcycles > 1)) { /* Ensures branch is not first opcode in block */ \
+ incPC(-2); \
+ if (writesVI && (reg == mVU->VIbackup[0])) { /* If prev Op modified VI reg */ \
+ mVUinfo |= _backupVI; \
+ incPC(2); \
+ mVUinfo |= infoVal; \
+ } \
+ else { incPC(2); } \
+ } \
+}
+
+microVUt(void) mVUanalyzeBranch1(int Is) {
+ microVU* mVU = mVUx;
+ if (mVUregs.VI[Is]) { analyzeVIreg1(Is); }
+ else { analyzeBranchVI(Is, _memReadIs); }
+}
+
+microVUt(void) mVUanalyzeBranch2(int Is, int It) {
+ microVU* mVU = mVUx;
+ if (mVUregs.VI[Is] || mVUregs.VI[It]) { analyzeVIreg1(Is); analyzeVIreg1(It); }
+ else { analyzeBranchVI(Is, _memReadIs); analyzeBranchVI(It, _memReadIt);}
+}
+
#endif //PCSX2_MICROVU
diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl
index 554cf2612b..c9a8217641 100644
--- a/pcsx2/x86/microVU_Compile.inl
+++ b/pcsx2/x86/microVU_Compile.inl
@@ -29,11 +29,7 @@
} \
}
-#define curI mVUcurProg.data[iPC]
-#define setCode() { mVU->code = curI; }
-#define startLoop() { mVUdebugStuff1(); mVUstall = 0; memset(&mVUregsTemp, 0, sizeof(mVUregsTemp)); }
-#define incPC(x) { iPC = ((iPC + x) & (mVU->progSize-1)); setCode(); }
-#define incCycles(x) { mVUincCycles(x); }
+#define startLoop() { mVUdebug1(); mVUstall = 0; memset(&mVUregsTemp, 0, sizeof(mVUregsTemp)); }
#define calcCycles(reg, x) { reg = ((reg > x) ? (reg - x) : 0); }
microVUt(void) mVUincCycles(int x) {
@@ -115,10 +111,10 @@ microVUx(void) mVUcompile(u32 startPC, u32 pipelineState, microRegInfo* pState,
if (isEOB) { x = 0; }
else if (isBranch) { mVUopU(); incPC(2); }
- mVUopU();
- if (isNop) { if (curI & _Ibit_) { incPC(1); mVU->iReg = curI; } else { incPC(1); } }
- else { incPC(1); mVUopL(); }
-
+ if (isNop) { mVUopU(); if (curI & _Ibit_) { incPC(1); mVU->iReg = curI; } else { incPC(1); } }
+ else if (!swapOps) { mVUopU(); incPC(1); mVUopL(); }
+ else { incPC(1); mVUopL(); incPC(-1); mVUopU(); incPC(1); }
+
if (!isBdelay) { incPC(1); }
else {
incPC(-2); // Go back to Branch Opcode
diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl
index 5ac22e06e7..18e73ebde7 100644
--- a/pcsx2/x86/microVU_Lower.inl
+++ b/pcsx2/x86/microVU_Lower.inl
@@ -799,7 +799,7 @@ microVUf(void) mVU_ISWR() {
microVUf(void) mVU_LQ() {
microVU* mVU = mVUx;
- if (!recPass) { /*If (!_Ft_) nop();*/ }
+ if (!recPass) { mVUanalyzeLQ(_Ft_, _Fs_, 0); }
else {
if (!_Fs_) {
mVUloadReg(xmmFt, (uptr)mVU->regs->Mem + getVUmem(_Imm11_), _X_Y_Z_W);
@@ -817,9 +817,9 @@ microVUf(void) mVU_LQ() {
microVUf(void) mVU_LQD() {
microVU* mVU = mVUx;
- if (!recPass) {}
+ if (!recPass) { mVUanalyzeLQ(_Ft_, _Fs_, 1); }
else {
- if (!_Fs_ && _Ft_ && !noWriteVF) {
+ if (!_Fs_ && !noWriteVF) {
mVUloadReg(xmmFt, (uptr)mVU->regs->Mem, _X_Y_Z_W);
mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
}
@@ -827,7 +827,7 @@ microVUf(void) mVU_LQD() {
mVUallocVIa(gprT1, _Fs_);
SUB16ItoR(gprT1, 1);
mVUallocVIb(gprT1, _Fs_); // ToDo: Backup to memory check.
- if (_Ft_ && !noWriteVF) {
+ if (!noWriteVF) {
mVUaddrFix(gprT1);
mVUloadReg2(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W);
mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
@@ -838,15 +838,15 @@ microVUf(void) mVU_LQD() {
microVUf(void) mVU_LQI() {
microVU* mVU = mVUx;
- if (!recPass) {}
+ if (!recPass) { mVUanalyzeLQ(_Ft_, _Fs_, 1); }
else {
- if (!_Fs_ && _Ft_ && !noWriteVF) {
+ if (!_Fs_ && !noWriteVF) {
mVUloadReg(xmmFt, (uptr)mVU->regs->Mem, _X_Y_Z_W);
mVUsaveReg(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
}
else {
mVUallocVIa((_Ft_) ? gprT1 : gprT2, _Fs_);
- if (_Ft_ && !noWriteVF) {
+ if (!noWriteVF) {
MOV32RtoR(gprT2, gprT1);
mVUaddrFix(gprT1);
mVUloadReg2(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W);
@@ -864,7 +864,7 @@ microVUf(void) mVU_LQI() {
microVUf(void) mVU_SQ() {
microVU* mVU = mVUx;
- if (!recPass) {}
+ if (!recPass) { mVUanalyzeSQ(_Fs_, _Ft_, 0); }
else {
if (!_Ft_) {
getReg7(xmmFs, _Fs_);
@@ -882,7 +882,7 @@ microVUf(void) mVU_SQ() {
microVUf(void) mVU_SQD() {
microVU* mVU = mVUx;
- if (!recPass) {}
+ if (!recPass) { mVUanalyzeSQ(_Fs_, _Ft_, 1); }
else {
if (!_Ft_) {
getReg7(xmmFs, _Fs_);
@@ -901,7 +901,7 @@ microVUf(void) mVU_SQD() {
microVUf(void) mVU_SQI() {
microVU* mVU = mVUx;
- if (!recPass) {}
+ if (!recPass) { mVUanalyzeSQ(_Fs_, _Ft_, 1); }
else {
if (!_Ft_) {
getReg7(xmmFs, _Fs_);
@@ -1042,8 +1042,10 @@ microVUf(void) mVU_XGKICK() {
if (!recPass) { mVUanalyzeXGkick(_Fs_, 4); }
else {
mVUallocVIa(gprT2, _Fs_); // gprT2 = ECX for __fastcall
+ PUSH32R(gprR); // gprR = EDX is volatile so backup
if (!vuIndex) CALLFunc((uptr)mVU_XGKICK0);
else CALLFunc((uptr)mVU_XGKICK1);
+ POP32R(gprR); // Restore
}
}
@@ -1058,7 +1060,8 @@ microVUf(void) mVU_B() {
microVUf(void) mVU_BAL() {
microVU* mVU = mVUx;
mVUbranch = 1;
- if (recPass) {
+ if (!recPass) { analyzeVIreg2(_Ft_, 1); }
+ else {
MOV32ItoR(gprT1, (xPC + (2 * 8)) & 0xffff);
mVUallocVIb(gprT1, _Ft_);
}
@@ -1066,34 +1069,50 @@ microVUf(void) mVU_BAL() {
microVUf(void) mVU_IBEQ() {
microVU* mVU = mVUx;
mVUbranch = 2;
+ if (!recPass) { mVUanalyzeBranch2(_Fs_, _Ft_); }
+ else {}
}
microVUf(void) mVU_IBGEZ() {
microVU* mVU = mVUx;
mVUbranch = 2;
+ if (!recPass) { mVUanalyzeBranch1(_Fs_); }
+ else {}
}
microVUf(void) mVU_IBGTZ() {
microVU* mVU = mVUx;
mVUbranch = 2;
-}
-microVUf(void) mVU_IBLTZ() {
- microVU* mVU = mVUx;
- mVUbranch = 2;
+ if (!recPass) { mVUanalyzeBranch1(_Fs_); }
+ else {}
}
microVUf(void) mVU_IBLEZ() {
microVU* mVU = mVUx;
mVUbranch = 2;
+ if (!recPass) { mVUanalyzeBranch1(_Fs_); }
+ else {}
+}
+microVUf(void) mVU_IBLTZ() {
+ microVU* mVU = mVUx;
+ mVUbranch = 2;
+ if (!recPass) { mVUanalyzeBranch1(_Fs_); }
+ else {}
}
microVUf(void) mVU_IBNE() {
microVU* mVU = mVUx;
mVUbranch = 2;
+ if (!recPass) { mVUanalyzeBranch2(_Fs_, _Ft_); }
+ else {}
}
microVUf(void) mVU_JR() {
microVU* mVU = mVUx;
mVUbranch = 3;
+ if (!recPass) { mVUanalyzeBranch1(_Fs_); }
+ else {}
}
microVUf(void) mVU_JALR() {
microVU* mVU = mVUx;
mVUbranch = 3;
+ if (!recPass) { mVUanalyzeBranch1(_Fs_); analyzeVIreg2(_Ft_, 1); }
+ else {}
}
#endif //PCSX2_MICROVU
diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h
index dd52f1b489..5a1267a556 100644
--- a/pcsx2/x86/microVU_Misc.h
+++ b/pcsx2/x86/microVU_Misc.h
@@ -144,14 +144,16 @@ declareAllVariables
#define mVUbranch mVUallocInfo.branch
#define mVUcycles mVUallocInfo.cycles
#define mVUstall mVUallocInfo.maxStall
-//#define mVUdivFlag mVUallocInfo.divFlag
-//#define mVUdivFlagT mVUallocInfo.divFlagTimer
#define mVUregs mVUallocInfo.regs
#define mVUregsTemp mVUallocInfo.regsTemp
#define mVUinfo mVUallocInfo.info[mVUallocInfo.curPC / 2]
#define mVUstartPC mVUallocInfo.startPC
#define iPC mVUallocInfo.curPC
#define xPC ((iPC / 2) * 8)
+#define curI mVUcurProg.data[iPC]
+#define setCode() { mVU->code = curI; }
+#define incPC(x) { iPC = ((iPC + x) & (mVU->progSize-1)); setCode(); }
+#define incCycles(x) { mVUincCycles(x); }
#define _isNOP (1<<0) // Skip Lower Instruction
#define _isBranch (1<<1) // Cur Instruction is a Branch
@@ -174,6 +176,11 @@ declareAllVariables
#define _fvsInstance (3<<18)
#define _fvcInstance (3<<20)
#define _noWriteVF (1<<21) // Don't write back the result of a lower op to VF reg if upper op writes to same reg (or if VF = 0)
+#define _backupVI (1<<22) // Backup VI reg to memory if modified before branch (branch uses old VI value unless opcode is ILW or ILWR)
+#define _memReadIs (1<<23) // Read Is (VI reg) from memory (used by branches)
+#define _memReadIt (1<<24) // Read If (VI reg) from memory (used by branches)
+#define _writesVI (1<<25) // Current Instruction writes to VI
+#define _swapOps (1<<26) // Runs Lower Instruction Before Upper Instruction
#define isNOP (mVUinfo & (1<<0))
#define isBranch (mVUinfo & (1<<1))
@@ -196,16 +203,18 @@ declareAllVariables
#define fvsInstance ((mVUinfo >> 18) & 3)
#define fvcInstance ((mVUinfo >> 20) & 3)
#define noWriteVF (mVUinfo & (1<<21))
-
-//#define getFs (mVUinfo & (1<<13))
-//#define getFt (mVUinfo & (1<<14))
-//#define fpmInstance (((u8)((mVUinfo & (3<<10)) >> 10) - 1) & 0x3)
+#define backupVI (mVUinfo & (1<<22))
+#define memReadIs (mVUinfo & (1<<23))
+#define memReadIt (mVUinfo & (1<<24))
+#define writesVI (mVUinfo & (1<<25))
+#define swapOps (mVUinfo & (1<<26))
#define isMMX(_VIreg_) (_VIreg_ >= 1 && _VIreg_ <=9)
#define mmVI(_VIreg_) (_VIreg_ - 1)
#ifdef mVUdebug
-#define mVUdebugStuff1() { \
+#define mVUlog Console::Notice
+#define mVUdebug1() { \
if (curI & _Ibit_) { SysPrintf("microVU: I-bit set!\n"); } \
if (curI & _Ebit_) { SysPrintf("microVU: E-bit set!\n"); } \
if (curI & _Mbit_) { SysPrintf("microVU: M-bit set!\n"); } \
@@ -213,5 +222,11 @@ declareAllVariables
if (curI & _Tbit_) { SysPrintf("microVU: T-bit set!\n"); } \
}
#else
-#define mVUdebugStuff1() {}
+#define mVUlog 0&&
+#define mVUdebug1() {}
#endif
+
+#define mVUcachCheck(x) { \
+ uptr diff = mVU->ptr - mVU->cache; \
+ if (diff > x) { Console::Error("microVU Error: Program went over it's cache limit. Size = %x", params diff); } \
+}