mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
4c8cf52c94
commit
d60718e79d
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -239,45 +239,74 @@ 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;
|
||||||
void* vmv_ptr = &vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS];
|
if( ppf >= 0 )
|
||||||
|
{
|
||||||
MOV32MtoR(EAX,(uptr)vmv_ptr);
|
MOV32ItoR( ECX, ppf );
|
||||||
MOV32ItoR(ECX,addr_const);
|
|
||||||
ADD32RtoR(ECX,EAX); // ecx=ppf
|
|
||||||
u8* _fullread = JS8(0);
|
|
||||||
|
|
||||||
_vtlb_DynGen_DirectRead( bits, false );
|
_vtlb_DynGen_DirectRead( bits, false );
|
||||||
u8* cont = JMP8(0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// has to: translate, find function, call function
|
||||||
|
u32 handler = (u8)vmv_ptr;
|
||||||
|
u32 paddr = ppf - handler + 0x80000000;
|
||||||
|
|
||||||
x86SetJ8(_fullread);
|
int szidx = 0;
|
||||||
_vtlb_DynGen_IndirectRead( bits );
|
switch( bits )
|
||||||
|
{
|
||||||
|
case 64: szidx=3; break;
|
||||||
|
case 128: szidx=4; break;
|
||||||
|
}
|
||||||
|
|
||||||
x86SetJ8(cont);
|
MOV32ItoR( ECX, paddr );
|
||||||
|
CALLFunc( (int)vtlbdata.RWFT[szidx][0][handler] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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, ppf );
|
||||||
MOV32ItoR(ECX,addr_const);
|
|
||||||
ADD32RtoR(ECX,EAX); // ecx=ppf
|
|
||||||
u8* _fullread = JS8(0);
|
|
||||||
|
|
||||||
_vtlb_DynGen_DirectRead( bits, sign );
|
_vtlb_DynGen_DirectRead( bits, sign );
|
||||||
u8* cont = JMP8(0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// has to: translate, find function, call function
|
||||||
|
u32 handler = (u8)vmv_ptr;
|
||||||
|
u32 paddr = ppf - handler + 0x80000000;
|
||||||
|
|
||||||
x86SetJ8(_fullread);
|
int szidx = 0;
|
||||||
_vtlb_DynGen_IndirectRead( bits );
|
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:
|
// perform sign extension on the result:
|
||||||
|
|
||||||
|
@ -295,8 +324,8 @@ void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const )
|
||||||
else
|
else
|
||||||
MOVZX32R16toR(EAX,EAX);
|
MOVZX32R16toR(EAX,EAX);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
x86SetJ8(cont);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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 )
|
||||||
|
{
|
||||||
void* vmv_ptr = &vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS];
|
MOV32ItoR( ECX, ppf );
|
||||||
|
|
||||||
MOV32MtoR(EAX,(uptr)vmv_ptr);
|
|
||||||
MOV32ItoR(ECX,addr_const);
|
|
||||||
ADD32RtoR(ECX,EAX); // ecx=ppf
|
|
||||||
u8* _full = JS8(0);
|
|
||||||
|
|
||||||
_vtlb_DynGen_DirectWrite( bits );
|
_vtlb_DynGen_DirectWrite( bits );
|
||||||
u8* cont = JMP8(0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// has to: translate, find function, call function
|
||||||
|
u32 handler = (u8)vmv_ptr;
|
||||||
|
u32 paddr = ppf - handler + 0x80000000;
|
||||||
|
|
||||||
x86SetJ8(_full);
|
int szidx = 0;
|
||||||
_vtlb_DynGen_IndirectWrite( bits );
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
x86SetJ8(cont);
|
MOV32ItoR( ECX, paddr );
|
||||||
|
CALLFunc( (int)vtlbdata.RWFT[szidx][1][handler] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue