mirror of https://github.com/PCSX2/pcsx2.git
microVU:
- Reimplemented mini/max opcodes using integer comparison operations instead of double comparison. This results in a bit less code and integer operations tend to be faster than double ops (especially on AMD cpus). Thanks to pseudonym for the idea! - Fixed some minor bugs in mVU dev builds. pcsx2: - Added __fc as a shorthand macro for __fastcall since we already have __ri and __fi macros. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4713 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
daa5a00a98
commit
996ca8ffff
|
@ -308,6 +308,7 @@ static const int __pagesize = PCSX2_PAGESIZE;
|
|||
|
||||
#define __ri __releaseinline
|
||||
#define __fi __forceinline
|
||||
#define __fc __fastcall
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
// Messages Called at Execution Time...
|
||||
//------------------------------------------------------------------
|
||||
|
||||
static void __fastcall mVUbadOp0(u32 prog, u32 pc) { Console.Error("microVU0 Warning: Exiting... Block started with illegal opcode. [%04x] [%x]", pc, prog); }
|
||||
static void __fastcall mVUbadOp1(u32 prog, u32 pc) { Console.Error("microVU1 Warning: Exiting... Block started with illegal opcode. [%04x] [%x]", pc, prog); }
|
||||
static void __fastcall mVUwarning0(u32 prog) { Console.Error("microVU0 Warning: Exiting from Possible Infinite Loop [%03d]", prog); }
|
||||
static void __fastcall mVUwarning1(u32 prog) { Console.Error("microVU1 Warning: Exiting from Possible Infinite Loop [%03d]", prog); }
|
||||
static void __fastcall mVUprintPC1(u32 pc) { Console.WriteLn("Block Start PC = 0x%04x", pc); }
|
||||
static void __fastcall mVUprintPC2(u32 pc) { Console.WriteLn("Block End PC = 0x%04x", pc); }
|
||||
static void __fc mVUbadOp0 (u32 prog, u32 pc) { Console.Error("microVU0 Warning: Exiting... Block started with illegal opcode. [%04x] [%03d]", pc, prog); }
|
||||
static void __fc mVUbadOp1 (u32 prog, u32 pc) { Console.Error("microVU1 Warning: Exiting... Block started with illegal opcode. [%04x] [%03d]", pc, prog); }
|
||||
static void __fc mVUwarning0(u32 prog, u32 pc) { Console.Error("microVU0 Warning: Exiting from Possible Infinite Loop [%04x] [%03d]", pc, prog); }
|
||||
static void __fc mVUwarning1(u32 prog, u32 pc) { Console.Error("microVU1 Warning: Exiting from Possible Infinite Loop [%04x] [%03d]", pc, prog); }
|
||||
static void __fc mVUprintPC1(u32 pc) { Console.WriteLn("Block Start PC = 0x%04x", pc); }
|
||||
static void __fc mVUprintPC2(u32 pc) { Console.WriteLn("Block End PC = 0x%04x", pc); }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Program Range Checking and Setting up Ranges
|
||||
|
@ -330,7 +330,7 @@ __fi bool doEarlyExit(microVU& mVU) {
|
|||
// Saves Pipeline State for resuming from early exits
|
||||
__fi void mVUsavePipelineState(microVU& mVU) {
|
||||
u32* lpS = (u32*)&mVU.prog.lpState;
|
||||
for (int i = 0; i < (sizeof(microRegInfo)-4)/4; i++, lpS++) {
|
||||
for(int i = 0; i < (sizeof(microRegInfo)-4)/4; i++, lpS++) {
|
||||
xMOV(ptr32[lpS], lpS[0]);
|
||||
}
|
||||
}
|
||||
|
@ -346,8 +346,9 @@ void mVUtestCycles(microVU& mVU) {
|
|||
// xFowardJZ32 vu0jmp;
|
||||
// mVUbackupRegs(mVU, true);
|
||||
// xMOV(gprT2, mVU.prog.cur->idx);
|
||||
// xMOV(gprT3, xPC);
|
||||
// xCALL(mVUwarning0); // VU0 is allowed early exit for COP2 Interlock Simulation
|
||||
// mVUbackupRegs(mVU, true);
|
||||
// mVUrestoreRegs(mVU, true);
|
||||
mVUsavePipelineState(mVU);
|
||||
mVUendProgram(mVU, NULL, 0);
|
||||
// vu0jmp.SetTarget();
|
||||
|
@ -355,8 +356,9 @@ void mVUtestCycles(microVU& mVU) {
|
|||
else {
|
||||
mVUbackupRegs(mVU, true);
|
||||
xMOV(gprT2, mVU.prog.cur->idx);
|
||||
xMOV(gprT3, xPC);
|
||||
xCALL(mVUwarning1);
|
||||
mVUbackupRegs(mVU, true);
|
||||
mVUrestoreRegs(mVU, true);
|
||||
mVUsavePipelineState(mVU);
|
||||
mVUendProgram(mVU, NULL, 0);
|
||||
}
|
||||
|
@ -507,7 +509,7 @@ __fi void* mVUentryGet(microVU& mVU, microBlockManager* block, u32 startPC, uptr
|
|||
__fi void* mVUblockFetch(microVU& mVU, u32 startPC, uptr pState) {
|
||||
|
||||
pxAssumeDev((startPC & 7) == 0, pxsFmt("microVU%d: unaligned startPC=0x%04x", mVU.index, startPC) );
|
||||
pxAssumeDev( startPC < mVU.microMemSize-8, pxsFmt("microVU%d: invalid startPC=0x%04x", mVU.index, startPC) );
|
||||
pxAssumeDev( startPC <= mVU.microMemSize-8, pxsFmt("microVU%d: invalid startPC=0x%04x", mVU.index, startPC) );
|
||||
startPC &= mVU.microMemSize-8;
|
||||
|
||||
blockCreate(startPC/8);
|
||||
|
|
|
@ -292,27 +292,50 @@ void MIN_MAX_PS(microVU& mVU, const xmm& to, const xmm& from, const xmm& t1in, c
|
|||
{
|
||||
const xmm& t1 = t1in.IsEmpty() ? mVU.regAlloc->allocReg() : t1in;
|
||||
const xmm& t2 = t2in.IsEmpty() ? mVU.regAlloc->allocReg() : t2in;
|
||||
// ZW
|
||||
xPSHUF.D(t1, to, 0xfa);
|
||||
xPAND (t1, ptr128[MIN_MAX.mask1]);
|
||||
xPOR (t1, ptr128[MIN_MAX.mask2]);
|
||||
xPSHUF.D(t2, from, 0xfa);
|
||||
xPAND (t2, ptr128[MIN_MAX.mask1]);
|
||||
xPOR (t2, ptr128[MIN_MAX.mask2]);
|
||||
if (min) xMIN.PD(t1, t2);
|
||||
else xMAX.PD(t1, t2);
|
||||
|
||||
// XY
|
||||
xPSHUF.D(t2, from, 0x50);
|
||||
xPAND (t2, ptr128[MIN_MAX.mask1]);
|
||||
xPOR (t2, ptr128[MIN_MAX.mask2]);
|
||||
xPSHUF.D(to, to, 0x50);
|
||||
xPAND (to, ptr128[MIN_MAX.mask1]);
|
||||
xPOR (to, ptr128[MIN_MAX.mask2]);
|
||||
if (min) xMIN.PD(to, t2);
|
||||
else xMAX.PD(to, t2);
|
||||
if (0) { // use double comparison
|
||||
// ZW
|
||||
xPSHUF.D(t1, to, 0xfa);
|
||||
xPAND (t1, ptr128[MIN_MAX.mask1]);
|
||||
xPOR (t1, ptr128[MIN_MAX.mask2]);
|
||||
xPSHUF.D(t2, from, 0xfa);
|
||||
xPAND (t2, ptr128[MIN_MAX.mask1]);
|
||||
xPOR (t2, ptr128[MIN_MAX.mask2]);
|
||||
if (min) xMIN.PD(t1, t2);
|
||||
else xMAX.PD(t1, t2);
|
||||
|
||||
// XY
|
||||
xPSHUF.D(t2, from, 0x50);
|
||||
xPAND (t2, ptr128[MIN_MAX.mask1]);
|
||||
xPOR (t2, ptr128[MIN_MAX.mask2]);
|
||||
xPSHUF.D(to, to, 0x50);
|
||||
xPAND (to, ptr128[MIN_MAX.mask1]);
|
||||
xPOR (to, ptr128[MIN_MAX.mask2]);
|
||||
if (min) xMIN.PD(to, t2);
|
||||
else xMAX.PD(to, t2);
|
||||
|
||||
xSHUF.PS(to, t1, 0x88);
|
||||
}
|
||||
else { // use integer comparison
|
||||
const xmm& c1 = min ? t2 : t1;
|
||||
const xmm& c2 = min ? t1 : t2;
|
||||
|
||||
xMOVAPS (t1, to);
|
||||
xPSRA.D (t1, 31);
|
||||
xPSRL.D (t1, 1);
|
||||
xPXOR (t1, to);
|
||||
|
||||
xMOVAPS (t2, from);
|
||||
xPSRA.D (t2, 31);
|
||||
xPSRL.D (t2, 1);
|
||||
xPXOR (t2, from);
|
||||
|
||||
xPCMP.GTD(c1, c2);
|
||||
xPAND (to, c1);
|
||||
xPANDN (c1, from);
|
||||
xPOR (to, c1);
|
||||
}
|
||||
|
||||
xSHUF.PS(to, t1, 0x88);
|
||||
if (t1 != t1in) mVU.regAlloc->clearNeeded(t1);
|
||||
if (t2 != t2in) mVU.regAlloc->clearNeeded(t2);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue