microVU: more cleanups (mostly just change pointers to references)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4415 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2011-03-12 08:02:21 +00:00
parent 6c8dc7bcb6
commit c4d8356a1b
5 changed files with 130 additions and 164 deletions

View File

@ -16,64 +16,7 @@
// Micro VU recompiler! - author: cottonvibes(@gmail.com) // Micro VU recompiler! - author: cottonvibes(@gmail.com)
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Common.h"
#include "microVU.h" #include "microVU.h"
#include "System/RecTypes.h"
// Include all the *.inl files (Needed because C++ sucks with templates and *.cpp files)
#include "microVU_Clamp.inl"
#include "microVU_Misc.inl"
#include "microVU_Log.inl"
#include "microVU_Analyze.inl"
#include "microVU_Alloc.inl"
#include "microVU_Upper.inl"
#include "microVU_Lower.inl"
#include "microVU_Tables.inl"
#include "microVU_Flags.inl"
#include "microVU_Branch.inl"
#include "microVU_Compile.inl"
#include "microVU_Execute.inl"
#include "microVU_Macro.inl"
//------------------------------------------------------------------
// Micro VU - Global Variables
//------------------------------------------------------------------
__aligned16 microVU microVU0;
__aligned16 microVU microVU1;
const __aligned(32) mVU_Globals mVUglob = {
__four(0x7fffffff), // absclip
__four(0x80000000), // signbit
__four(0xff7fffff), // minvals
__four(0x7f7fffff), // maxvals
__four(0x3f800000), // ONE!
__four(0x3f490fdb), // PI4!
__four(0x3f7ffff5), // T1
__four(0xbeaaa61c), // T5
__four(0x3e4c40a6), // T2
__four(0xbe0e6c63), // T3
__four(0x3dc577df), // T4
__four(0xbd6501c4), // T6
__four(0x3cb31652), // T7
__four(0xbb84d7e7), // T8
__four(0xbe2aaaa4), // S2
__four(0x3c08873e), // S3
__four(0xb94fb21f), // S4
__four(0x362e9c14), // S5
__four(0x3e7fffa8), // E1
__four(0x3d0007f4), // E2
__four(0x3b29d3ff), // E3
__four(0x3933e553), // E4
__four(0x36b63510), // E5
__four(0x353961ac), // E6
__four(16.0), // FTOI_4
__four(4096.0), // FTOI_12
__four(32768.0), // FTOI_15
__four(0.0625f), // ITOF_4
__four(0.000244140625), // ITOF_12
__four(0.000030517578125) // ITOF_15
};
//------------------------------------------------------------------ //------------------------------------------------------------------
// Micro VU - Main Functions // Micro VU - Main Functions
@ -162,11 +105,9 @@ void mVUreset(microVU& mVU, bool resetReserve) {
mVU.prog.prog[i] = new deque<microProgram*>(); mVU.prog.prog[i] = new deque<microProgram*>();
continue; continue;
} }
deque<microProgram*>::iterator it(mVU.prog.prog[i]->begin()); deque<microProgram*>::iterator it(mVU.prog.prog[i]->begin());
for ( ; it != mVU.prog.prog[i]->end(); ++it) { for ( ; it != mVU.prog.prog[i]->end(); ++it) {
if (mVU.index) mVUdeleteProg<1>(it[0]); mVUdeleteProg(mVU, it[0]);
else mVUdeleteProg<0>(it[0]);
} }
mVU.prog.prog[i]->clear(); mVU.prog.prog[i]->clear();
mVU.prog.quick[i].block = NULL; mVU.prog.quick[i].block = NULL;
@ -177,8 +118,7 @@ void mVUreset(microVU& mVU, bool resetReserve) {
// Free Allocated Resources // Free Allocated Resources
void mVUclose(microVU& mVU) { void mVUclose(microVU& mVU) {
safe_delete(mVU.cache_reserve); safe_delete (mVU.cache_reserve);
SafeSysMunmap(mVU.dispCache, mVUdispCacheSize); SafeSysMunmap(mVU.dispCache, mVUdispCacheSize);
// Delete Programs and Block Managers // Delete Programs and Block Managers
@ -186,8 +126,7 @@ void mVUclose(microVU& mVU) {
if (!mVU.prog.prog[i]) continue; if (!mVU.prog.prog[i]) continue;
deque<microProgram*>::iterator it(mVU.prog.prog[i]->begin()); deque<microProgram*>::iterator it(mVU.prog.prog[i]->begin());
for ( ; it != mVU.prog.prog[i]->end(); ++it) { for ( ; it != mVU.prog.prog[i]->end(); ++it) {
if (mVU.index) mVUdeleteProg<1>(it[0]); mVUdeleteProg(mVU, it[0]);
else mVUdeleteProg<0>(it[0]);
} }
safe_delete(mVU.prog.prog[i]); safe_delete(mVU.prog.prog[i]);
} }
@ -210,14 +149,13 @@ static __fi void mVUclear(mV, u32 addr, u32 size) {
//------------------------------------------------------------------ //------------------------------------------------------------------
// 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.
static __fi void mVUvsyncUpdate(mV) { static __ri void mVUvsyncUpdate(mV) {
//mVU->prog.curFrame++; //mVU->prog.curFrame++;
} }
// Deletes a program // Deletes a program
_mVUt __fi void mVUdeleteProg(microProgram*& prog) { __ri void mVUdeleteProg(microVU& mVU, microProgram*& prog) {
microVU* mVU = mVUx; for (u32 i = 0; i < (mVU.progSize / 2); i++) {
for (u32 i = 0; i < (mVU->progSize / 2); i++) {
safe_delete(prog->block[i]); safe_delete(prog->block[i]);
} }
safe_delete(prog->ranges); safe_delete(prog->ranges);
@ -225,38 +163,35 @@ _mVUt __fi void mVUdeleteProg(microProgram*& prog) {
} }
// Creates a new Micro Program // Creates a new Micro Program
_mVUt __fi microProgram* mVUcreateProg(int startPC) { __ri microProgram* mVUcreateProg(microVU& mVU, int startPC) {
microVU* mVU = mVUx;
microProgram* prog = (microProgram*)_aligned_malloc(sizeof(microProgram), 64); microProgram* prog = (microProgram*)_aligned_malloc(sizeof(microProgram), 64);
memzero_ptr<sizeof(microProgram)>(prog); memzero_ptr<sizeof(microProgram)>(prog);
prog->idx = mVU->prog.total++; prog->idx = mVU.prog.total++;
prog->ranges = new deque<microRange>(); prog->ranges = new deque<microRange>();
prog->startPC = startPC; prog->startPC = startPC;
mVUcacheProg<vuIndex>(*prog); // Cache Micro Program mVUcacheProg(mVU, *prog); // Cache Micro Program
double cacheSize = (double)((u32)mVU->prog.x86end - (u32)mVU->prog.x86start); double cacheSize = (double)((u32)mVU.prog.x86end - (u32)mVU.prog.x86start);
double cacheUsed =((double)((u32)mVU->prog.x86ptr - (u32)mVU->prog.x86start)) / (double)_1mb; double cacheUsed =((double)((u32)mVU.prog.x86ptr - (u32)mVU.prog.x86start)) / (double)_1mb;
double cachePerc =((double)((u32)mVU->prog.x86ptr - (u32)mVU->prog.x86start)) / cacheSize * 100; double cachePerc =((double)((u32)mVU.prog.x86ptr - (u32)mVU.prog.x86start)) / cacheSize * 100;
ConsoleColors c = vuIndex ? Color_Orange : Color_Magenta; ConsoleColors c = mVU.index ? Color_Orange : Color_Magenta;
DevCon.WriteLn(c, "microVU%d: Cached Prog = [%03d] [PC=%04x] [List=%02d] (Cache=%3.3f%%) [%3.1fmb]", DevCon.WriteLn(c, "microVU%d: Cached Prog = [%03d] [PC=%04x] [List=%02d] (Cache=%3.3f%%) [%3.1fmb]",
vuIndex, prog->idx, startPC*8, mVU->prog.prog[startPC]->size()+1, cachePerc, cacheUsed); mVU.index, prog->idx, startPC*8, mVU.prog.prog[startPC]->size()+1, cachePerc, cacheUsed);
return prog; return prog;
} }
// Caches Micro Program // Caches Micro Program
_mVUt __fi void mVUcacheProg(microProgram& prog) { __ri void mVUcacheProg(microVU& mVU, microProgram& prog) {
microVU* mVU = mVUx; if (!mVU.index) memcpy_const(prog.data, mVU.regs().Micro, 0x1000);
if (!vuIndex) memcpy_const(prog.data, mVU->regs().Micro, 0x1000); else memcpy_const(prog.data, mVU.regs().Micro, 0x4000);
else memcpy_const(prog.data, mVU->regs().Micro, 0x4000);
mVUdumpProg(prog); mVUdumpProg(prog);
} }
// Generate Hash for partial program based on compiled ranges... // Generate Hash for partial program based on compiled ranges...
_mVUt __fi u64 mVUrangesHash(microProgram& prog) { u64 mVUrangesHash(microVU& mVU, microProgram& prog) {
microVU* mVU = mVUx;
u32 hash[2] = {0, 0}; u32 hash[2] = {0, 0};
deque<microRange>::const_iterator it(prog.ranges->begin()); deque<microRange>::const_iterator it(prog.ranges->begin());
for ( ; it != prog.ranges->end(); ++it) { for ( ; it != prog.ranges->end(); ++it) {
if((it[0].start<0)||(it[0].end<0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU->index, it[0].start, it[0].end); } if((it[0].start<0)||(it[0].end<0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU.index, it[0].start, it[0].end); }
for(int i = it[0].start/4; i < it[0].end/4; i++) { for(int i = it[0].start/4; i < it[0].end/4; i++) {
hash[0] -= prog.data[i]; hash[0] -= prog.data[i];
hash[1] ^= prog.data[i]; hash[1] ^= prog.data[i];
@ -266,15 +201,14 @@ _mVUt __fi u64 mVUrangesHash(microProgram& prog) {
} }
// Prints the ratio of unique programs to total programs // Prints the ratio of unique programs to total programs
_mVUt __fi void mVUprintUniqueRatio() { void mVUprintUniqueRatio(microVU& mVU) {
microVU* mVU = mVUx;
vector<u64> v; vector<u64> v;
for(u32 pc = 0; pc < mProgSize/2; pc++) { for(u32 pc = 0; pc < mProgSize/2; pc++) {
microProgramList* list = mVU->prog.prog[pc]; microProgramList* list = mVU.prog.prog[pc];
if (!list) continue; if (!list) continue;
deque<microProgram*>::iterator it(list->begin()); deque<microProgram*>::iterator it(list->begin());
for ( ; it != list->end(); ++it) { for ( ; it != list->end(); ++it) {
v.push_back(mVUrangesHash<vuIndex>(*it[0])); v.push_back(mVUrangesHash(mVU, *it[0]));
} }
} }
u32 total = v.size(); u32 total = v.size();
@ -285,12 +219,11 @@ _mVUt __fi void mVUprintUniqueRatio() {
} }
// Compare partial program by only checking compiled ranges... // Compare partial program by only checking compiled ranges...
_mVUt __fi bool mVUcmpPartial(microProgram& prog) { __ri bool mVUcmpPartial(microVU& mVU, microProgram& prog) {
microVU* mVU = mVUx;
deque<microRange>::const_iterator it(prog.ranges->begin()); deque<microRange>::const_iterator it(prog.ranges->begin());
for ( ; it != prog.ranges->end(); ++it) { for ( ; it != prog.ranges->end(); ++it) {
if((it[0].start<0)||(it[0].end<0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU->index, it[0].start, it[0].end); } if((it[0].start<0)||(it[0].end<0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU.index, it[0].start, it[0].end); }
if (memcmp_mmx(cmpOffset(prog.data), cmpOffset(mVU->regs().Micro), ((it[0].end + 8) - it[0].start))) { if (memcmp_mmx(cmpOffset(prog.data), cmpOffset(mVU.regs().Micro), ((it[0].end + 8) - it[0].start))) {
return 0; return 0;
} }
} }
@ -298,13 +231,12 @@ _mVUt __fi bool mVUcmpPartial(microProgram& prog) {
} }
// Compare Cached microProgram to mVU->regs().Micro // Compare Cached microProgram to mVU->regs().Micro
_mVUt __fi bool mVUcmpProg(microProgram& prog, const bool cmpWholeProg) { __fi bool mVUcmpProg(microVU& mVU, microProgram& prog, const bool cmpWholeProg) {
microVU* mVU = mVUx; if ((cmpWholeProg && !memcmp_mmx((u8*)prog.data, mVU.regs().Micro, mVU.microMemSize))
if ((cmpWholeProg && !memcmp_mmx((u8*)prog.data, mVU->regs().Micro, mVU->microMemSize)) || (!cmpWholeProg && mVUcmpPartial(mVU, prog))) {
|| (!cmpWholeProg && mVUcmpPartial<vuIndex>(prog))) { mVU.prog.cleared = 0;
mVU->prog.cleared = 0; mVU.prog.cur = &prog;
mVU->prog.cur = &prog; mVU.prog.isSame = cmpWholeProg ? 1 : -1;
mVU->prog.isSame = cmpWholeProg ? 1 : -1;
return 1; return 1;
} }
return 0; return 0;
@ -312,13 +244,13 @@ _mVUt __fi bool mVUcmpProg(microProgram& prog, const bool cmpWholeProg) {
// Searches for Cached Micro Program and sets prog.cur to it (returns entry-point to program) // Searches for Cached Micro Program and sets prog.cur to it (returns entry-point to program)
_mVUt __fi void* mVUsearchProg(u32 startPC, uptr pState) { _mVUt __fi void* mVUsearchProg(u32 startPC, uptr pState) {
microVU* mVU = mVUx; microVU& mVU = mVUx;
microProgramQuick& quick = mVU->prog.quick[startPC/8]; microProgramQuick& quick = mVU.prog.quick[startPC/8];
microProgramList* list = mVU->prog.prog [startPC/8]; microProgramList* list = mVU.prog.prog [startPC/8];
if(!quick.prog) { // If null, we need to search for new program if(!quick.prog) { // If null, we need to search for new program
deque<microProgram*>::iterator it(list->begin()); deque<microProgram*>::iterator it(list->begin());
for ( ; it != list->end(); ++it) { for ( ; it != list->end(); ++it) {
if (mVUcmpProg<vuIndex>(*it[0], 0)) { if (mVUcmpProg(mVU, *it[0], 0)) {
quick.block = it[0]->block[startPC/8]; quick.block = it[0]->block[startPC/8];
quick.prog = it[0]; quick.prog = it[0];
list->erase(it); list->erase(it);
@ -328,19 +260,19 @@ _mVUt __fi void* mVUsearchProg(u32 startPC, uptr pState) {
} }
// If cleared and program not found, make a new program instance // If cleared and program not found, make a new program instance
mVU->prog.cleared = 0; mVU.prog.cleared = 0;
mVU->prog.isSame = 1; mVU.prog.isSame = 1;
mVU->prog.cur = mVUcreateProg<vuIndex>(startPC/8); mVU.prog.cur = mVUcreateProg( mVU, startPC/8);
void* entryPoint = mVUblockFetch(mVU, startPC, pState); void* entryPoint = mVUblockFetch(&mVU, startPC, pState);
quick.block = mVU->prog.cur->block[startPC/8]; quick.block = mVU.prog.cur->block[startPC/8];
quick.prog = mVU->prog.cur; quick.prog = mVU.prog.cur;
list->push_front(mVU->prog.cur); list->push_front(mVU.prog.cur);
//mVUprintUniqueRatio<vuIndex>(); //mVUprintUniqueRatio(mVU);
return entryPoint; return entryPoint;
} }
// If list.quick, then we've already found and recompiled the program ;) // If list.quick, then we've already found and recompiled the program ;)
mVU->prog.isSame = -1; mVU.prog.isSame = -1;
mVU->prog.cur = quick.prog; mVU.prog.cur = quick.prog;
return mVUentryGet(mVU, quick.block, startPC, pState); return mVUentryGet(mVU, quick.block, startPC, pState);
} }

View File

@ -21,12 +21,13 @@ using namespace std;
using namespace x86Emitter; using namespace x86Emitter;
#include <deque> #include <deque>
#include "Common.h"
#include "VU.h" #include "VU.h"
#include "GS.h" #include "GS.h"
#include "Gif.h" #include "Gif.h"
#include "iR5900.h" #include "iR5900.h"
#include "R5900OpcodeTables.h" #include "R5900OpcodeTables.h"
#include "System/RecTypes.h"
#include "x86emitter/x86emitter.h" #include "x86emitter/x86emitter.h"
#include "microVU_Misc.h" #include "microVU_Misc.h"
#include "microVU_IR.h" #include "microVU_IR.h"
@ -210,7 +211,7 @@ struct microVU {
VURegs& regs() const { return ::vuRegs[index]; } VURegs& regs() const { return ::vuRegs[index]; }
VIFregisters& getVifRegs() const { return regs().GetVifRegs(); } VIFregisters& getVifRegs() const { return regs().GetVifRegs(); }
__fi REG_VI& getVI(uint reg) const { return regs().VI[reg]; } __fi REG_VI& getVI(uint reg) const { return regs().VI[reg]; }
__fi VECTOR& getVF(uint reg) const { return regs().VF[reg]; } __fi VECTOR& getVF(uint reg) const { return regs().VF[reg]; }
@ -244,15 +245,16 @@ struct microVU {
}; };
// microVU rec structs // microVU rec structs
extern __aligned16 microVU microVU0; __aligned16 microVU microVU0;
extern __aligned16 microVU microVU1; __aligned16 microVU microVU1;
// Debug Helper // Debug Helper
int mVUdebugNow = 0; int mVUdebugNow = 0;
// Main Functions // Main Functions
static void mVUclear(mV, u32, u32); extern void mVUclear(mV, u32, u32);
static void* mVUblockFetch(microVU* mVU, u32 startPC, uptr pState); extern void mVUreset(microVU& mVU, bool resetReserve);
extern void* mVUblockFetch(microVU* mVU, u32 startPC, uptr pState);
_mVUt extern void* __fastcall mVUcompileJIT(u32 startPC, uptr ptr); _mVUt extern void* __fastcall mVUcompileJIT(u32 startPC, uptr ptr);
// Prototypes for Linux // Prototypes for Linux
@ -262,10 +264,9 @@ mVUop(mVUopU);
mVUop(mVUopL); mVUop(mVUopL);
// Private Functions // Private Functions
_mVUt extern void mVUcacheProg (microProgram& prog); extern void mVUcacheProg (microVU& mVU, microProgram& prog);
_mVUt extern void mVUdeleteProg(microProgram*& prog); extern void mVUdeleteProg(microVU& mVU, microProgram*& prog);
_mVUt extern void* mVUsearchProg(u32 startPC, uptr pState); _mVUt extern void* mVUsearchProg(u32 startPC, uptr pState);
_mVUt extern microProgram* mVUfindLeastUsedProg();
extern void* __fastcall mVUexecuteVU0(u32 startPC, u32 cycles); extern void* __fastcall mVUexecuteVU0(u32 startPC, u32 cycles);
extern void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles); extern void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles);
@ -282,3 +283,18 @@ template<typename T>
void sortVector(T& v) { void sortVector(T& v) {
sort(v.begin(), v.end()); sort(v.begin(), v.end());
} }
// Include all the *.inl files (microVU compiles as 1 Translation Unit)
#include "microVU_Clamp.inl"
#include "microVU_Misc.inl"
#include "microVU_Log.inl"
#include "microVU_Analyze.inl"
#include "microVU_Alloc.inl"
#include "microVU_Upper.inl"
#include "microVU_Lower.inl"
#include "microVU_Tables.inl"
#include "microVU_Flags.inl"
#include "microVU_Branch.inl"
#include "microVU_Compile.inl"
#include "microVU_Execute.inl"
#include "microVU_Macro.inl"

View File

@ -36,8 +36,7 @@ static __fi void mVUcheckIsSame(mV) {
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);
} }
if (mVU->prog.isSame == 0) { if (mVU->prog.isSame == 0) {
if (!isVU1) mVUcacheProg<0>(*mVU->prog.cur); mVUcacheProg(*mVU, *mVU->prog.cur);
else mVUcacheProg<1>(*mVU->prog.cur);
mVU->prog.isSame = 1; mVU->prog.isSame = 1;
} }
} }
@ -495,32 +494,32 @@ void* mVUcompile(microVU* mVU, u32 startPC, uptr pState) {
} }
// Returns the entry point of the block (compiles it if not found) // Returns the entry point of the block (compiles it if not found)
static __fi void* mVUentryGet(microVU* mVU, microBlockManager* block, u32 startPC, uptr pState) { static __fi void* mVUentryGet(microVU& mVU, microBlockManager* block, u32 startPC, uptr pState) {
microBlock* pBlock = block->search((microRegInfo*)pState); microBlock* pBlock = block->search((microRegInfo*)pState);
if (pBlock) return pBlock->x86ptrStart; if (pBlock) return pBlock->x86ptrStart;
else return mVUcompile(mVU, startPC, pState); else return mVUcompile(&mVU, startPC, pState);
} }
// Search for Existing Compiled Block (if found, return x86ptr; else, compile and return x86ptr) // Search for Existing Compiled Block (if found, return x86ptr; else, compile and return x86ptr)
static __fi void* mVUblockFetch(microVU* mVU, u32 startPC, uptr pState) { static __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 & 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; startPC &= mVU->microMemSize-8;
blockCreate(startPC/8); blockCreate(startPC/8);
return mVUentryGet(mVU, mVUblocks[startPC/8], startPC, pState); return mVUentryGet(*mVU, mVUblocks[startPC/8], startPC, pState);
} }
// mVUcompileJIT() - Called By JR/JALR during execution // mVUcompileJIT() - Called By JR/JALR during execution
_mVUt void* __fastcall mVUcompileJIT(u32 startPC, uptr ptr) { _mVUt void* __fastcall mVUcompileJIT(u32 startPC, uptr ptr) {
if (doJumpCaching) { // When doJumpCaching, ptr is a microBlock pointer if (doJumpCaching) { // When doJumpCaching, ptr is a microBlock pointer
microVU* mVU = mVUx; microVU& mVU = mVUx;
microBlock* pBlock = (microBlock*)ptr; microBlock* pBlock = (microBlock*)ptr;
microJumpCache& jc = pBlock->jumpCache[startPC/8]; microJumpCache& jc = pBlock->jumpCache[startPC/8];
if (jc.prog && jc.prog == mVU->prog.quick[startPC/8].prog) return jc.x86ptrStart; if (jc.prog && jc.prog == mVU.prog.quick[startPC/8].prog) return jc.x86ptrStart;
void* v = mVUsearchProg<vuIndex>(startPC, (uptr)&pBlock->pStateEnd); void* v = mVUsearchProg<vuIndex>(startPC, (uptr)&pBlock->pStateEnd);
jc.prog = mVU->prog.quick[startPC/8].prog; jc.prog = mVU.prog.quick[startPC/8].prog;
jc.x86ptrStart = v; jc.x86ptrStart = v;
return v; return v;
} }

View File

@ -19,10 +19,6 @@
// Dispatcher Functions // Dispatcher Functions
//------------------------------------------------------------------ //------------------------------------------------------------------
#ifdef __GNUC__
extern void mVUreset(microVU& mVU, bool resetReserve);
#endif
// Generates the code for entering recompiled blocks // Generates the code for entering recompiled blocks
void mVUdispatcherA(mV) { void mVUdispatcherA(mV) {
mVU->startFunct = x86Ptr; mVU->startFunct = x86Ptr;
@ -171,14 +167,14 @@ void mVUdispatcherD(mV) {
// Executes for number of cycles // Executes for number of cycles
_mVUt void* __fastcall mVUexecute(u32 startPC, u32 cycles) { _mVUt void* __fastcall mVUexecute(u32 startPC, u32 cycles) {
microVU* mVU = mVUx; microVU& mVU = mVUx;
//DevCon.WriteLn("microVU%x: startPC = 0x%x, cycles = 0x%x", vuIndex, startPC, cycles); //DevCon.WriteLn("microVU%x: startPC = 0x%x, cycles = 0x%x", vuIndex, startPC, cycles);
mVU->cycles = cycles; mVU.cycles = cycles;
mVU->totalCycles = cycles; mVU.totalCycles = cycles;
xSetPtr(mVU->prog.x86ptr); // Set x86ptr to where last program left off xSetPtr(mVU.prog.x86ptr); // Set x86ptr to where last program left off
return mVUsearchProg<vuIndex>(startPC, (uptr)&mVU->prog.lpState); // Find and set correct program return mVUsearchProg<vuIndex>(startPC, (uptr)&mVU.prog.lpState); // Find and set correct program
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -186,24 +182,24 @@ _mVUt void* __fastcall mVUexecute(u32 startPC, u32 cycles) {
//------------------------------------------------------------------ //------------------------------------------------------------------
_mVUt void mVUcleanUp() { _mVUt void mVUcleanUp() {
microVU* mVU = mVUx; microVU& mVU = mVUx;
//mVUprint("microVU: Program exited successfully!"); //mVUprint("microVU: Program exited successfully!");
//mVUprint("microVU: VF0 = {%x,%x,%x,%x}", mVU->regs().VF[0].UL[0], mVU->regs().VF[0].UL[1], mVU->regs().VF[0].UL[2], mVU->regs().VF[0].UL[3]); //mVUprint("microVU: VF0 = {%x,%x,%x,%x}", mVU.regs().VF[0].UL[0], mVU.regs().VF[0].UL[1], mVU.regs().VF[0].UL[2], mVU.regs().VF[0].UL[3]);
//mVUprint("microVU: VI0 = %x", mVU->regs().VI[0].UL); //mVUprint("microVU: VI0 = %x", mVU.regs().VI[0].UL);
mVU->prog.x86ptr = x86Ptr; mVU.prog.x86ptr = x86Ptr;
if ((xGetPtr() < mVU->prog.x86start) || (xGetPtr() >= mVU->prog.x86end)) { if ((xGetPtr() < mVU.prog.x86start) || (xGetPtr() >= mVU.prog.x86end)) {
Console.WriteLn(vuIndex ? Color_Orange : Color_Magenta, "microVU%d: Program cache limit reached.", mVU->index); Console.WriteLn(vuIndex ? Color_Orange : Color_Magenta, "microVU%d: Program cache limit reached.", mVU.index);
mVUreset(*mVU, false); mVUreset(mVU, false);
} }
mVU->cycles = mVU->totalCycles - mVU->cycles; mVU.cycles = mVU.totalCycles - mVU.cycles;
mVU->regs().cycle += mVU->cycles; mVU.regs().cycle += mVU.cycles;
cpuRegs.cycle += ((mVU->cycles < 3000) ? mVU->cycles : 3000) * EmuConfig.Speedhacks.VUCycleSteal; cpuRegs.cycle += ((mVU.cycles < 3000) ? mVU.cycles : 3000) * EmuConfig.Speedhacks.VUCycleSteal;
//static int ax = 0; ax++; //static int ax = 0; ax++;
//if (!(ax % 100000)) { //if (!(ax % 100000)) {
// for (u32 i = 0; i < (mVU->progSize / 2); i++) { // for (u32 i = 0; i < (mVU.progSize / 2); i++) {
// if (mVUcurProg.block[i]) { // if (mVUcurProg.block[i]) {
// mVUcurProg.block[i]->printInfo(i*8); // mVUcurProg.block[i]->printInfo(i*8);
// } // }

View File

@ -37,7 +37,39 @@ struct mVU_Globals {
float ITOF_4[4], ITOF_12[4], ITOF_15[4]; float ITOF_4[4], ITOF_12[4], ITOF_15[4];
}; };
extern const __aligned(32) mVU_Globals mVUglob; #define __four(val) { val, val, val, val }
static const __aligned(32) mVU_Globals mVUglob = {
__four(0x7fffffff), // absclip
__four(0x80000000), // signbit
__four(0xff7fffff), // minvals
__four(0x7f7fffff), // maxvals
__four(0x3f800000), // ONE!
__four(0x3f490fdb), // PI4!
__four(0x3f7ffff5), // T1
__four(0xbeaaa61c), // T5
__four(0x3e4c40a6), // T2
__four(0xbe0e6c63), // T3
__four(0x3dc577df), // T4
__four(0xbd6501c4), // T6
__four(0x3cb31652), // T7
__four(0xbb84d7e7), // T8
__four(0xbe2aaaa4), // S2
__four(0x3c08873e), // S3
__four(0xb94fb21f), // S4
__four(0x362e9c14), // S5
__four(0x3e7fffa8), // E1
__four(0x3d0007f4), // E2
__four(0x3b29d3ff), // E3
__four(0x3933e553), // E4
__four(0x36b63510), // E5
__four(0x353961ac), // E6
__four(16.0), // FTOI_4
__four(4096.0), // FTOI_12
__four(32768.0), // FTOI_15
__four(0.0625f), // ITOF_4
__four(0.000244140625), // ITOF_12
__four(0.000030517578125) // ITOF_15
};
static const uint _Ibit_ = 1 << 31; static const uint _Ibit_ = 1 << 31;
static const uint _Ebit_ = 1 << 30; static const uint _Ebit_ = 1 << 30;
@ -125,18 +157,10 @@ static const uint divD = 0x2080000;
typedef void __fastcall Fntype_mVUrecInst( microVU* mVU, int recPass ); typedef void __fastcall Fntype_mVUrecInst( microVU* mVU, int recPass );
typedef Fntype_mVUrecInst* Fnptr_mVUrecInst; typedef Fntype_mVUrecInst* Fnptr_mVUrecInst;
// Recursive Inline
#ifndef __LINUX__
#define __recInline __ri
#else
#define __recInline inline
#endif
// Function/Template Stuff // Function/Template Stuff
#define mVUx (vuIndex ? &microVU1 : &microVU0) #define mVUx (vuIndex ? microVU1 : microVU0)
#define mVUop(opName) static void __fastcall opName (mP) #define mVUop(opName) static void __fastcall opName (mP)
#define _mVUt template<int vuIndex> #define _mVUt template<int vuIndex>
#define _r static __recInline
// Define Passes // Define Passes
#define pass1 if (recPass == 0) #define pass1 if (recPass == 0)
@ -168,7 +192,6 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
//------------------------------------------------------------------ //------------------------------------------------------------------
// Misc Macros... // Misc Macros...
#define __four(val) { val, val, val, val }
#define mVUcurProg mVU->prog.cur[0] #define mVUcurProg mVU->prog.cur[0]
#define mVUblocks mVU->prog.cur->block #define mVUblocks mVU->prog.cur->block
#define mVUir mVU->prog.IRinfo #define mVUir mVU->prog.IRinfo