More vtlb optimizations: Switched over to full const resolution of the TLB, and added a shortcut for the INTC_STAT register (replacing the one rama added to HwRead.cpp a couple days ago).

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@884 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-04-02 14:50:19 +00:00
parent 4c8cf52c94
commit d60718e79d
2 changed files with 105 additions and 70 deletions

View File

@ -214,6 +214,12 @@ static __forceinline mem32_t __hwRead32_page_0F( u32 mem, bool intchack )
switch( mem ) switch( mem )
{ {
case 0xf000:
if( intchack ) IntCHackCheck();
// This one is checked alot, so leave it commented out unless you love 600 meg logfiles.
//HW_LOG("INTC_STAT Read 32bit %x", psHu32(0xf010));
break;
case 0xf010: case 0xf010:
HW_LOG("INTC_MASK Read32, value=0x%x", psHu32(INTC_MASK)); HW_LOG("INTC_MASK Read32, value=0x%x", psHu32(INTC_MASK));
break; break;
@ -255,22 +261,12 @@ static __forceinline mem32_t __hwRead32_page_0F( u32 mem, bool intchack )
} }
} }
return 0; return 0;
case 0xf000:
//Put this back on top in case you remove the shortcut for intc_stat register (see below function) (rama).
if( intchack ) IntCHackCheck();
// This one is checked alot, so leave it commented out unless you love 600 meg logfiles.
//HW_LOG("INTC_STAT Read 32bit %x", psHu32(0xf010));
break;
} }
return *((u32*)&PS2MEM_HW[mem]); return *((u32*)&PS2MEM_HW[mem]);
} }
mem32_t __fastcall hwRead32_page_0F(u32 mem) mem32_t __fastcall hwRead32_page_0F(u32 mem)
{ {
if (mem == 0x1000f000) //shortcut for intc_stat
return *((u32*)&PS2MEM_HW[0xF000]);
return __hwRead32_page_0F( mem, false ); return __hwRead32_page_0F( mem, false );
} }

View File

