mirror of https://github.com/PCSX2/pcsx2.git
Reverted BTS due to unexpected complications, but retained a minor optimization we developed during the BTS experiment. :)
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1091 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
7dfc4c9ea2
commit
9513be5476
|
@ -76,9 +76,6 @@ int _SPR0chain()
|
||||||
{
|
{
|
||||||
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
||||||
|
|
||||||
// Clear dependent EE recompiler blocks, if necessary [needed for BTS protection system]
|
|
||||||
Cpu->Clear( spr0->madr, spr0->qwc << 2 );
|
|
||||||
|
|
||||||
// clear VU mem also!
|
// clear VU mem also!
|
||||||
TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
|
TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
|
||||||
|
|
||||||
|
@ -124,7 +121,6 @@ void _SPR0interleave()
|
||||||
{
|
{
|
||||||
// clear VU mem also!
|
// clear VU mem also!
|
||||||
TestClearVUs(spr0->madr, spr0->qwc << 2);
|
TestClearVUs(spr0->madr, spr0->qwc << 2);
|
||||||
Cpu->Clear( spr0->madr, spr0->qwc << 2 );
|
|
||||||
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
||||||
}
|
}
|
||||||
spr0->sadr += spr0->qwc * 16;
|
spr0->sadr += spr0->qwc * 16;
|
||||||
|
|
|
@ -90,18 +90,6 @@ callfunction:
|
||||||
// Interpreter Implementations of VTLB Memory Operations.
|
// Interpreter Implementations of VTLB Memory Operations.
|
||||||
// See recVTLB.cpp for the dynarec versions.
|
// See recVTLB.cpp for the dynarec versions.
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// Helper for the BTS manual protection system. Sets a bit based on the given address,
|
|
||||||
// marking that piece of PS2 memory as 'dirty.'
|
|
||||||
//
|
|
||||||
static void memwritebits(u8* ptr)
|
|
||||||
{
|
|
||||||
u32 offs=ptr-vtlbdata.alloc_base;
|
|
||||||
offs/=16;
|
|
||||||
vtlbdata.alloc_bits[offs/8] |= 1 << (offs%8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// Interpreted VTLB lookup for 8, 16, and 32 bit accesses
|
// Interpreted VTLB lookup for 8, 16, and 32 bit accesses
|
||||||
template<int DataSize,typename DataType>
|
template<int DataSize,typename DataType>
|
||||||
__forceinline DataType __fastcall MemOp_r0(u32 addr)
|
__forceinline DataType __fastcall MemOp_r0(u32 addr)
|
||||||
|
@ -168,7 +156,6 @@ __forceinline void __fastcall MemOp_w0(u32 addr, DataType data)
|
||||||
s32 ppf=addr+vmv;
|
s32 ppf=addr+vmv;
|
||||||
if (!(ppf<0))
|
if (!(ppf<0))
|
||||||
{
|
{
|
||||||
memwritebits((u8*)ppf);
|
|
||||||
*reinterpret_cast<DataType*>(ppf)=data;
|
*reinterpret_cast<DataType*>(ppf)=data;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -198,7 +185,6 @@ __forceinline void __fastcall MemOp_w1(u32 addr,const DataType* data)
|
||||||
s32 ppf=addr+vmv;
|
s32 ppf=addr+vmv;
|
||||||
if (!(ppf<0))
|
if (!(ppf<0))
|
||||||
{
|
{
|
||||||
memwritebits((u8*)ppf);
|
|
||||||
*reinterpret_cast<DataType*>(ppf)=*data;
|
*reinterpret_cast<DataType*>(ppf)=*data;
|
||||||
if (DataSize==128)
|
if (DataSize==128)
|
||||||
*reinterpret_cast<DataType*>(ppf+8)=data[1];
|
*reinterpret_cast<DataType*>(ppf+8)=data[1];
|
||||||
|
|
|
@ -81,8 +81,6 @@ namespace vtlb_private
|
||||||
|
|
||||||
struct MapData
|
struct MapData
|
||||||
{
|
{
|
||||||
u8 alloc_bits[VTLB_ALLOC_SIZE/16/8];
|
|
||||||
|
|
||||||
u8* alloc_base; //base of the memory array
|
u8* alloc_base; //base of the memory array
|
||||||
int alloc_current; //current base
|
int alloc_current; //current base
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
int LastIndex (u32 startpc) const;
|
int LastIndex (u32 startpc) const;
|
||||||
BASEBLOCKEX* GetByX86(uptr ip);
|
BASEBLOCKEX* GetByX86(uptr ip);
|
||||||
|
|
||||||
inline int Index (u32 startpc) const
|
__forceinline int Index (u32 startpc) const
|
||||||
{
|
{
|
||||||
int idx = LastIndex(startpc);
|
int idx = LastIndex(startpc);
|
||||||
// fixme: I changed the parenthesis to be unambiguous, but this needs to be checked to see if ((x or y or z) and w)
|
// fixme: I changed the parenthesis to be unambiguous, but this needs to be checked to see if ((x or y or z) and w)
|
||||||
|
@ -83,31 +83,43 @@ public:
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline BASEBLOCKEX* operator[](int idx)
|
__forceinline BASEBLOCKEX* operator[](int idx)
|
||||||
{
|
{
|
||||||
if (idx < 0 || idx >= (int)blocks.size())
|
if (idx < 0 || idx >= (int)blocks.size())
|
||||||
return 0;
|
return 0;
|
||||||
return &blocks[idx];
|
return &blocks[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline BASEBLOCKEX* Get(u32 startpc)
|
__forceinline BASEBLOCKEX* Get(u32 startpc)
|
||||||
{
|
{
|
||||||
return (*this)[Index(startpc)];
|
return (*this)[Index(startpc)];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Remove(int idx)
|
__forceinline void Remove(int idx)
|
||||||
{
|
{
|
||||||
//u32 startpc = blocks[idx].startpc;
|
//u32 startpc = blocks[idx].startpc;
|
||||||
std::pair<linkiter_t, linkiter_t> range = links.equal_range(blocks[idx].startpc);
|
std::pair<linkiter_t, linkiter_t> range = links.equal_range(blocks[idx].startpc);
|
||||||
for (linkiter_t i = range.first; i != range.second; ++i)
|
for (linkiter_t i = range.first; i != range.second; ++i)
|
||||||
*(u32*)i->second = recompiler - (i->second + 4);
|
*(u32*)i->second = recompiler - (i->second + 4);
|
||||||
|
|
||||||
|
if( IsDevBuild )
|
||||||
|
{
|
||||||
|
// Clear the first instruction to 0xcc (breakpoint), as a way to assert if some
|
||||||
|
// static jumps get left behind to this block. Note: Do not clear more than the
|
||||||
|
// first byte, since this code is called during exception handlers and event handlers
|
||||||
|
// both of which expect to be able to return to the recompiled code.
|
||||||
|
|
||||||
|
BASEBLOCKEX effu( blocks[idx] );
|
||||||
|
memset( (void*)effu.fnptr, 0xcc, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: remove links from this block?
|
// TODO: remove links from this block?
|
||||||
blocks.erase(blocks.begin() + idx);
|
blocks.erase(blocks.begin() + idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Link(u32 pc, uptr jumpptr);
|
void Link(u32 pc, uptr jumpptr);
|
||||||
|
|
||||||
inline void Reset()
|
__forceinline void Reset()
|
||||||
{
|
{
|
||||||
blocks.clear();
|
blocks.clear();
|
||||||
links.clear();
|
links.clear();
|
||||||
|
|
|
@ -751,13 +751,6 @@ void recClear(u32 addr, u32 size)
|
||||||
return;
|
return;
|
||||||
addr = HWADDR(addr);
|
addr = HWADDR(addr);
|
||||||
|
|
||||||
addr -= addr % 16; // round down.
|
|
||||||
size += 3; // round up!
|
|
||||||
size -= size % 4;
|
|
||||||
|
|
||||||
for (u32 a = addr / 16; a < addr / 16 + size / 4; a++)
|
|
||||||
vtlb_private::vtlbdata.alloc_bits[a / 8] &= ~(1 << (a & 7));
|
|
||||||
|
|
||||||
int blockidx = recBlocks.LastIndex(addr + size * 4 - 4);
|
int blockidx = recBlocks.LastIndex(addr + size * 4 - 4);
|
||||||
|
|
||||||
if (blockidx == -1)
|
if (blockidx == -1)
|
||||||
|
@ -1274,7 +1267,7 @@ void __fastcall dyna_block_discard(u32 start,u32 sz)
|
||||||
|
|
||||||
void __fastcall dyna_page_reset(u32 start,u32 sz)
|
void __fastcall dyna_page_reset(u32 start,u32 sz)
|
||||||
{
|
{
|
||||||
DevCon::WriteLn("dyna_page_reset .. start=%08X count=%d", params start,sz);
|
DevCon::WriteLn("dyna_page_reset .. start=%08X size=%d", params start,sz*4);
|
||||||
Cpu->Clear(start & ~0xfffUL, 0x400);
|
Cpu->Clear(start & ~0xfffUL, 0x400);
|
||||||
manual_counter[start >> 12]++;
|
manual_counter[start >> 12]++;
|
||||||
mmap_MarkCountedRamPage(PSM(start), start & ~0xfffUL);
|
mmap_MarkCountedRamPage(PSM(start), start & ~0xfffUL);
|
||||||
|
@ -1532,10 +1525,10 @@ StartRecomp:
|
||||||
iDumpBlock(startpc, recPtr);
|
iDumpBlock(startpc, recPtr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u32 sz=(s_nEndBlock-startpc)>>2;
|
u32 sz = (s_nEndBlock-startpc)>>2;
|
||||||
|
|
||||||
u32 inpage_ptr=HWADDR(startpc);
|
u32 inpage_ptr = HWADDR(startpc);
|
||||||
u32 inpage_sz=sz*4;
|
u32 inpage_sz = sz*4;
|
||||||
|
|
||||||
while(inpage_sz)
|
while(inpage_sz)
|
||||||
{
|
{
|
||||||
|
@ -1551,38 +1544,41 @@ StartRecomp:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using namespace vtlb_private;
|
xMOV( ecx, inpage_ptr );
|
||||||
|
xMOV( edx, pgsz / 4 );
|
||||||
MOV32ItoR(ECX, inpage_ptr);
|
//xMOV( eax, startpc ); // uncomment this to access startpc (as eax) in dyna_block_discard
|
||||||
MOV32ItoR(EDX, pgsz / 4);
|
|
||||||
|
u32 lpc = inpage_ptr;
|
||||||
u32 index = (psM - vtlbdata.alloc_base + inpage_ptr) / 16 / 32; // 16 bytes per bit, 32 bits per dword.
|
u32 stg = pgsz;
|
||||||
u32 mask = 0;
|
while(stg>0)
|
||||||
|
|
||||||
u32 start = inpage_ptr & ~15;
|
|
||||||
u32 end = inpage_ptr + pgsz;
|
|
||||||
for (u32 pos = start, bit = (start / 16) % 32; pos < end; pos += 16, bit++) {
|
|
||||||
if( bit == 32 )
|
|
||||||
{
|
|
||||||
xTEST(ptr32[&vtlbdata.alloc_bits[index]], mask);
|
|
||||||
xJNZ(dyna_block_discard);
|
|
||||||
bit = 0;
|
|
||||||
mask = 0;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
mask |= 1 << bit;
|
|
||||||
}
|
|
||||||
xTEST(ptr32[&vtlbdata.alloc_bits[index]], mask);
|
|
||||||
xJNZ(dyna_block_discard);
|
|
||||||
|
|
||||||
if (manual_counter[inpage_ptr >> 12] <= 4)
|
|
||||||
{
|
{
|
||||||
|
xCMP( ptr32[PSM(lpc)], *(u32*)PSM(lpc) );
|
||||||
|
xJNE( dyna_block_discard );
|
||||||
|
|
||||||
|
stg -= 4;
|
||||||
|
lpc += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startpc != 0x81fc0 && manual_counter[inpage_ptr >> 12] <= 4) {
|
||||||
xADD(ptr16[&manual_page[inpage_ptr >> 12]], 1);
|
xADD(ptr16[&manual_page[inpage_ptr >> 12]], 1);
|
||||||
xJC( dyna_page_reset );
|
xJC( dyna_page_reset );
|
||||||
|
|
||||||
|
// KH2 manual_counter failure -- during the intro vid a block which overlaps
|
||||||
|
// two pages causes constant recompilation. The block is very large and has two entry
|
||||||
|
// points, one around 0x01f1de1c and one around 0x01f1dfac (varies on locale). The
|
||||||
|
// former is the one that's not being cleared correctly [or at least behaves as though
|
||||||
|
// it's not being cleared correctly].
|
||||||
|
|
||||||
|
// note: clearcnt is measured per-page, not per-block!
|
||||||
|
DbgCon::WriteLn( "Manual block @ %08X : size=%3d page/offs=%05X/%03X inpgsz=%d clearcnt=%d",
|
||||||
|
params startpc, sz, inpage_ptr>>12, inpage_offs, inpage_sz, manual_counter[inpage_ptr >> 12] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbgCon::WriteLn( "Uncounted Manual block @ %08X : size=%3d page/offs=%05X/%03X inpgsz=%d",
|
||||||
|
params startpc, sz, inpage_ptr>>12, inpage_offs, pgsz, inpage_sz );
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgCon::WriteLn("Manual block @ %08X : %08X %d %d %d %d", params
|
|
||||||
startpc,inpage_ptr,pgsz,0x1000-inpage_offs,inpage_sz,sz*4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inpage_ptr += pgsz;
|
inpage_ptr += pgsz;
|
||||||
|
|
|
@ -423,14 +423,6 @@ static void _vtlb_DynGen_DirectWrite( u32 bits )
|
||||||
iMOV128_SSE(ptr[ecx],ptr[edx]);
|
iMOV128_SSE(ptr[ecx],ptr[edx]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
xSHR( ecx, 4 );
|
|
||||||
|
|
||||||
uptr alloc_base = (uptr)vtlbdata.alloc_base;
|
|
||||||
u8* bits_base = vtlbdata.alloc_bits;
|
|
||||||
bits_base -= (alloc_base>>4)/8; //in bytes
|
|
||||||
|
|
||||||
xBTS( ptr32[bits_base], ecx );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue