mirror of https://github.com/PCSX2/pcsx2.git
microVU: Minor changes/cleanups
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4412 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
7edaa221b8
commit
ed35dcac17
|
@ -82,106 +82,114 @@ const __aligned(32) mVU_Globals mVUglob = {
|
|||
static __fi void mVUthrowHardwareDeficiency(const wxChar* extFail, int vuIndex) {
|
||||
throw Exception::HardwareDeficiency()
|
||||
.SetDiagMsg(pxsFmt(L"microVU%d recompiler init failed: %s is not available.", vuIndex, extFail))
|
||||
.SetUserMsg(pxsFmt(_("%s Extensions not found. microVU requires a host CPU with MMX, SSE, and SSE2 extensions."), extFail ));
|
||||
.SetUserMsg(pxsFmt(_("%s Extensions not found. microVU requires a host CPU with MMX, SSE, and SSE2 extensions."), extFail));
|
||||
}
|
||||
|
||||
void microVU::reserveCache()
|
||||
{
|
||||
cache_reserve = new RecompiledCodeReserve( pxsFmt("Micro VU%u Recompiler Cache", index) );
|
||||
cache_reserve->SetProfilerName( pxsFmt("mVU%urec", index) );
|
||||
|
||||
cache = index ?
|
||||
(u8*)cache_reserve->Reserve( cacheSize * _1mb, HostMemoryMap::mVU1rec ) :
|
||||
(u8*)cache_reserve->Reserve( cacheSize * _1mb, HostMemoryMap::mVU0rec );
|
||||
void mVUreserveCache(microVU& mVU) {
|
||||
|
||||
cache_reserve->ThrowIfNotOk();
|
||||
mVU.cache_reserve = new RecompiledCodeReserve(pxsFmt("Micro VU%u Recompiler Cache", mVU.index));
|
||||
mVU.cache_reserve->SetProfilerName(pxsFmt("mVU%urec", mVU.index));
|
||||
|
||||
mVU.cache = mVU.index ?
|
||||
(u8*)mVU.cache_reserve->Reserve(mVU.cacheSize * _1mb, HostMemoryMap::mVU1rec):
|
||||
(u8*)mVU.cache_reserve->Reserve(mVU.cacheSize * _1mb, HostMemoryMap::mVU0rec);
|
||||
|
||||
mVU.cache_reserve->ThrowIfNotOk();
|
||||
}
|
||||
|
||||
// Only run this once per VU! ;)
|
||||
void microVU::init(uint vuIndex) {
|
||||
void mVUinit(microVU& mVU, uint vuIndex) {
|
||||
|
||||
if(!x86caps.hasMultimediaExtensions) mVUthrowHardwareDeficiency( L"MMX", vuIndex );
|
||||
if(!x86caps.hasStreamingSIMDExtensions) mVUthrowHardwareDeficiency( L"SSE", vuIndex );
|
||||
if(!x86caps.hasStreamingSIMD2Extensions) mVUthrowHardwareDeficiency( L"SSE2", vuIndex );
|
||||
if(!x86caps.hasMultimediaExtensions) mVUthrowHardwareDeficiency( L"MMX", vuIndex );
|
||||
if(!x86caps.hasStreamingSIMDExtensions) mVUthrowHardwareDeficiency( L"SSE", vuIndex );
|
||||
if(!x86caps.hasStreamingSIMD2Extensions) mVUthrowHardwareDeficiency( L"SSE2", vuIndex );
|
||||
|
||||
memzero(prog);
|
||||
memzero(mVU.prog);
|
||||
|
||||
index = vuIndex;
|
||||
cop2 = 0;
|
||||
vuMemSize = (index ? 0x4000 : 0x1000);
|
||||
microMemSize = (index ? 0x4000 : 0x1000);
|
||||
progSize = (index ? 0x4000 : 0x1000) / 4;
|
||||
progMemMask = progSize-1;
|
||||
mVU.index = vuIndex;
|
||||
mVU.cop2 = 0;
|
||||
mVU.vuMemSize = (mVU.index ? 0x4000 : 0x1000);
|
||||
mVU.microMemSize = (mVU.index ? 0x4000 : 0x1000);
|
||||
mVU.progSize = (mVU.index ? 0x4000 : 0x1000) / 4;
|
||||
mVU.progMemMask = mVU.progSize-1;
|
||||
mVU.cacheSize = vuIndex ? mVU1cacheReserve : mVU0cacheReserve;
|
||||
mVU.cache = NULL;
|
||||
mVU.dispCache = NULL;
|
||||
mVU.startFunct = NULL;
|
||||
mVU.exitFunct = NULL;
|
||||
|
||||
reserveCache();
|
||||
mVUreserveCache(mVU);
|
||||
|
||||
dispCache = SysMmapEx(0, mVUdispCacheSize, 0, (index ? "Micro VU1 Dispatcher" : "Micro VU0 Dispatcher"));
|
||||
if (!dispCache) throw Exception::OutOfMemory( index ? L"Micro VU1 Dispatcher" : L"Micro VU0 Dispatcher" );
|
||||
memset(dispCache, 0xcc, mVUdispCacheSize);
|
||||
mVU.dispCache = SysMmapEx(0, mVUdispCacheSize, 0,(mVU.index ? "Micro VU1 Dispatcher" : "Micro VU0 Dispatcher"));
|
||||
if (!mVU.dispCache) throw Exception::OutOfMemory (mVU.index ? L"Micro VU1 Dispatcher" : L"Micro VU0 Dispatcher");
|
||||
memset(mVU.dispCache, 0xcc, mVUdispCacheSize);
|
||||
|
||||
regAlloc = new microRegAlloc(index);
|
||||
mVU.regAlloc = new microRegAlloc(mVU.index);
|
||||
}
|
||||
|
||||
// Resets Rec Data
|
||||
void microVU::reset() {
|
||||
void mVUreset(microVU& mVU, bool resetReserve) {
|
||||
|
||||
x86SetPtr(dispCache);
|
||||
mVUdispatcherA(this);
|
||||
mVUdispatcherB(this);
|
||||
mVUdispatcherC(this);
|
||||
mVUdispatcherD(this);
|
||||
// Restore reserve to uncommitted state
|
||||
if (resetReserve) mVU.cache_reserve->Reset();
|
||||
|
||||
x86SetPtr(mVU.dispCache);
|
||||
mVUdispatcherA(&mVU);
|
||||
mVUdispatcherB(&mVU);
|
||||
mVUdispatcherC(&mVU);
|
||||
mVUdispatcherD(&mVU);
|
||||
mVUemitSearch();
|
||||
|
||||
// Clear All Program Data
|
||||
//memset(&prog, 0, sizeof(prog));
|
||||
memset(&prog.lpState, 0, sizeof(prog.lpState));
|
||||
//memset(&mVU.prog, 0, sizeof(mVU.prog));
|
||||
memset(&mVU.prog.lpState, 0, sizeof(mVU.prog.lpState));
|
||||
|
||||
// Program Variables
|
||||
prog.cleared = 1;
|
||||
prog.isSame = -1;
|
||||
prog.cur = NULL;
|
||||
prog.total = 0;
|
||||
prog.curFrame = 0;
|
||||
mVU.prog.cleared = 1;
|
||||
mVU.prog.isSame = -1;
|
||||
mVU.prog.cur = NULL;
|
||||
mVU.prog.total = 0;
|
||||
mVU.prog.curFrame = 0;
|
||||
|
||||
// Setup Dynarec Cache Limits for Each Program
|
||||
u8* z = cache;
|
||||
prog.x86start = z;
|
||||
prog.x86ptr = z;
|
||||
prog.x86end = z + ((cacheSize - mVUcacheSafeZone) * _1mb);
|
||||
u8* z = mVU.cache;
|
||||
mVU.prog.x86start = z;
|
||||
mVU.prog.x86ptr = z;
|
||||
mVU.prog.x86end = z + ((mVU.cacheSize - mVUcacheSafeZone) * _1mb);
|
||||
|
||||
for (u32 i = 0; i < (progSize / 2); i++) {
|
||||
if(!prog.prog[i]) {
|
||||
prog.prog[i] = new deque<microProgram*>();
|
||||
for(u32 i = 0; i < (mVU.progSize / 2); i++) {
|
||||
if(!mVU.prog.prog[i]) {
|
||||
mVU.prog.prog[i] = new deque<microProgram*>();
|
||||
continue;
|
||||
}
|
||||
|
||||
deque<microProgram*>::iterator it(prog.prog[i]->begin());
|
||||
for ( ; it != prog.prog[i]->end(); ++it) {
|
||||
if (index) mVUdeleteProg<1>(it[0]);
|
||||
else mVUdeleteProg<0>(it[0]);
|
||||
deque<microProgram*>::iterator it(mVU.prog.prog[i]->begin());
|
||||
for ( ; it != mVU.prog.prog[i]->end(); ++it) {
|
||||
if (mVU.index) mVUdeleteProg<1>(it[0]);
|
||||
else mVUdeleteProg<0>(it[0]);
|
||||
}
|
||||
prog.prog[i]->clear();
|
||||
prog.quick[i].block = NULL;
|
||||
prog.quick[i].prog = NULL;
|
||||
mVU.prog.prog[i]->clear();
|
||||
mVU.prog.quick[i].block = NULL;
|
||||
mVU.prog.quick[i].prog = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Free Allocated Resources
|
||||
void microVU::close() {
|
||||
void mVUclose(microVU& mVU) {
|
||||
|
||||
safe_delete(cache_reserve);
|
||||
safe_delete(mVU.cache_reserve);
|
||||
|
||||
SafeSysMunmap(dispCache, mVUdispCacheSize);
|
||||
SafeSysMunmap(mVU.dispCache, mVUdispCacheSize);
|
||||
|
||||
// Delete Programs and Block Managers
|
||||
for (u32 i = 0; i < (progSize / 2); i++) {
|
||||
if (!prog.prog[i]) continue;
|
||||
deque<microProgram*>::iterator it(prog.prog[i]->begin());
|
||||
for ( ; it != prog.prog[i]->end(); ++it) {
|
||||
if (index) mVUdeleteProg<1>(it[0]);
|
||||
else mVUdeleteProg<0>(it[0]);
|
||||
for (u32 i = 0; i < (mVU.progSize / 2); i++) {
|
||||
if (!mVU.prog.prog[i]) continue;
|
||||
deque<microProgram*>::iterator it(mVU.prog.prog[i]->begin());
|
||||
for ( ; it != mVU.prog.prog[i]->end(); ++it) {
|
||||
if (mVU.index) mVUdeleteProg<1>(it[0]);
|
||||
else mVUdeleteProg<0>(it[0]);
|
||||
}
|
||||
safe_delete(prog.prog[i]);
|
||||
safe_delete(mVU.prog.prog[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,29 +355,29 @@ void recMicroVU1::Vsync() throw() { mVUvsyncUpdate(µVU1); }
|
|||
|
||||
void recMicroVU0::Reserve() {
|
||||
if (AtomicExchange(m_Reserved, 1) == 0)
|
||||
microVU0.init(0);
|
||||
mVUinit(microVU0, 0);
|
||||
}
|
||||
void recMicroVU1::Reserve() {
|
||||
if (AtomicExchange(m_Reserved, 1) == 0)
|
||||
microVU1.init(1);
|
||||
mVUinit(microVU1, 1);
|
||||
}
|
||||
|
||||
void recMicroVU0::Shutdown() throw() {
|
||||
if (AtomicExchange(m_Reserved, 0) == 1)
|
||||
microVU0.close();
|
||||
mVUclose(microVU0);
|
||||
}
|
||||
void recMicroVU1::Shutdown() throw() {
|
||||
if (AtomicExchange(m_Reserved, 0) == 1)
|
||||
microVU1.close();
|
||||
mVUclose(microVU1);
|
||||
}
|
||||
|
||||
void recMicroVU0::Reset() {
|
||||
if(!pxAssertDev(m_Reserved, "MicroVU0 CPU Provider has not been reserved prior to reset!")) return;
|
||||
microVU0.reset();
|
||||
mVUreset(microVU0, true);
|
||||
}
|
||||
void recMicroVU1::Reset() {
|
||||
if(!pxAssertDev(m_Reserved, "MicroVU1 CPU Provider has not been reserved prior to reset!")) return;
|
||||
microVU1.reset();
|
||||
mVUreset(microVU1, true);
|
||||
}
|
||||
|
||||
void recMicroVU0::Execute(u32 cycles) {
|
||||
|
@ -405,13 +413,17 @@ uint recMicroVU1::GetCacheReserve() const {
|
|||
return microVU1.cacheSize;
|
||||
}
|
||||
|
||||
void recMicroVU0::SetCacheReserve( uint reserveInMegs ) const {
|
||||
DevCon.WriteLn("microVU0: Upping cache size [%dmb]", reserveInMegs);
|
||||
microVU0.cacheSize = min(reserveInMegs, mVUcacheMaxReserve);
|
||||
void recMicroVU0::SetCacheReserve(uint reserveInMegs) const {
|
||||
DevCon.WriteLn("microVU0: Changing cache size [%dmb]", reserveInMegs);
|
||||
microVU0.cacheSize = min(reserveInMegs, mVU0cacheReserve);
|
||||
safe_delete(microVU0.cache_reserve); // I assume this unmaps the memory
|
||||
mVUreserveCache(microVU0); // Need rec-reset after this
|
||||
}
|
||||
void recMicroVU1::SetCacheReserve( uint reserveInMegs ) const {
|
||||
DevCon.WriteLn("microVU1: Upping cache size [%dmb]", reserveInMegs);
|
||||
microVU1.cacheSize = min(reserveInMegs, mVUcacheMaxReserve);
|
||||
void recMicroVU1::SetCacheReserve(uint reserveInMegs) const {
|
||||
DevCon.WriteLn("microVU1: Changing cache size [%dmb]", reserveInMegs);
|
||||
microVU1.cacheSize = min(reserveInMegs, mVU1cacheReserve);
|
||||
safe_delete(microVU1.cache_reserve); // I assume this unmaps the memory
|
||||
mVUreserveCache(microVU1); // Need rec-reset after this
|
||||
}
|
||||
|
||||
void recMicroVU1::ResumeXGkick() {
|
||||
|
|
|
@ -162,10 +162,10 @@ struct microProgManager {
|
|||
microRegInfo lpState; // Pipeline state from where program left off (useful for continuing execution)
|
||||
};
|
||||
|
||||
static const uint mVUdispCacheSize = __pagesize; // Dispatcher Cache Size (in bytes)
|
||||
static const uint mVUcacheSafeZone = 3; // Safe-Zone for program recompilation (in megabytes)
|
||||
static const uint mVUcacheInitReserve = 64; // Initial Reserve Cache Size (in megabytes)
|
||||
static const uint mVUcacheMaxReserve = 128; // Max Reserve Cache Size (in megabytes)
|
||||
static const uint mVUdispCacheSize = __pagesize; // Dispatcher Cache Size (in bytes)
|
||||
static const uint mVUcacheSafeZone = 3; // Safe-Zone for program recompilation (in megabytes)
|
||||
static const uint mVU0cacheReserve = 64; // mVU0 Reserve Cache Size (in megabytes)
|
||||
static const uint mVU1cacheReserve = 64; // mVU1 Reserve Cache Size (in megabytes)
|
||||
|
||||
struct microVU {
|
||||
|
||||
|
@ -241,20 +241,6 @@ struct microVU {
|
|||
pxAssumeDev((prog.IRinfo.curPC & 1) == 0, "microVU recompiler: Upper instructions cannot have valid branch addresses.");
|
||||
return (((prog.IRinfo.curPC + 4) + (Imm11() * 2)) & progMemMask) * 4;
|
||||
}
|
||||
|
||||
microVU()
|
||||
{
|
||||
cacheSize = mVUcacheInitReserve;
|
||||
cache = NULL;
|
||||
dispCache = NULL;
|
||||
startFunct = NULL;
|
||||
exitFunct = NULL;
|
||||
}
|
||||
|
||||
void reserveCache();
|
||||
void init(uint vuIndex);
|
||||
void reset();
|
||||
void close();
|
||||
};
|
||||
|
||||
// microVU rec structs
|
||||
|
|
|
@ -191,7 +191,7 @@ _mVUt void mVUcleanUp() {
|
|||
|
||||
if ((xGetPtr() < mVU->prog.x86start) || (xGetPtr() >= mVU->prog.x86end)) {
|
||||
Console.WriteLn(vuIndex ? Color_Orange : Color_Magenta, "microVU%d: Program cache limit reached.", mVU->index);
|
||||
mVU->reset();
|
||||
mVUreset(*mVU, false);
|
||||
}
|
||||
|
||||
mVU->cycles = mVU->totalCycles - mVU->cycles;
|
||||
|
|
|
@ -36,20 +36,16 @@ static void mVUupdateFlags(mV, const xmm& reg, const xmm& regT1in = xEmptyReg, c
|
|||
const xmm& regT1 = regT1b ? mVU->regAlloc->allocReg() : regT1in;
|
||||
|
||||
xmm regT2 = reg;
|
||||
if ((mFLAG.doFlag && !(_XYZW_SS && modXYZW)))
|
||||
{
|
||||
if ((mFLAG.doFlag && !(_XYZW_SS && modXYZW))) {
|
||||
regT2 = regT2in;
|
||||
if (regT2.IsEmpty())
|
||||
{
|
||||
if (regT2.IsEmpty()) {
|
||||
regT2 = mVU->regAlloc->allocReg();
|
||||
regT2b = true;
|
||||
}
|
||||
|
||||
xPSHUF.D(regT2, reg, 0x1B); // Flip wzyx to xyzw
|
||||
}
|
||||
else regT2 = reg;
|
||||
|
||||
|
||||
if (sFLAG.doFlag) {
|
||||
mVUallocSFLAGa(sReg, sFLAG.lastWrite); // Get Prev Status Flag
|
||||
if (sFLAG.doNonSticky) xAND(sReg, 0xfffc00ff); // Clear O,U,S,Z flags
|
||||
|
|
Loading…
Reference in New Issue