- fixed the 5 warnings in hacksDlg.cpp

microVU:
- major changes to microprogram logging. logs are now in html format with color-coding, hyperlinks to branch addresses, horizontal rules separating blocks, etc...
- made mmx reg usage for VI regs toggable (off by default now)
- minor changes

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1071 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-04-27 10:00:58 +00:00
parent 13cda40ec8
commit 5183f1eb63
11 changed files with 101 additions and 64 deletions

View File

@ -86,11 +86,11 @@ BOOL APIENTRY HacksProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
}
}
newhacks.IOPCycleDouble = IsDlgButtonChecked(hDlg, IDC_IOPSYNC);
newhacks.WaitCycleExt = IsDlgButtonChecked(hDlg, IDC_WAITCYCLES);
newhacks.INTCSTATSlow = IsDlgButtonChecked(hDlg, IDC_INTCSTATHACK);
newhacks.ESCExits = IsDlgButtonChecked(hDlg, IDC_ESCHACK);
newhacks.IdleLoopFF = IsDlgButtonChecked(hDlg, IDC_IDLELOOPFF);
newhacks.IOPCycleDouble = !!IsDlgButtonChecked(hDlg, IDC_IOPSYNC);
newhacks.WaitCycleExt = !!IsDlgButtonChecked(hDlg, IDC_WAITCYCLES);
newhacks.INTCSTATSlow = !!IsDlgButtonChecked(hDlg, IDC_INTCSTATHACK);
newhacks.ESCExits = !!IsDlgButtonChecked(hDlg, IDC_ESCHACK);
newhacks.IdleLoopFF = !!IsDlgButtonChecked(hDlg, IDC_IDLELOOPFF);
newhacks.VUCycleSteal = SendDlgItemMessage(hDlg, IDC_VUCYCLE, TBM_GETPOS, 0, 0);
CheckVUCycleHack(hDlg, newhacks.VUCycleSteal);

View File

@ -118,7 +118,7 @@ union VURecRegs
u32 id;
};
#define SUPERVU_XGKICKDELAY 1 // yes this is needed as default (wipeout)
#define SUPERVU_XGKICKDELAY 0 // yes this is needed as default (wipeout)
class VuBaseBlock;

View File

@ -28,7 +28,6 @@
PCSX2_ALIGNED16(microVU microVU0);
PCSX2_ALIGNED16(microVU microVU1);
FILE *mVUlogFile[2] = {NULL, NULL};
declareAllVariables // Declares All Global Variables :D
//------------------------------------------------------------------
@ -46,7 +45,6 @@ microVUt(void) mVUinit(VURegs* vuRegsPtr) {
mVU->cache = NULL;
memset(&mVU->prog, 0, sizeof(mVU->prog));
mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init");
mVUsetupLog();
mVUreset<vuIndex>();
}
@ -151,7 +149,7 @@ microVUt(int) mVUfindLeastUsedProg() {
if (mVU->prog.total < mVU->prog.max) {
mVU->prog.total++;
mVUcacheProg<vuIndex>(mVU->prog.total); // Cache Micro Program
Console::Notice("microVU: Program Total = %d", params mVU->prog.total);
Console::Notice("microVU%d: Cached MicroPrograms = %d", params vuIndex, mVU->prog.total+1);
return mVU->prog.total;
}
else {
@ -165,7 +163,7 @@ microVUt(int) mVUfindLeastUsedProg() {
}
mVUclearProg<vuIndex>(j); // Clear old data if overwriting old program
mVUcacheProg<vuIndex>(j); // Cache Micro Program
Console::Notice("microVU: Program Cache got Full!");
Console::Notice("microVU%d: MicroProgram Cache Full!", params vuIndex);
return j;
}
}
@ -175,9 +173,7 @@ microVUt(int) mVUsearchProg() {
microVU* mVU = mVUx;
if (mVU->prog.cleared) { // If cleared, we need to search for new program
for (int i = 0; i <= mVU->prog.total; i++) {
//if (i == mVU->prog.cur) continue; // We can skip the current program. (ToDo: Verify that games don't clear, and send the same microprogram :/)
if (!memcmp_mmx(mVU->prog.prog[i].data, mVU->regs->Micro, mVU->microSize)) {
//if (i == mVU->prog.cur) { mVUprint("microVU: Same micro program sent!"); }
mVU->prog.cur = i;
mVU->prog.cleared = 0;
mVU->prog.prog[i].used++;

View File

@ -93,7 +93,8 @@ struct microVU {
static const u32 cacheSize = 0x800000; // VU Cache Size
microProgManager<0x4000> prog; // Micro Program Data
FILE* logFile; // Log File Pointer
VURegs* regs; // VU Regs Struct
u8* cache; // Dynarec Cache Start (where we will start writing the recompiled code to)
u8* startFunct; // Ptr Function to the Start code for recompiled programs
@ -109,6 +110,8 @@ struct microVU {
u32 espBackup; // Temp Backup for ESP
u32 totalCycles;
u32 cycles;
PCSX2_ALIGNED16(u32 xmmPQb[4]); // Backup for xmmPQ
};
// microVU rec structs
@ -119,9 +122,6 @@ 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 );
// Used for logging microPrograms
extern FILE *mVUlogFile[2];
// Main Functions
microVUt(void) mVUinit(VURegs*);
microVUt(void) mVUreset();

View File

@ -714,9 +714,9 @@ microVUt(void) mVUallocCFLAGb(int reg, int fInstance) {
microVUt(void) mVUallocVIa(int GPRreg, int _reg_) {
microVU* mVU = mVUx;
if (_reg_ == 0) { XOR32RtoR(GPRreg, GPRreg); }
else if (_reg_ < 9) { MOVD32MMXtoR(GPRreg, mmVI(_reg_)); }
else { MOVZX32M16toR(GPRreg, (uptr)&mVU->regs->VI[_reg_].UL); }
if (!_reg_ || _reg_>15) { XOR32RtoR(GPRreg, GPRreg); }
else if (isMMX(_reg_)) { MOVD32MMXtoR(GPRreg, mmVI(_reg_)); }
else { MOVZX32M16toR(GPRreg, (uptr)&mVU->regs->VI[_reg_].UL); }
}
microVUt(void) mVUallocVIb(int GPRreg, int _reg_) {
@ -727,9 +727,9 @@ microVUt(void) mVUallocVIb(int GPRreg, int _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 if (_reg_ < 16) { MOV16RtoM((uptr)&mVU->regs->VI[_reg_].UL, GPRreg); }
if (_reg_ == 0) { return; }
else if (isMMX(_reg_)) { MOVD32RtoMMX(mmVI(_reg_), GPRreg); }
else if (_reg_ < 16) { MOV16RtoM((uptr)&mVU->regs->VI[_reg_].UL, GPRreg); }
}
//------------------------------------------------------------------

View File

@ -359,14 +359,14 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
memcpy_fast(&pBlock->pStateEnd, &mVUregs, sizeof(microRegInfo));
mVUsetupBranch<vuIndex>(bStatus, bMac);
PUSH32R(gprR); // Backup EDX
mVUbackupRegs<vuIndex>();
MOV32MtoR(gprT2, (uptr)&mVU->branch); // Get startPC (ECX first argument for __fastcall)
//AND32ItoR(gprT2, (vuIndex)?0x3ff8:0xff8); // Ensure valid jump address
MOV32ItoR(gprR, (u32)&pBlock->pStateEnd); // Get pState (EDX second argument for __fastcall)
if (!vuIndex) CALLFunc((uptr)mVUcompileVU0); //(u32 startPC, uptr pState)
else CALLFunc((uptr)mVUcompileVU1);
POP32R(gprR); // Restore EDX
mVUrestoreRegs<vuIndex>();
JMPR(gprT1); // Jump to rec-code address
return thisPtr;
}

View File

@ -56,8 +56,8 @@ microVUt(void) mVUdispatcherA() {
MOV32RtoR(gprF2, gprF0);
MOV32RtoR(gprF3, gprF0);
for (int i = 0; i < 8; i++) {
MOVQMtoR(i, (uptr)&mVU->regs->VI[i+1].UL);
for (int i = 1; i < 16; i++) {
if (isMMX(i)) { MOVQMtoR(mmVI(i), (uptr)&mVU->regs->VI[i].UL); }
}
SSE_MOVAPS_M128_to_XMM(xmmACC, (uptr)&mVU->regs->ACC.UL[0]);
@ -99,7 +99,10 @@ microVUt(void) mVUdispatcherB() {
MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprF0);
for (int i = 0; i < 8; i++) {
MOVDMMXtoM((uptr)&mVU->regs->VI[i+1].UL, i);
}
for (int i = 1; i < 16; i++) {
if (isMMX(i)) { MOVDMMXtoM((uptr)&mVU->regs->VI[i].UL, mmVI(i)); }
}
SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->ACC.UL[0], xmmACC);
@ -112,7 +115,7 @@ microVUt(void) mVUdispatcherB() {
//write8(0xcc);
EMMS();
if (isMMX(1)) EMMS();
RET();
mVUcacheCheck(x86Ptr, mVU->cache, 512);

View File

@ -19,13 +19,9 @@
#pragma once
#ifdef PCSX2_MICROVU
microVUt(void) __mVUsetupLog() {
if (!vuIndex) { if (!mVUlogFile[0]) mVUlogFile[0] = fopen(LOGS_DIR "\\microVU0.txt", "w"); }
else { if (!mVUlogFile[1]) mVUlogFile[1] = fopen(LOGS_DIR "\\microVU1.txt", "w"); }
}
// writes text directly to the microVU.txt, no newlines appended.
microVUx(void) __mVULog(const char* fmt, ...) {
microVU* mVU = mVUx;
char tmp[2024];
va_list list;
@ -35,10 +31,9 @@ microVUx(void) __mVULog(const char* fmt, ...) {
int length = vsprintf(tmp, fmt, list);
va_end(list);
if (mVUlogFile[vuIndex]) {
fputs(tmp, mVUlogFile[vuIndex]);
//fputs("\n", mVUlogFile[vuIndex]);
fflush(mVUlogFile[vuIndex]);
if (mVU->logFile) {
fputs(tmp, mVU->logFile);
fflush(mVU->logFile);
}
}
@ -46,15 +41,30 @@ microVUx(void) __mVULog(const char* fmt, ...) {
microVUt(void) __mVUdumpProgram(int progIndex) {
microVU* mVU = mVUx;
bool bitX[7];
bool bitX[9];
char str[30];
int delay = 0;
mVUbranch = 0;
sprintf(str, "%s\\microVU%d prog - %02d.html", LOGS_DIR, vuIndex, progIndex);
mVU->logFile = fopen(str, "w");
mVUlog("<html>\n");
mVUlog("<title>microVU%d MicroProgram Log</title>\n", vuIndex);
mVUlog("<body bgcolor=\"#000000\" LINK=\"#1111ff\" VLINK=\"#1111ff\">\n");
mVUlog("<font face=\"Courier New\" color=\"#ffffff\">\n");
mVUlog("<font size=\"5\" color=\"#7099ff\">");
mVUlog("*********************\n<br>", progIndex);
mVUlog("* Micro-Program #%02d *\n<br>", progIndex);
mVUlog("*********************\n\n<br><br>", progIndex);
mVUlog("</font>");
mVUlog("*********************\n", progIndex);
mVUlog("* Micro-Program #%02d *\n", progIndex);
mVUlog("*********************\n\n", progIndex);
for (u32 i = 0; i < mVU->progSize; i+=2) {
if (delay) { delay--; mVUlog("</font>"); if (!delay) mVUlog("<hr/>"); }
if (mVUbranch) { delay = 1; mVUbranch = 0; }
mVU->code = mVU->prog.prog[progIndex].data[i+1];
mVUlog("[%04x] (%08x) ", i*4, mVU->code);
bitX[0] = 0;
bitX[1] = 0;
@ -63,14 +73,21 @@ microVUt(void) __mVUdumpProgram(int progIndex) {
bitX[4] = 0;
bitX[5] = 0;
bitX[6] = 0;
bitX[7] = 0;
bitX[8] = 0;
if (mVU->code & _Ibit_) {bitX[0] = 1; bitX[5] = 1;}
if (mVU->code & _Ebit_) {bitX[1] = 1; bitX[5] = 1;}
if (mVU->code & _Mbit_) {bitX[2] = 1; bitX[5] = 1;}
if (mVU->code & _Dbit_) {bitX[3] = 1; bitX[5] = 1;}
if (mVU->code & _Tbit_) {bitX[4] = 1; bitX[5] = 1;}
if (mVU->code & _Ibit_) { bitX[0] = 1; bitX[5] = 1; bitX[7] = 1; }
if (mVU->code & _Ebit_) { bitX[1] = 1; bitX[5] = 1; delay = 2; }
if (mVU->code & _Mbit_) { bitX[2] = 1; bitX[5] = 1; }
if (mVU->code & _Dbit_) { bitX[3] = 1; bitX[5] = 1; }
if (mVU->code & _Tbit_) { bitX[4] = 1; bitX[5] = 1; }
if (delay == 2) { mVUlog("<font color=\"#FFFF00\">"); }
if (delay == 1) { mVUlog("<font color=\"#999999\">"); }
iPC = (i+1)/4;
mVUlog("<a name=\"addr%04x\">", i*4);
mVUlog("[%04x] (%08x)</a> ", i*4, mVU->code);
mVUopU<vuIndex, 2>();
if (bitX[5]) {
@ -84,11 +101,17 @@ microVUt(void) __mVUdumpProgram(int progIndex) {
}
iPC = i/4;
if (bitX[7]) { mVUlog("<font color=\"#0070ff\">"); }
mVU->code = mVU->prog.prog[progIndex].data[i];
mVUlog("\n[%04x] (%08x) ", i*4, mVU->code);
mVUlog("<br>\n[%04x] (%08x) ", i*4, mVU->code);
mVUopL<vuIndex, 2>();
mVUlog("\n\n");
mVUlog("\n\n<br><br>");
if (bitX[7]) { mVUlog("</font>"); }
}
mVUlog("</font>\n");
mVUlog("</body>\n");
mVUlog("</html>\n");
fclose(mVU->logFile);
}
#endif //PCSX2_MICROVU

View File

@ -752,8 +752,7 @@ microVUf(void) mVU_ILW() {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
ADD32ItoR(gprT1, _Imm11_);
mVUaddrFix<vuIndex>(gprT1);
MOV32RmtoR(gprT1, gprT1, (uptr)mVU->regs->Mem + offsetSS);
if (isMMX(_Ft_)) AND32ItoR(gprT1, 0xffff);
MOVZX32Rm16toR(gprT1, gprT1, (uptr)mVU->regs->Mem + offsetSS);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
}
@ -1098,10 +1097,10 @@ microVUf(void) mVU_XGKICK() {
pass2 {
mVUprint("XGkick");
mVUallocVIa<vuIndex>(gprT2, _Fs_); // gprT2 = ECX for __fastcall
PUSH32R(gprR); // gprR = EDX is volatile so backup
mVUbackupRegs<vuIndex>();
if (mtgsThread != NULL) CALLFunc((uptr)mVU_XGKICK_);
else CALLFunc((uptr)mVU_XGKICK__);
POP32R(gprR); // Restore
mVUrestoreRegs<vuIndex>();
}
pass3 { mVUlog("XGKICK vi%02d", _Fs_); }
}
@ -1113,7 +1112,7 @@ microVUf(void) mVU_XGKICK() {
microVUf(void) mVU_B() {
microVU* mVU = mVUx;
mVUbranch = 1;
pass3 { mVUlog("B [%04x]", branchAddr); }
pass3 { mVUlog("B [<a href=\"#addr%04x\">%04x</a>]", branchAddr, branchAddr); }
}
microVUf(void) mVU_BAL() {
microVU* mVU = mVUx;
@ -1123,7 +1122,7 @@ microVUf(void) mVU_BAL() {
MOV32ItoR(gprT1, bSaveAddr);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("BAL vi%02d [%04x]", _Ft_, branchAddr); }
pass3 { mVUlog("BAL vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Ft_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBEQ() {
microVU* mVU = mVUx;
@ -1136,7 +1135,7 @@ microVUf(void) mVU_IBEQ() {
else { mVUallocVIa<vuIndex>(gprT2, _Ft_); XOR32RtoR(gprT1, gprT2); }
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBEQ vi%02d, vi%02d [%04x]", _Ft_, _Fs_, branchAddr); }
pass3 { mVUlog("IBEQ vi%02d, vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Ft_, _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBGEZ() {
microVU* mVU = mVUx;
@ -1147,7 +1146,7 @@ microVUf(void) mVU_IBGEZ() {
else mVUallocVIa<vuIndex>(gprT1, _Fs_);
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBGEZ vi%02d [%04x]", _Fs_, branchAddr); }
pass3 { mVUlog("IBGEZ vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBGTZ() {
microVU* mVU = mVUx;
@ -1158,7 +1157,7 @@ microVUf(void) mVU_IBGTZ() {
else mVUallocVIa<vuIndex>(gprT1, _Fs_);
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBGTZ vi%02d [%04x]", _Fs_, branchAddr); }
pass3 { mVUlog("IBGTZ vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBLEZ() {
microVU* mVU = mVUx;
@ -1169,7 +1168,7 @@ microVUf(void) mVU_IBLEZ() {
else mVUallocVIa<vuIndex>(gprT1, _Fs_);
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBLEZ vi%02d [%04x]", _Fs_, branchAddr); }
pass3 { mVUlog("IBLEZ vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBLTZ() {
microVU* mVU = mVUx;
@ -1180,7 +1179,7 @@ microVUf(void) mVU_IBLTZ() {
else mVUallocVIa<vuIndex>(gprT1, _Fs_);
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBLTZ vi%02d [%04x]", _Fs_, branchAddr); }
pass3 { mVUlog("IBLTZ vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBNE() {
microVU* mVU = mVUx;
@ -1193,7 +1192,7 @@ microVUf(void) mVU_IBNE() {
else { mVUallocVIa<vuIndex>(gprT2, _Ft_); XOR32RtoR(gprT1, gprT2); }
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBNE vi%02d, vi%02d [%04x]", _Ft_, _Fs_, branchAddr); }
pass3 { mVUlog("IBNE vi%02d, vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Ft_, _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_JR() {
microVU* mVU = mVUx;

View File

@ -231,7 +231,7 @@ declareAllVariables
#define doDivFlag (mVUinfo & (1<<28))
#define doClip (mVUinfo & (1<<29))
#define isMMX(_VIreg_) (_VIreg_ >= 1 && _VIreg_ <=9)
#define isMMX(_VIreg_) 0//(_VIreg_ >= 1 && _VIreg_ <=8)
#define mmVI(_VIreg_) (_VIreg_ - 1)
#ifdef mVUdebug
@ -250,11 +250,9 @@ declareAllVariables
#ifdef mVUlogProg
#define mVUlog __mVULog<vuIndex>
#define mVUsetupLog __mVUsetupLog<vuIndex>
#define mVUdumpProg __mVUdumpProgram<vuIndex>
#else
#define mVUlog 0&&
#define mVUsetupLog()
#define mVUdumpProg 0&&
#endif

View File

@ -281,4 +281,22 @@ microVUt(void) mVUaddrFix(int gprReg) {
}
}
// Backup Volatile Regs (EAX, ECX, EDX, MM0~7, XMM0~7, are all volatile according to 32bit Win/Linux ABI)
microVUt(void) mVUbackupRegs() {
microVU* mVU = mVUx;
SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->ACC.UL[0], xmmACC);
SSE_MOVAPS_XMM_to_M128((uptr)&mVU->xmmPQb[0], xmmPQ);
PUSH32R(gprR); // Backup EDX
}
// Restore Volatile Regs
microVUt(void) mVUrestoreRegs() {
microVU* mVU = mVUx;
SSE_MOVAPS_M128_to_XMM(xmmACC, (uptr)&mVU->regs->ACC.UL[0]);
SSE_MOVAPS_M128_to_XMM(xmmPQ, (uptr)&mVU->xmmPQb[0]);
SSE_MOVAPS_M128_to_XMM(xmmMax, (uptr)mVU_maxvals);
SSE_MOVAPS_M128_to_XMM(xmmMin, (uptr)mVU_minvals);
POP32R(gprR); // Restore EDX
}
#endif //PCSX2_MICROVU