@ -239,64 +239,93 @@ void vtlb_DynGenRead32(u32 bits, bool sign)
x86SetJ8(cont); x86SetJ8(cont);
} }
//
// TLB lookup is performed in const, with the assumption that the COP0/TLB will clear the
// recompiler if the TLB is changed.
void vtlb_DynGenRead64_Const( u32 bits, u32 addr_const ) void vtlb_DynGenRead64_Const( u32 bits, u32 addr_const )
{ {
jASSUME( bits == 64 || bits == 128 ); u32 vmv_ptr = vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS];
s32 ppf = addr_const + vmv_ptr;
if( ppf >= 0 )
{
MOV32ItoR( ECX, ppf );
_vtlb_DynGen_DirectRead( bits, false );
}
else
{
// has to: translate, find function, call function
u32 handler = (u8)vmv_ptr;
u32 paddr = ppf - handler + 0x80000000;
void* vmv_ptr = &vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS]; int szidx = 0;
switch( bits )
{
case 64: szidx=3; break;
case 128: szidx=4; break;
}
MOV32MtoR(EAX,(uptr)vmv_ptr); MOV32ItoR( ECX, paddr );
MOV32ItoR(ECX,addr_const); CALLFunc( (int)vtlbdata.RWFT[szidx][0][handler] );
ADD32RtoR(ECX,EAX); // ecx=ppf }
u8* _fullread = JS8(0);
_vtlb_DynGen_DirectRead( bits, false );
u8* cont = JMP8(0);
x86SetJ8(_fullread);
_vtlb_DynGen_IndirectRead( bits );
x86SetJ8(cont);
} }
// Recompiled input registers: // Recompiled input registers:
// ecx - source address to read from // ecx - source address to read from
// Returns read value in eax. // Returns read value in eax.
//
// TLB lookup is performed in const, with the assumption that the COP0/TLB will clear the
// recompiler if the TLB is changed.
void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const ) void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const )
{ {
jASSUME( bits <= 32 ); u32 vmv_ptr = vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS];
s32 ppf = addr_const + vmv_ptr;
void* vmv_ptr = &vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS]; if( ppf >= 0 )
MOV32MtoR(EAX,(uptr)vmv_ptr);
MOV32ItoR(ECX,addr_const);
ADD32RtoR(ECX,EAX); // ecx=ppf
u8* _fullread = JS8(0);
_vtlb_DynGen_DirectRead( bits, sign );
u8* cont = JMP8(0);
x86SetJ8(_fullread);
_vtlb_DynGen_IndirectRead( bits );
// perform sign extension on the result:
if( bits==8 )
{ {
if( sign ) MOV32ItoR( ECX, ppf );
MOVSX32R8toR(EAX,EAX); _vtlb_DynGen_DirectRead( bits, sign );
else
MOVZX32R8toR(EAX,EAX);
} }
else if( bits==16 ) else
{ {
if( sign ) // has to: translate, find function, call function
MOVSX32R16toR(EAX,EAX); u32 handler = (u8)vmv_ptr;
else u32 paddr = ppf - handler + 0x80000000;
MOVZX32R16toR(EAX,EAX);
}
x86SetJ8(cont); int szidx = 0;
switch( bits )
{
case 8: szidx=0; break;
case 16: szidx=1; break;
case 32: szidx=2; break;
}
// Shortcut for the INTC_STAT register, which many games like to spin on heavily.
if( (bits == 32) && !CHECK_INTC_STAT_HACK && (paddr == INTC_STAT) )
{
MOV32MtoR( EAX, (uptr)&psHu32( INTC_STAT ) );
}
else
{
MOV32ItoR( ECX, paddr );
CALLFunc( (int)vtlbdata.RWFT[szidx][0][handler] );
// perform sign extension on the result:
if( bits==8 )
{
if( sign )
MOVSX32R8toR(EAX,EAX);
else
MOVZX32R8toR(EAX,EAX);
}
else if( bits==16 )
{
if( sign )
MOVSX32R16toR(EAX,EAX);
else
MOVZX32R16toR(EAX,EAX);
}
}
}
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -392,24 +421,34 @@ void vtlb_DynGenWrite(u32 sz)
// Generates code for a store instruction, where the address is a known constant. // Generates code for a store instruction, where the address is a known constant.
// TLB lookup is performed in const, with the assumption that the COP0/TLB will clear the
// recompiler if the TLB is changed.
void vtlb_DynGenWrite_Const( u32 bits, u32 addr_const ) void vtlb_DynGenWrite_Const( u32 bits, u32 addr_const )
{ {
// Important: It's not technically safe to do a const lookup of the VTLB here, since u32 vmv_ptr = vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS];
// the VTLB could feasibly be remapped by other recompiled code at any time. s32 ppf = addr_const + vmv_ptr;
// So we're limited in exactly how much we can pre-calcuate. if( ppf >= 0 )
{
MOV32ItoR( ECX, ppf );
_vtlb_DynGen_DirectWrite( bits );
}
else
{
// has to: translate, find function, call function
u32 handler = (u8)vmv_ptr;
u32 paddr = ppf - handler + 0x80000000;
void* vmv_ptr = &vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS]; int szidx = 0;
switch( bits )
{
case 8: szidx=0; break;
case 16: szidx=1; break;
case 32: szidx=2; break;
case 64: szidx=3; break;
case 128: szidx=4; break;
}
MOV32MtoR(EAX,(uptr)vmv_ptr); MOV32ItoR( ECX, paddr );
MOV32ItoR(ECX,addr_const); CALLFunc( (int)vtlbdata.RWFT[szidx][1][handler] );
ADD32RtoR(ECX,EAX); // ecx=ppf }
u8* _full = JS8(0);
_vtlb_DynGen_DirectWrite( bits );
u8* cont = JMP8(0);
x86SetJ8(_full);
_vtlb_DynGen_IndirectWrite( bits );
x86SetJ8(cont);
} }