Minor vif/vu changes...

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2654 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2010-03-02 04:36:09 +00:00
parent f8e9b0a5bd
commit 0c8c01494f
8 changed files with 90 additions and 53 deletions

View File

@ -40,14 +40,17 @@ void vu1ResetRegs()
vif1Regs->stat.VEW = false; vif1Regs->stat.VEW = false;
} }
static int count; void vu1Finish() {
while (VU0.VI[REG_VPU_STAT].UL & 0x100) {
void __fastcall vu1ExecMicro(u32 addr)
{
while(VU0.VI[REG_VPU_STAT].UL & 0x100) {
VUM_LOG("vu1ExecMicro > Stalling until current microprogram finishes"); VUM_LOG("vu1ExecMicro > Stalling until current microprogram finishes");
CpuVU1->Execute(vu1RunCycles); CpuVU1->Execute(vu1RunCycles);
} }
}
void __fastcall vu1ExecMicro(u32 addr)
{
static int count = 0;
vu1Finish();
VUM_LOG("vu1ExecMicro %x", addr); VUM_LOG("vu1ExecMicro %x", addr);
VUM_LOG("vu1ExecMicro %x (count=%d)", addr, count++); VUM_LOG("vu1ExecMicro %x (count=%d)", addr, count++);

View File

@ -294,6 +294,7 @@ extern void vu0Finish();
extern void recResetVU0( void ); extern void recResetVU0( void );
// VU1 // VU1
extern void vu1Finish();
extern void vu1ResetRegs(); extern void vu1ResetRegs();
extern void __fastcall vu1ExecMicro(u32 addr); extern void __fastcall vu1ExecMicro(u32 addr);
extern void vu1Exec(VURegs* VU); extern void vu1Exec(VURegs* VU);

View File

@ -19,11 +19,12 @@
#include "VUmicro.h" #include "VUmicro.h"
#include "newVif.h" #include "newVif.h"
__forceinline void vif0FLUSH() // Run VU0 until finish, don't add cycles to EE
// because its vif stalling not the EE core...
__forceinline void vif0FLUSH()
{ {
if (!(VU0.VI[REG_VPU_STAT].UL & 1)) return;
int _cycles = VU0.cycle; int _cycles = VU0.cycle;
// Run VU0 until finish, don't add cycles to EE
// because its vif stalling not the EE core...
vu0Finish(); vu0Finish();
g_vifCycles += (VU0.cycle - _cycles) * BIAS; g_vifCycles += (VU0.cycle - _cycles) * BIAS;
} }

View File

@ -21,17 +21,12 @@
#include "VUmicro.h" #include "VUmicro.h"
#include "newVif.h" #include "newVif.h"
__forceinline void vif1FLUSH() __forceinline void vif1FLUSH()
{ {
if (VU0.VI[REG_VPU_STAT].UL & 0x100) if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) return;
{ int _cycles = VU1.cycle;
int _cycles = VU1.cycle; vu1Finish();
g_vifCycles += (VU1.cycle - _cycles) * BIAS;
do { CpuVU1->Execute(vu1RunCycles); }
while (VU0.VI[REG_VPU_STAT].UL & 0x100);
g_vifCycles += (VU1.cycle - _cycles) * BIAS;
}
} }
void vif1TransferFromMemory() void vif1TransferFromMemory()

View File

@ -184,8 +184,7 @@ _mVUt _f void mVUclearProg(int progIndex) {
microProgram& program = mVU->prog.prog[progIndex]; microProgram& program = mVU->prog.prog[progIndex];
program.used = 0; program.used = 0;
program.isDead = 1; program.age = isDead;
program.isOld = 1;
program.frame = mVU->prog.curFrame; program.frame = mVU->prog.curFrame;
for (int j = 0; j <= program.ranges.max; j++) { for (int j = 0; j <= program.ranges.max; j++) {
program.ranges.range[j][0] = -1; // Set range to program.ranges.range[j][0] = -1; // Set range to
@ -209,7 +208,7 @@ _mVUt _f void mVUcacheProg(int progIndex) {
_f void mVUsortProg(mV, int progIndex) { _f void mVUsortProg(mV, int progIndex) {
int* temp = new int[mVU->prog.max+1]; int* temp = new int[mVU->prog.max+1];
int offset = 0; int offset = 0;
for (int i = 0; i <= (mVU->prog.max-1); i++) { for (int i = 0; i <=(mVU->prog.max-1); i++) {
if (progIndex == mVU->prog.progList[i]) offset = 1; if (progIndex == mVU->prog.progList[i]) offset = 1;
temp[i+1] = mVU->prog.progList[i+offset]; temp[i+1] = mVU->prog.progList[i+offset];
} }
@ -223,14 +222,13 @@ _mVUt _f int mVUfindLeastUsedProg() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
for (int i = 0; i <= mVU->prog.max; i++) { for (int i = 0; i <= mVU->prog.max; i++) {
if (mVU->prog.prog[i].isDead) { if (mVU->prog.prog[i].age == isDead) {
mVU->prog.total++; mVU->prog.total++;
mVUcacheProg<vuIndex>(i); // Cache Micro Program mVUcacheProg<vuIndex>(i); // Cache Micro Program
mVU->prog.prog[i].isDead = 0; mVU->prog.prog[i].age = isYoung;
mVU->prog.prog[i].isOld = 0; mVU->prog.prog[i].used = 1;
mVU->prog.prog[i].used = 1;
mVUsortProg(mVU, i); mVUsortProg(mVU, i);
Console.WriteLn( Color_Orange, "microVU%d: Cached MicroPrograms = [%03d] [%03d]", vuIndex, i+1, mVU->prog.total+1); Console.WriteLn(Color_Orange, "microVU%d: Cached MicroPrograms = [%03d] [%03d]", vuIndex, i+1, mVU->prog.total+1);
return i; return i;
} }
} }
@ -243,31 +241,32 @@ _mVUt _f int mVUfindLeastUsedProg() {
} }
mVU->prog.total -= ((mVU->prog.max+1)/4)-1; mVU->prog.total -= ((mVU->prog.max+1)/4)-1;
mVUcacheProg<vuIndex>(pIdx); // Cache Micro Program mVUcacheProg<vuIndex>(pIdx); // Cache Micro Program
mVU->prog.prog[pIdx].isDead = 0; mVU->prog.prog[pIdx].age = isYoung;
mVU->prog.prog[pIdx].isOld = 0; mVU->prog.prog[pIdx].used = 1;
mVU->prog.prog[pIdx].used = 1;
mVUsortProg(mVU, pIdx); mVUsortProg(mVU, pIdx);
Console.WriteLn( Color_Orange, "microVU%d: Cached MicroPrograms = [%03d] [%03d]", vuIndex, pIdx+1, mVU->prog.total+1); Console.WriteLn(Color_Orange, "microVU%d: Cached MicroPrograms = [%03d] [%03d]", vuIndex, pIdx+1, mVU->prog.total+1);
return pIdx; return pIdx;
} }
// Finds and Ages/Kills Programs if they haven't been used in a while. // Finds and Ages/Kills Programs if they haven't been used in a while.
_f void mVUvsyncUpdate(mV) { _f void mVUvsyncUpdate(mV) {
for (int i = 0; i <= mVU->prog.max; i++) { for (int i = 0; i <= mVU->prog.max; i++) {
if (mVU->prog.prog[i].isDead) continue; if (mVU->prog.prog[i].age == isDead) continue;
if (mVU->prog.prog[i].used) { if (mVU->prog.prog[i].used) {
mVU->prog.prog[i].used = 0; mVU->prog.prog[i].used = 0;
mVU->prog.prog[i].frame = mVU->prog.curFrame; mVU->prog.prog[i].frame = mVU->prog.curFrame;
} }
else if (((mVU->prog.curFrame - mVU->prog.prog[i].frame) >= (360 * 10)) && (i != mVU->prog.cur)) { else { // Age Micro Program that wasn't used
mVU->prog.total--; s32 diff = mVU->prog.curFrame - mVU->prog.prog[i].frame;
if (!mVU->index) mVUclearProg<0>(i); if (diff >= (360 * 10)) {
else mVUclearProg<1>(i); if (i == mVU->prog.cur) continue; // Don't Age/Kill last used program
DevCon.WriteLn("microVU%d: Killing Dead Program [%03d]", mVU->index, i+1); mVU->prog.total--;
} if (!mVU->index) mVUclearProg<0>(i);
else if (((mVU->prog.curFrame - mVU->prog.prog[i].frame) >= (30 * 1)) && !mVU->prog.prog[i].isOld) { else mVUclearProg<1>(i);
mVU->prog.prog[i].isOld = 1; DevCon.WriteLn("microVU%d: Killing Dead Program [%03d]", mVU->index, i+1);
//DevCon.Status("microVU%d: Aging Old Program [%03d]", mVU->index, i+1); }
elif(diff >= (60 * 1)) { mVU->prog.prog[i].age = isOld; }
elif(diff >= (20 * 1)) { mVU->prog.prog[i].age = isAged; }
} }
} }
mVU->prog.curFrame++; mVU->prog.curFrame++;
@ -286,16 +285,16 @@ _mVUt _f bool mVUcmpPartial(int progIndex) {
} }
// Compare Cached microProgram to mVU->regs->Micro // Compare Cached microProgram to mVU->regs->Micro
_mVUt _f bool mVUcmpProg(int progIndex, const bool checkOld, const bool cmpWholeProg) { _mVUt _f bool mVUcmpProg(int progIndex, const int checkAge, const bool cmpWholeProg) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!mVUprogI.isDead && (checkOld == mVUprogI.isOld)) { if (checkAge == mVUprogI.age) {
if ((cmpWholeProg && !memcmp_mmx((u8*)mVUprogI.data, mVU->regs->Micro, mVU->microMemSize)) if ((cmpWholeProg && !memcmp_mmx((u8*)mVUprogI.data, mVU->regs->Micro, mVU->microMemSize))
|| (!cmpWholeProg && mVUcmpPartial<vuIndex>(progIndex))) { || (!cmpWholeProg && mVUcmpPartial<vuIndex>(progIndex))) {
mVU->prog.cur = progIndex; mVU->prog.cur = progIndex;
mVU->prog.cleared = 0; mVU->prog.cleared = 0;
mVU->prog.isSame = cmpWholeProg ? 1 : -1; mVU->prog.isSame = cmpWholeProg ? 1 : -1;
mVU->prog.prog[progIndex].used = 1; mVU->prog.prog[progIndex].used = 1;
mVU->prog.prog[progIndex].isOld = 0; mVU->prog.prog[progIndex].age = isYoung;
return 1; return 1;
} }
} }
@ -311,7 +310,11 @@ _mVUt _f int mVUsearchProg() {
return 1; // Check Young Programs return 1; // Check Young Programs
} }
for (int i = mVU->prog.max; i >= 0; i--) { for (int i = mVU->prog.max; i >= 0; i--) {
if (mVUcmpProg<vuIndex>(mVU->prog.progList[i], 1, 0)) if (mVUcmpProg<vuIndex>(mVU->prog.progList[i], 1, 0))
return 1; // Check Aged Programs
}
for (int i = mVU->prog.max; i >= 0; i--) {
if (mVUcmpProg<vuIndex>(mVU->prog.progList[i], 2, 0))
return 1; // Check Old Programs return 1; // Check Old Programs
} }
mVU->prog.cur = mVUfindLeastUsedProg<vuIndex>(); // If cleared and program not found, make a new program instance mVU->prog.cur = mVUfindLeastUsedProg<vuIndex>(); // If cleared and program not found, make a new program instance
@ -319,8 +322,8 @@ _mVUt _f int mVUsearchProg() {
mVU->prog.isSame = 1; mVU->prog.isSame = 1;
return 0; return 0;
} }
mVU->prog.prog[mVU->prog.cur].used = 1; mVU->prog.prog[mVU->prog.cur].used = 1;
mVU->prog.prog[mVU->prog.cur].isOld = 0; mVU->prog.prog[mVU->prog.cur].age = isYoung;
return 1; // If !cleared, then we're still on the same program as last-time ;) return 1; // If !cleared, then we're still on the same program as last-time ;)
} }

View File

@ -111,6 +111,13 @@ struct microRange {
s32 range[mMaxRanges][2]; s32 range[mMaxRanges][2];
}; };
enum microProgramAge {
isYoung = 0,
isAged = 1,
isOld = 2,
isDead = 3
};
#define mProgSize (0x4000/4) #define mProgSize (0x4000/4)
struct microProgram { struct microProgram {
u32 data [mProgSize]; // Holds a copy of the VU microProgram u32 data [mProgSize]; // Holds a copy of the VU microProgram
@ -118,8 +125,7 @@ struct microProgram {
microRange ranges; // The ranges of the microProgram that have already been recompiled microRange ranges; // The ranges of the microProgram that have already been recompiled
u32 frame; // Frame # the program was last used on u32 frame; // Frame # the program was last used on
u32 used; // Program was used this frame? u32 used; // Program was used this frame?
bool isDead; // Program is Dead? int age; // Program age... Young, Aged, Old, or Dead...
bool isOld; // Program is Old? (Program hasn't been used in a while)
}; };
#define mMaxProg ((mVU->index)?400:8) // The amount of Micro Programs Recs will 'remember' #define mMaxProg ((mVU->index)?400:8) // The amount of Micro Programs Recs will 'remember'

View File

@ -31,9 +31,36 @@
// Helper Functions // Helper Functions
//------------------------------------------------------------------ //------------------------------------------------------------------
// Used by checkIfSibling below...
bool cmpSibling(mV, int progIndex) {
if (mVUprogI.age == isDead) return 0;
for (int i = 0; i <= mVUprogI.ranges.total; i++) {
if ((mVUprogI.ranges.range[i][0] < 0)
|| (mVUprogI.ranges.range[i][1] < 0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU->index, i, mVUprogI.ranges.total); }
if (memcmp_mmx(cmpOffset(mVUprogI.data), cmpOffset(mVU->regs->Micro), ((mVUprogI.ranges.range[i][1] + 8) - mVUprogI.ranges.range[i][0]))) {
return 0;
}
}
return 1;
}
// Since we use partial-program comparisons to search cached microPrograms,
// it is possible that another cached microProgram we have also would've
// passed the comparison check. This function checks how often this happens...
_f void checkIfSibling(mV) {
if (mVU->prog.isSame != -1) return;
for (int i = mVU->prog.max; i >= 0; i--) {
if (i != mVU->prog.cur && cmpSibling(mVU, i)) {
if (mVU->prog.prog[i].block[iPC/2] != NULL) {
DevCon.WriteLn("mVU: microProgram Sibling Detected! [%d][%d]", mVU->prog.cur, i);
}
}
}
}
// Used by mVUsetupRange // Used by mVUsetupRange
_f void mVUcheckIsSame(mV) { _f void mVUcheckIsSame(mV) {
if (0) checkIfSibling(mVU);
if (mVU->prog.isSame == -1) { if (mVU->prog.isSame == -1) {
mVU->prog.isSame = !memcmp_mmx((u8*)mVUcurProg.data, mVU->regs->Micro, mVU->microMemSize); mVU->prog.isSame = !memcmp_mmx((u8*)mVUcurProg.data, mVU->regs->Micro, mVU->microMemSize);
} }
@ -65,7 +92,7 @@ _f void mVUsetupRange(mV, s32 pc, bool isStartPC) {
mVUcurProg.ranges.total = 0; mVUcurProg.ranges.total = 0;
mVUrange[0] = 0; mVUrange[0] = 0;
mVUrange[1] = mVU->microMemSize - 8; mVUrange[1] = mVU->microMemSize - 8;
DevCon.WriteLn( Color_StrongBlack, "microVU%d: Prog Range List Full", mVU->index); DevCon.Warning("microVU%d: Prog Range List Full", mVU->index);
} }
} }
else { else {
@ -100,7 +127,7 @@ _f void mVUsetupRange(mV, s32 pc, bool isStartPC) {
mVUcurProg.ranges.total = 0; mVUcurProg.ranges.total = 0;
mVUrange[0] = 0; mVUrange[0] = 0;
mVUrange[1] = mVU->microMemSize - 8; mVUrange[1] = mVU->microMemSize - 8;
DevCon.WriteLn( Color_StrongBlack, "microVU%d: Prog Range List Full", mVU->index); DevCon.Warning("microVU%d: Prog Range List Full", mVU->index);
} }
} }
} }

View File

@ -196,6 +196,7 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
#define shuffleSS(x) ((x==1)?(0x27):((x==2)?(0xc6):((x==4)?(0xe1):(0xe4)))) #define shuffleSS(x) ((x==1)?(0x27):((x==2)?(0xc6):((x==4)?(0xe1):(0xe4))))
#define _1mb (0x100000) #define _1mb (0x100000)
#define clampE CHECK_VU_EXTRA_OVERFLOW #define clampE CHECK_VU_EXTRA_OVERFLOW
#define elif else if
// Flag Info // Flag Info
#define __Status (mVUregs.needExactMatch & 1) #define __Status (mVUregs.needExactMatch & 1)