- 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:
cottonvibes 2011-06-05 10:30:04 +00:00
parent daa5a00a98
commit 996ca8ffff
3 changed files with 55 additions and 29 deletions

View File

@ -308,6 +308,7 @@ static const int __pagesize = PCSX2_PAGESIZE;
#define __ri __releaseinline
#define __fi __forceinline
#define __fc __fastcall
#endif

View File

@ -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);

View File

@ -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);
}