mirror of https://github.com/PCSX2/pcsx2.git
microVU: Added some options in microVU_Misc.h to easily enable/disable certain mVU features to help in debugging problematic games...
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4625 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
d9d909849d
commit
a70fec55f7
|
@ -441,13 +441,21 @@ __ri int mVUbranchCheck(mV) {
|
|||
if (!mVUcount) return 0;
|
||||
incPC(-2);
|
||||
if (mVUlow.branch) {
|
||||
mVUlow.badBranch = 1;
|
||||
incPC(2);
|
||||
mVUlow.evilBranch = 1;
|
||||
mVUregs.blockType = 2;
|
||||
mVUregs.needExactMatch |= 7; // This might not be necessary, but w/e...
|
||||
DevCon.Warning("microVU%d Warning: Branch in Branch delay slot! [%04x]", mVU.index, xPC);
|
||||
return 1;
|
||||
if (doBranchInDelaySlot) {
|
||||
mVUlow.badBranch = 1;
|
||||
incPC(2);
|
||||
mVUlow.evilBranch = 1;
|
||||
mVUregs.blockType = 2;
|
||||
mVUregs.needExactMatch |= 7; // This might not be necessary, but w/e...
|
||||
DevCon.Warning("microVU%d Warning: Branch in Branch delay slot! [%04x]", mVU.index, xPC);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
incPC(2);
|
||||
mVUlow.isNOP = 1;
|
||||
DevCon.Warning("microVU%d Warning: Branch in Branch delay slot! [%04x]", mVU.index, xPC);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
incPC(2);
|
||||
return 0;
|
||||
|
|
|
@ -118,7 +118,7 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump) {
|
|||
else xMOV(gprT3, (uptr)&mVUpBlock->pStateEnd);
|
||||
|
||||
if (!mVU.index) xCALL(mVUcompileJIT<0>); //(u32 startPC, uptr pState)
|
||||
else xCALL(mVUcompileJIT<1>);
|
||||
else xCALL(mVUcompileJIT<1>);
|
||||
|
||||
mVUrestoreRegs(mVU);
|
||||
xJMP(gprT1); // Jump to rec-code address
|
||||
|
|
|
@ -513,6 +513,9 @@ __fi void* mVUblockFetch(microVU& mVU, u32 startPC, uptr pState) {
|
|||
|
||||
// mVUcompileJIT() - Called By JR/JALR during execution
|
||||
_mVUt void* __fastcall mVUcompileJIT(u32 startPC, uptr ptr) {
|
||||
if (doJumpAsSameProgram) { // Treat jump as part of same microProgram
|
||||
return mVUblockFetch(mVUx, startPC, ptr);
|
||||
}
|
||||
if (doJumpCaching) { // When doJumpCaching, ptr is a microBlock pointer
|
||||
microVU& mVU = mVUx;
|
||||
microBlock* pBlock = (microBlock*)ptr;
|
||||
|
@ -524,7 +527,6 @@ _mVUt void* __fastcall mVUcompileJIT(u32 startPC, uptr ptr) {
|
|||
return v;
|
||||
}
|
||||
else { // When !doJumpCaching, pBlock param is really a microRegInfo pointer
|
||||
//return mVUblockFetch(mVUx, startPC, ptr);
|
||||
return mVUsearchProg<vuIndex>(startPC, ptr); // Find and set correct program
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,8 +168,8 @@ void mVUdispatcherD(mV) {
|
|||
_mVUt void* __fastcall mVUexecute(u32 startPC, u32 cycles) {
|
||||
|
||||
microVU& mVU = mVUx;
|
||||
u32 vuLimit = vuIndex ? 0x3fff : 0xfff;
|
||||
if (startPC > vuLimit) {
|
||||
u32 vuLimit = vuIndex ? 0x3ff8 : 0xff8;
|
||||
if (startPC > vuLimit + 7) {
|
||||
DevCon.Warning("microVU%x Warning: startPC = 0x%x, cycles = 0x%x", vuIndex, startPC, cycles);
|
||||
}
|
||||
|
||||
|
|
|
@ -131,17 +131,17 @@ __fi void mVUsetFlags(mV, microFlagCycles& mFC) {
|
|||
}
|
||||
mFC.cycles += mVUstall;
|
||||
|
||||
sFLAG.read = findFlagInst(mFC.xStatus, mFC.cycles);
|
||||
mFLAG.read = findFlagInst(mFC.xMac, mFC.cycles);
|
||||
cFLAG.read = findFlagInst(mFC.xClip, mFC.cycles);
|
||||
sFLAG.read = doFlagInsts ? findFlagInst(mFC.xStatus, mFC.cycles) : 0;
|
||||
mFLAG.read = doFlagInsts ? findFlagInst(mFC.xMac, mFC.cycles) : 0;
|
||||
cFLAG.read = doFlagInsts ? findFlagInst(mFC.xClip, mFC.cycles) : 0;
|
||||
|
||||
sFLAG.write = xS;
|
||||
mFLAG.write = xM;
|
||||
cFLAG.write = xC;
|
||||
sFLAG.write = doFlagInsts ? xS : 0;
|
||||
mFLAG.write = doFlagInsts ? xM : 0;
|
||||
cFLAG.write = doFlagInsts ? xC : 0;
|
||||
|
||||
sFLAG.lastWrite = (xS-1) & 3;
|
||||
mFLAG.lastWrite = (xM-1) & 3;
|
||||
cFLAG.lastWrite = (xC-1) & 3;
|
||||
sFLAG.lastWrite = doFlagInsts ? (xS-1) & 3 : 0;
|
||||
mFLAG.lastWrite = doFlagInsts ? (xM-1) & 3 : 0;
|
||||
cFLAG.lastWrite = doFlagInsts ? (xC-1) & 3 : 0;
|
||||
|
||||
if (sHackCond) { sFLAG.doFlag = 0; }
|
||||
if (sFLAG.doFlag) { if(noFlagOpts){sFLAG.doNonSticky=1;mFLAG.doFlag=1;}}
|
||||
|
|
|
@ -552,6 +552,8 @@ mVUop(mVU_FMOR) {
|
|||
mVUop(mVU_FSAND) {
|
||||
pass1 { mVUanalyzeSflag(mVU, _It_); }
|
||||
pass2 {
|
||||
if (_Imm12_ & 0x0c30) DevCon.WriteLn(Color_Green, "mVU_FSAND: Checking I/D/IS/DS Flags");
|
||||
if (_Imm12_ & 0x030c) DevCon.WriteLn(Color_Green, "mVU_FSAND: Checking U/O/US/OS Flags");
|
||||
mVUallocSFLAGc(gprT1, gprT2, sFLAG.read);
|
||||
xAND(gprT1, _Imm12_);
|
||||
mVUallocVIb(mVU, gprT1, _It_);
|
||||
|
@ -575,6 +577,8 @@ mVUop(mVU_FSEQ) {
|
|||
pass1 { mVUanalyzeSflag(mVU, _It_); }
|
||||
pass2 {
|
||||
int imm = 0;
|
||||
if (_Imm12_ & 0x0c30) DevCon.WriteLn(Color_Green, "mVU_FSEQ: Checking I/D/IS/DS Flags");
|
||||
if (_Imm12_ & 0x030c) DevCon.WriteLn(Color_Green, "mVU_FSEQ: Checking U/O/US/OS Flags");
|
||||
if (_Imm12_ & 0x0001) imm |= 0x0000f00; // Z
|
||||
if (_Imm12_ & 0x0002) imm |= 0x000f000; // S
|
||||
if (_Imm12_ & 0x0004) imm |= 0x0010000; // U
|
||||
|
|
|
@ -273,7 +273,7 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
|
|||
#endif
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Optimization Options
|
||||
// Optimization / Debug Options
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// Reg Alloc
|
||||
|
@ -291,6 +291,21 @@ static const bool noFlagOpts = 0; // Set to 1 to disable all flag setting optimi
|
|||
// an Upper Instruction updates them. It also always transfers the 4 possible
|
||||
// flag instances between blocks...
|
||||
|
||||
// Multiple Flag Instances
|
||||
static const bool doFlagInsts = 1; // Set to 1 to enable multiple flag instances
|
||||
// This is the correct behavior of the VU's. Due to the pipeline of the VU's
|
||||
// there can be up to 4 different instances of values to keep track of
|
||||
// for the 3 different types of flags: Status, Mac, Clip flags.
|
||||
// Setting this to 0 acts as if there is only 1 instance of each flag,
|
||||
// which may be useful to check for potential flag pipeline bugs.
|
||||
|
||||
// Branch in Branch Delay Slots
|
||||
static const bool doBranchInDelaySlot = 1; // Set to 1 to enable evil-branches
|
||||
// This attempts to emulate the correct behavior for branches in branch delay
|
||||
// slots. It is evil that games do this, and handling the different possible
|
||||
// cases is tricky and bug prone. If this option is disabled then the second
|
||||
// branch is treated as a NOP and effectively ignored.
|
||||
|
||||
// Constant Propagation
|
||||
static const bool doConstProp = 0; // Set to 1 to turn on vi15 const propagation
|
||||
// Enables Constant Propagation for Jumps based on vi15 'link-register'
|
||||
|
@ -304,6 +319,16 @@ static const bool doJumpCaching = 1; // Set to 1 to enable jump caching
|
|||
// routine that is performed every indirect jump in order to find a block within a
|
||||
// program that matches the correct pipeline state.
|
||||
|
||||
// Indirect Jumps are part of same cached microProgram
|
||||
static const bool doJumpAsSameProgram = 0; // Set to 1 to treat jumps as same program
|
||||
// Enabling this treats indirect jumps (JR/JALR) as part of the same microProgram
|
||||
// when determining the valid ranges for the microProgram cache. Disabling this
|
||||
// counts indirect jumps as separate cached microPrograms which generally leads
|
||||
// to more microPrograms being cached, but the programs created are smaller and
|
||||
// the overall cache usage ends up being more optimal; it can also help prevent
|
||||
// constant recompilation problems in certain games.
|
||||
// Note: You MUST disable doJumpCaching if you enable this option.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Speed Hacks (can cause infinite loops, SPS, Black Screens, etc...)
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -434,7 +434,7 @@ void SSE_ADD2SS(mV, const xmm& to, const xmm& from, const xmm& t1 = xEmptyReg, c
|
|||
else { ADD_SS(mVU, to, from, t1, t2); }
|
||||
}
|
||||
|
||||
// FIXME: why do we need two identical definitions with different names?
|
||||
// Does same as SSE_ADDPS since tri-ace games only need SS implementation of VUADDSUBHACK...
|
||||
void SSE_ADD2PS(mV, const xmm& to, const xmm& from, const xmm& t1 = xEmptyReg, const xmm& t2 = xEmptyReg)
|
||||
{
|
||||
clampOp(xADD.PS, 1);
|
||||
|
|
Loading…
Reference in New Issue