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:
Jake.Stine 2009-04-30 01:16:25 +00:00
parent 7dfc4c9ea2
commit 9513be5476
6 changed files with 51 additions and 71 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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