mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
6c8dc7bcb6
commit
c4d8356a1b
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -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 ? µVU1 : µVU0)
|
#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
|
||||||
|
|
Loading…
Reference in New Issue