Optimized vtlb direct path memory operations using some crafty asm code. Expect 2-3% speedups in most things, and perhaps more in some FMVs.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1137 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-05-06 02:15:43 +00:00
parent 6a075aca03
commit 1cf028ccf5
15 changed files with 344 additions and 277 deletions

View File

@ -56,7 +56,7 @@ void MapTLB(int i)
if (tlb[i].S)
{
DevCon::WriteLn("OMG SPRAM MAPPING %08X %08X\n",params tlb[i].VPN2,tlb[i].Mask);
vtlb_VMapBuffer(tlb[i].VPN2,psS,0x4000);
vtlb_VMapBuffer(tlb[i].VPN2, psS, 0x4000);
}
if (tlb[i].VPN2 == 0x70000000) return; //uh uhh right ...

View File

@ -384,8 +384,8 @@ void hwReset();
void hwShutdown();
// hw read functions
extern u8 hwRead8 (u32 mem);
extern u16 hwRead16(u32 mem);
extern mem8_t hwRead8 (u32 mem);
extern mem16_t hwRead16(u32 mem);
extern mem32_t __fastcall hwRead32_page_00(u32 mem);
extern mem32_t __fastcall hwRead32_page_01(u32 mem);
@ -409,14 +409,14 @@ extern void __fastcall hwRead128_generic(u32 mem, mem128_t *out);
extern void hwWrite8 (u32 mem, u8 value);
extern void hwWrite16(u32 mem, u16 value);
extern void __fastcall hwWrite32_page_00( u32 mem, u32 value );
extern void __fastcall hwWrite32_page_01( u32 mem, u32 value );
extern void __fastcall hwWrite32_page_02( u32 mem, u32 value );
extern void __fastcall hwWrite32_page_03( u32 mem, u32 value );
extern void __fastcall hwWrite32_page_0B( u32 mem, u32 value );
extern void __fastcall hwWrite32_page_0E( u32 mem, u32 value );
extern void __fastcall hwWrite32_page_0F( u32 mem, u32 value );
extern void __fastcall hwWrite32_generic( u32 mem, u32 value );
extern void __fastcall hwWrite32_page_00( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_01( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_02( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_03( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_0B( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_0E( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_0F( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_generic( u32 mem, mem32_t value );
extern void __fastcall hwWrite64_page_02( u32 mem, const mem64_t* srcval );
extern void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval );

View File

@ -52,7 +52,7 @@ static __forceinline void IntCHackCheck()
/////////////////////////////////////////////////////////////////////////
// Hardware READ 8 bit
__forceinline u8 hwRead8(u32 mem)
__forceinline mem8_t hwRead8(u32 mem)
{
u8 ret;
@ -117,7 +117,7 @@ __forceinline u8 hwRead8(u32 mem)
/////////////////////////////////////////////////////////////////////////
// Hardware READ 16 bit
__forceinline u16 hwRead16(u32 mem)
__forceinline mem16_t hwRead16(u32 mem)
{
u16 ret;

View File

@ -98,39 +98,39 @@ void psxRecMemWrite32();
namespace IopMemory
{
// Sif functions not made yet (will for future Iop improvements):
extern u8 __fastcall SifRead8( u32 iopaddr );
extern u16 __fastcall SifRead16( u32 iopaddr );
extern u32 __fastcall SifRead32( u32 iopaddr );
extern mem8_t __fastcall SifRead8( u32 iopaddr );
extern mem16_t __fastcall SifRead16( u32 iopaddr );
extern mem32_t __fastcall SifRead32( u32 iopaddr );
extern void __fastcall SifWrite8( u32 iopaddr, u8 data );
extern void __fastcall SifWrite16( u32 iopaddr, u16 data );
extern void __fastcall SifWrite32( u32 iopaddr, u32 data );
extern void __fastcall SifWrite8( u32 iopaddr, mem8_t data );
extern void __fastcall SifWrite16( u32 iopaddr, mem16_t data );
extern void __fastcall SifWrite32( u32 iopaddr, mem32_t data );
extern u8 __fastcall iopHwRead8_generic( u32 addr );
extern u16 __fastcall iopHwRead16_generic( u32 addr );
extern u32 __fastcall iopHwRead32_generic( u32 addr );
extern void __fastcall iopHwWrite8_generic( u32 addr, u8 val );
extern void __fastcall iopHwWrite16_generic( u32 addr, u16 val );
extern void __fastcall iopHwWrite32_generic( u32 addr, u32 val );
extern mem8_t __fastcall iopHwRead8_generic( u32 addr );
extern mem16_t __fastcall iopHwRead16_generic( u32 addr );
extern mem32_t __fastcall iopHwRead32_generic( u32 addr );
extern void __fastcall iopHwWrite8_generic( u32 addr, mem8_t val );
extern void __fastcall iopHwWrite16_generic( u32 addr, mem16_t val );
extern void __fastcall iopHwWrite32_generic( u32 addr, mem32_t val );
extern u8 __fastcall iopHwRead8_Page1( u32 iopaddr );
extern u8 __fastcall iopHwRead8_Page3( u32 iopaddr );
extern u8 __fastcall iopHwRead8_Page8( u32 iopaddr );
extern u16 __fastcall iopHwRead16_Page1( u32 iopaddr );
extern u16 __fastcall iopHwRead16_Page3( u32 iopaddr );
extern u16 __fastcall iopHwRead16_Page8( u32 iopaddr );
extern u32 __fastcall iopHwRead32_Page1( u32 iopaddr );
extern u32 __fastcall iopHwRead32_Page3( u32 iopaddr );
extern u32 __fastcall iopHwRead32_Page8( u32 iopaddr );
extern mem8_t __fastcall iopHwRead8_Page1( u32 iopaddr );
extern mem8_t __fastcall iopHwRead8_Page3( u32 iopaddr );
extern mem8_t __fastcall iopHwRead8_Page8( u32 iopaddr );
extern mem16_t __fastcall iopHwRead16_Page1( u32 iopaddr );
extern mem16_t __fastcall iopHwRead16_Page3( u32 iopaddr );
extern mem16_t __fastcall iopHwRead16_Page8( u32 iopaddr );
extern mem32_t __fastcall iopHwRead32_Page1( u32 iopaddr );
extern mem32_t __fastcall iopHwRead32_Page3( u32 iopaddr );
extern mem32_t __fastcall iopHwRead32_Page8( u32 iopaddr );
extern void __fastcall iopHwWrite8_Page1( u32 iopaddr, u8 data );
extern void __fastcall iopHwWrite8_Page3( u32 iopaddr, u8 data );
extern void __fastcall iopHwWrite8_Page8( u32 iopaddr, u8 data );
extern void __fastcall iopHwWrite16_Page1( u32 iopaddr, u16 data );
extern void __fastcall iopHwWrite16_Page3( u32 iopaddr, u16 data );
extern void __fastcall iopHwWrite16_Page8( u32 iopaddr, u16 data );
extern void __fastcall iopHwWrite32_Page1( u32 iopaddr, u32 data );
extern void __fastcall iopHwWrite32_Page3( u32 iopaddr, u32 data );
extern void __fastcall iopHwWrite32_Page8( u32 iopaddr, u32 data );
extern void __fastcall iopHwWrite8_Page1( u32 iopaddr, mem8_t data );
extern void __fastcall iopHwWrite8_Page3( u32 iopaddr, mem8_t data );
extern void __fastcall iopHwWrite8_Page8( u32 iopaddr, mem8_t data );
extern void __fastcall iopHwWrite16_Page1( u32 iopaddr, mem16_t data );
extern void __fastcall iopHwWrite16_Page3( u32 iopaddr, mem16_t data );
extern void __fastcall iopHwWrite16_Page8( u32 iopaddr, mem16_t data );
extern void __fastcall iopHwWrite32_Page1( u32 iopaddr, mem32_t data );
extern void __fastcall iopHwWrite32_Page3( u32 iopaddr, mem32_t data );
extern void __fastcall iopHwWrite32_Page8( u32 iopaddr, mem32_t data );
}

View File

@ -347,7 +347,7 @@ void __fastcall _ext_memRead128(u32 mem, mem128_t *out)
}
template<int p>
void __fastcall _ext_memWrite8 (u32 mem, u8 value)
void __fastcall _ext_memWrite8 (u32 mem, mem8_t value)
{
switch (p) {
case 1: // hwm
@ -367,7 +367,7 @@ void __fastcall _ext_memWrite8 (u32 mem, u8 value)
cpuTlbMissW(mem, cpuRegs.branch);
}
template<int p>
void __fastcall _ext_memWrite16(u32 mem, u16 value)
void __fastcall _ext_memWrite16(u32 mem, mem16_t value)
{
switch (p) {
case 1: // hwm
@ -392,7 +392,7 @@ void __fastcall _ext_memWrite16(u32 mem, u16 value)
}
template<int p>
void __fastcall _ext_memWrite32(u32 mem, u32 value)
void __fastcall _ext_memWrite32(u32 mem, mem32_t value)
{
switch (p) {
case 6: // gsm
@ -407,7 +407,7 @@ void __fastcall _ext_memWrite32(u32 mem, u32 value)
}
template<int p>
void __fastcall _ext_memWrite64(u32 mem, const u64* value)
void __fastcall _ext_memWrite64(u32 mem, const mem64_t* value)
{
/*switch (p) {
@ -423,7 +423,7 @@ void __fastcall _ext_memWrite64(u32 mem, const u64* value)
}
template<int p>
void __fastcall _ext_memWrite128(u32 mem, const u64 *value)
void __fastcall _ext_memWrite128(u32 mem, const mem128_t *value)
{
/*switch (p) {
//case 1: // hwm

View File

@ -25,14 +25,14 @@ using namespace Internal;
//////////////////////////////////////////////////////////////////////////////////////////
//
u8 __fastcall iopHwRead8_Page1( u32 addr )
mem8_t __fastcall iopHwRead8_Page1( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f801xxx:
jASSUME( (addr >> 12) == 0x1f801 );
u32 masked_addr = addr & 0x0fff;
u8 ret; // using a return var can be helpful in debugging.
mem8_t ret; // using a return var can be helpful in debugging.
switch( masked_addr )
{
mcase(HW_SIO_DATA): ret = sioRead8(); break;
@ -71,42 +71,42 @@ u8 __fastcall iopHwRead8_Page1( u32 addr )
return ret;
}
PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u8>( addr ), addr, ret );
PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<mem8_t>( addr ), addr, ret );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u8 __fastcall iopHwRead8_Page3( u32 addr )
mem8_t __fastcall iopHwRead8_Page3( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
u8 ret;
mem8_t ret;
if( addr == 0x1f803100 ) // PS/EE/IOP conf related
ret = 0x10; // Dram 2M
else
ret = psxHu8( addr );
PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u8>( addr ), addr, psxHu8(addr) );
PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<mem8_t>( addr ), addr, psxHu8(addr) );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u8 __fastcall iopHwRead8_Page8( u32 addr )
mem8_t __fastcall iopHwRead8_Page8( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
u8 ret;
mem8_t ret;
if( addr == HW_SIO2_FIFO )
ret = sio2_fifoOut();//sio2 serial data feed/fifo_out
else
ret = psxHu8( addr );
PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u8>( addr ), addr, psxHu8(addr) );
PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<mem8_t>( addr ), addr, psxHu8(addr) );
return ret;
}
@ -323,62 +323,62 @@ static __forceinline T _HwRead_16or32_Page1( u32 addr )
//////////////////////////////////////////////////////////////////////////////////////////
//
u16 __fastcall iopHwRead16_Page1( u32 addr )
mem16_t __fastcall iopHwRead16_Page1( u32 addr )
{
return _HwRead_16or32_Page1<u16>( addr );
return _HwRead_16or32_Page1<mem16_t>( addr );
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u16 __fastcall iopHwRead16_Page3( u32 addr )
mem16_t __fastcall iopHwRead16_Page3( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
u16 ret = psxHu16(addr);
PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, ret );
mem16_t ret = psxHu16(addr);
PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<mem16_t>( addr ), addr, ret );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u16 __fastcall iopHwRead16_Page8( u32 addr )
mem16_t __fastcall iopHwRead16_Page8( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
u16 ret = psxHu16(addr);
PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, ret );
mem16_t ret = psxHu16(addr);
PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<mem16_t>( addr ), addr, ret );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u32 __fastcall iopHwRead32_Page1( u32 addr )
mem32_t __fastcall iopHwRead32_Page1( u32 addr )
{
return _HwRead_16or32_Page1<u32>( addr );
return _HwRead_16or32_Page1<mem32_t>( addr );
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u32 __fastcall iopHwRead32_Page3( u32 addr )
mem32_t __fastcall iopHwRead32_Page3( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
const u32 ret = psxHu32(addr);
PSXHW_LOG( "HwRead32 from %s, addr 0x%08x = 0x%08x", _log_GetIopHwName<u32>( addr ), addr, ret );
const mem32_t ret = psxHu32(addr);
PSXHW_LOG( "HwRead32 from %s, addr 0x%08x = 0x%08x", _log_GetIopHwName<mem32_t>( addr ), addr, ret );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u32 __fastcall iopHwRead32_Page8( u32 addr )
mem32_t __fastcall iopHwRead32_Page8( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
u32 masked_addr = addr & 0x0fff;
u32 ret;
mem32_t ret;
if( masked_addr >= 0x200 )
{
@ -426,7 +426,7 @@ u32 __fastcall iopHwRead32_Page8( u32 addr )
}
else ret = psxHu32(addr);
PSXHW_LOG( "HwRead32 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u32>( addr ), addr, ret );
PSXHW_LOG( "HwRead32 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<mem32_t>( addr ), addr, ret );
return ret;
}

View File

@ -37,9 +37,9 @@ static __forceinline void _generic_write( u32 addr, T val )
psxHu(addr) = val;
}
void __fastcall iopHwWrite8_generic( u32 addr, u8 val ) { _generic_write<u8>( addr, val ); }
void __fastcall iopHwWrite16_generic( u32 addr, u16 val ) { _generic_write<u16>( addr, val ); }
void __fastcall iopHwWrite32_generic( u32 addr, u32 val ) { _generic_write<u32>( addr, val ); }
void __fastcall iopHwWrite8_generic( u32 addr, mem8_t val ) { _generic_write<mem8_t>( addr, val ); }
void __fastcall iopHwWrite16_generic( u32 addr, mem16_t val ) { _generic_write<mem16_t>( addr, val ); }
void __fastcall iopHwWrite32_generic( u32 addr, mem32_t val ) { _generic_write<mem32_t>( addr, val ); }
//////////////////////////////////////////////////////////////////////////////////////////
//
@ -53,14 +53,14 @@ static __forceinline T _generic_read( u32 addr )
return ret;
}
u8 __fastcall iopHwRead8_generic( u32 addr ) { return _generic_read<u8>( addr ); }
u16 __fastcall iopHwRead16_generic( u32 addr ) { return _generic_read<u16>( addr ); }
u32 __fastcall iopHwRead32_generic( u32 addr ) { return _generic_read<u32>( addr ); }
mem8_t __fastcall iopHwRead8_generic( u32 addr ) { return _generic_read<mem8_t>( addr ); }
mem16_t __fastcall iopHwRead16_generic( u32 addr ) { return _generic_read<mem16_t>( addr ); }
mem32_t __fastcall iopHwRead32_generic( u32 addr ) { return _generic_read<mem32_t>( addr ); }
//////////////////////////////////////////////////////////////////////////////////////////
//
void __fastcall iopHwWrite8_Page1( u32 addr, u8 val )
void __fastcall iopHwWrite8_Page1( u32 addr, mem8_t val )
{
// all addresses are assumed to be prefixed with 0x1f801xxx:
jASSUME( (addr >> 12) == 0x1f801 );
@ -103,13 +103,13 @@ void __fastcall iopHwWrite8_Page1( u32 addr, u8 val )
break;
}
PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x\n", _log_GetIopHwName<u8>(addr), addr, val );
PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x\n", _log_GetIopHwName<mem8_t>(addr), addr, val );
}
static char g_pbuf[1024];
static int g_pbufi;
void __fastcall iopHwWrite8_Page3( u32 addr, u8 val )
void __fastcall iopHwWrite8_Page3( u32 addr, mem8_t val )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
@ -133,11 +133,11 @@ void __fastcall iopHwWrite8_Page3( u32 addr, u8 val )
}
}
PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u8>(addr), addr, psxHu8(addr) );
PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<mem8_t>(addr), addr, psxHu8(addr) );
psxHu8( addr ) = val;
}
void __fastcall iopHwWrite8_Page8( u32 addr, u8 val )
void __fastcall iopHwWrite8_Page8( u32 addr, mem8_t val )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
@ -147,7 +147,7 @@ void __fastcall iopHwWrite8_Page8( u32 addr, u8 val )
else
psxHu8( addr ) = val;
PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u8>(addr), addr, psxHu8(addr) );
PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<mem8_t>(addr), addr, psxHu8(addr) );
}
@ -463,43 +463,43 @@ static __forceinline void _HwWrite_16or32_Page1( u32 addr, T val )
//////////////////////////////////////////////////////////////////////////////////////////
//
void __fastcall iopHwWrite16_Page1( u32 addr, u16 val )
void __fastcall iopHwWrite16_Page1( u32 addr, mem16_t val )
{
_HwWrite_16or32_Page1<u16>( addr, val );
_HwWrite_16or32_Page1<mem16_t>( addr, val );
}
void __fastcall iopHwWrite16_Page3( u32 addr, u16 val )
void __fastcall iopHwWrite16_Page3( u32 addr, mem16_t val )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
psxHu16(addr) = val;
PSXHW_LOG( "HwWrite16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, val );
PSXHW_LOG( "HwWrite16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<mem16_t>( addr ), addr, val );
}
void __fastcall iopHwWrite16_Page8( u32 addr, u16 val )
void __fastcall iopHwWrite16_Page8( u32 addr, mem16_t val )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
psxHu16(addr) = val;
PSXHW_LOG( "HwWrite16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, val );
PSXHW_LOG( "HwWrite16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<mem16_t>( addr ), addr, val );
}
//////////////////////////////////////////////////////////////////////////////////////////
//
void __fastcall iopHwWrite32_Page1( u32 addr, u32 val )
void __fastcall iopHwWrite32_Page1( u32 addr, mem32_t val )
{
_HwWrite_16or32_Page1<u32>( addr, val );
_HwWrite_16or32_Page1<mem32_t >( addr, val );
}
void __fastcall iopHwWrite32_Page3( u32 addr, u32 val )
void __fastcall iopHwWrite32_Page3( u32 addr, mem32_t val )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
psxHu16(addr) = val;
PSXHW_LOG( "HwWrite32 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, val );
PSXHW_LOG( "HwWrite32 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<mem32_t>( addr ), addr, val );
}
void __fastcall iopHwWrite32_Page8( u32 addr, u32 val )
void __fastcall iopHwWrite32_Page8( u32 addr, mem32_t val )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
@ -539,7 +539,7 @@ void __fastcall iopHwWrite32_Page8( u32 addr, u32 val )
}
else psxHu32(addr) = val;
PSXHW_LOG( "HwWrite32 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u32>( addr ), addr, val );
PSXHW_LOG( "HwWrite32 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<mem32_t>( addr ), addr, val );
}
}

View File

@ -61,30 +61,6 @@ vtlbHandler UnmappedVirtHandler1;
vtlbHandler UnmappedPhyHandler0;
vtlbHandler UnmappedPhyHandler1;
/*
__asm
{
mov eax,ecx;
shr ecx,12;
mov ecx,[ecx*4+vmap]; //translate
add ecx,eax; //transform
js callfunction; //if <0 its invalid ptr :)
mov eax,[ecx];
mov [edx],eax;
xor eax,eax;
ret;
callfunction:
xchg eax,ecx;
shr eax,12; //get the 'ppn'
//ecx = original addr
//eax = function entry + 0x800000
//edx = data ptr
jmp [readfunctions8-0x800000+eax];
}*/
//////////////////////////////////////////////////////////////////////////////////////////
// Interpreter Implementations of VTLB Memory Operations.
@ -516,22 +492,27 @@ void vtlb_Init()
//the physical address space can be 'compressed' to just 29 bits.However, to properly handle exceptions
//there must be a way to get the full address back.Thats why i use these 2 functions and encode the hi bit directly into em :)
UnmappedVirtHandler0=vtlb_RegisterHandler(vtlbUnmappedVRead8<0>,vtlbUnmappedVRead16<0>,vtlbUnmappedVRead32<0>,vtlbUnmappedVRead64<0>,vtlbUnmappedVRead128<0>,
vtlbUnmappedVWrite8<0>,vtlbUnmappedVWrite16<0>,vtlbUnmappedVWrite32<0>,vtlbUnmappedVWrite64<0>,vtlbUnmappedVWrite128<0>);
UnmappedVirtHandler0 = vtlb_RegisterHandler(
vtlbUnmappedVRead8<0>,vtlbUnmappedVRead16<0>,vtlbUnmappedVRead32<0>,vtlbUnmappedVRead64<0>,vtlbUnmappedVRead128<0>,
vtlbUnmappedVWrite8<0>,vtlbUnmappedVWrite16<0>,vtlbUnmappedVWrite32<0>,vtlbUnmappedVWrite64<0>,vtlbUnmappedVWrite128<0>
);
UnmappedVirtHandler1=vtlb_RegisterHandler(vtlbUnmappedVRead8<0x80000000>,vtlbUnmappedVRead16<0x80000000>,vtlbUnmappedVRead32<0x80000000>,
vtlbUnmappedVRead64<0x80000000>,vtlbUnmappedVRead128<0x80000000>,
vtlbUnmappedVWrite8<0x80000000>,vtlbUnmappedVWrite16<0x80000000>,vtlbUnmappedVWrite32<0x80000000>,
vtlbUnmappedVWrite64<0x80000000>,vtlbUnmappedVWrite128<0x80000000>);
UnmappedVirtHandler1 = vtlb_RegisterHandler(
vtlbUnmappedVRead8<0x80000000>,vtlbUnmappedVRead16<0x80000000>,vtlbUnmappedVRead32<0x80000000>, vtlbUnmappedVRead64<0x80000000>,vtlbUnmappedVRead128<0x80000000>,
vtlbUnmappedVWrite8<0x80000000>,vtlbUnmappedVWrite16<0x80000000>,vtlbUnmappedVWrite32<0x80000000>, vtlbUnmappedVWrite64<0x80000000>,vtlbUnmappedVWrite128<0x80000000>
);
UnmappedPhyHandler0=vtlb_RegisterHandler(vtlbUnmappedPRead8<0>,vtlbUnmappedPRead16<0>,vtlbUnmappedPRead32<0>,vtlbUnmappedPRead64<0>,vtlbUnmappedPRead128<0>,
vtlbUnmappedPWrite8<0>,vtlbUnmappedPWrite16<0>,vtlbUnmappedPWrite32<0>,vtlbUnmappedPWrite64<0>,vtlbUnmappedPWrite128<0>);
UnmappedPhyHandler0 = vtlb_RegisterHandler(
vtlbUnmappedPRead8<0>,vtlbUnmappedPRead16<0>,vtlbUnmappedPRead32<0>,vtlbUnmappedPRead64<0>,vtlbUnmappedPRead128<0>,
vtlbUnmappedPWrite8<0>,vtlbUnmappedPWrite16<0>,vtlbUnmappedPWrite32<0>,vtlbUnmappedPWrite64<0>,vtlbUnmappedPWrite128<0>
);
UnmappedPhyHandler1=vtlb_RegisterHandler(vtlbUnmappedPRead8<0x80000000>,vtlbUnmappedPRead16<0x80000000>,vtlbUnmappedPRead32<0x80000000>,
vtlbUnmappedPRead64<0x80000000>,vtlbUnmappedPRead128<0x80000000>,
vtlbUnmappedPWrite8<0x80000000>,vtlbUnmappedPWrite16<0x80000000>,vtlbUnmappedPWrite32<0x80000000>,
vtlbUnmappedPWrite64<0x80000000>,vtlbUnmappedPWrite128<0x80000000>);
DefaultPhyHandler=vtlb_RegisterHandler(0,0,0,0,0,0,0,0,0,0);
UnmappedPhyHandler1 = vtlb_RegisterHandler(
vtlbUnmappedPRead8<0x80000000>,vtlbUnmappedPRead16<0x80000000>,vtlbUnmappedPRead32<0x80000000>, vtlbUnmappedPRead64<0x80000000>,vtlbUnmappedPRead128<0x80000000>,
vtlbUnmappedPWrite8<0x80000000>,vtlbUnmappedPWrite16<0x80000000>,vtlbUnmappedPWrite32<0x80000000>, vtlbUnmappedPWrite64<0x80000000>,vtlbUnmappedPWrite128<0x80000000>
);
DefaultPhyHandler = vtlb_RegisterHandler(0,0,0,0,0,0,0,0,0,0);
//done !
@ -542,6 +523,9 @@ void vtlb_Init()
vtlb_VMapUnmap(0,(VTLB_VMAP_ITEMS-1)*VTLB_PAGE_SIZE);
//yeah i know, its stupid .. but this code has to be here for now ;p
vtlb_VMapUnmap((VTLB_VMAP_ITEMS-1)*VTLB_PAGE_SIZE,VTLB_PAGE_SIZE);
extern void vtlb_dynarec_init();
vtlb_dynarec_init();
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -48,13 +48,13 @@ extern void vtlb_VMapUnmap(u32 vaddr,u32 sz);
//Memory functions
extern u8 __fastcall vtlb_memRead8(u32 mem);
extern u16 __fastcall vtlb_memRead16(u32 mem);
extern mem8_t __fastcall vtlb_memRead8(u32 mem);
extern mem16_t __fastcall vtlb_memRead16(u32 mem);
extern u32 __fastcall vtlb_memRead32(u32 mem);
extern void __fastcall vtlb_memRead64(u32 mem, u64 *out);
extern void __fastcall vtlb_memRead128(u32 mem, u64 *out);
extern void __fastcall vtlb_memWrite8 (u32 mem, u8 value);
extern void __fastcall vtlb_memWrite16(u32 mem, u16 value);
extern void __fastcall vtlb_memWrite8 (u32 mem, mem8_t value);
extern void __fastcall vtlb_memWrite16(u32 mem, mem16_t value);
extern void __fastcall vtlb_memWrite32(u32 mem, u32 value);
extern void __fastcall vtlb_memWrite64(u32 mem, const u64* value);
extern void __fastcall vtlb_memWrite128(u32 mem, const u64* value);

View File

@ -3028,10 +3028,6 @@
RelativePath="..\..\x86\ix86\ix86_types.h"
>
</File>
<File
RelativePath="..\..\x86\ix86\ix86_writers.inl"
>
</File>
<Filter
Name="Implement"
>

View File

@ -340,14 +340,22 @@ int _flushUnusedConstReg()
return 0;
}
// ------------------------------------------------------------------------
// recAllocStackMem -- an optimization trick to write data to a location so that
// recompiled code can reference it later on during execution.
//
// Intended use is for setting up 128 bit SSE immediates, and for compiling a
// struct-worth of const data for calling a function/handler (vtlb).
//
u32* recAllocStackMem(int size, int align)
{
// write to a temp loc, trick
if( (u32)recStackPtr % align ) recStackPtr += align - ((u32)recStackPtr%align);
recStackPtr += align - ((u32)recStackPtr % align);
recStackPtr += size;
return (u32*)(recStackPtr-size);
}
//////////////////////////////////////////////////////////////////////////////////////////
//
static const int REC_CACHEMEM = 0x01000000;
static void __fastcall dyna_block_discard(u32 start,u32 sz);

View File

@ -157,11 +157,31 @@ void iMOV64_Smart( const ModSibBase& destRm, const ModSibBase& srcRm )
*/
//////////////////////////////////////////////////////////////////////////////////////////
// Dynarec Load Implementations
static void _vtlb_DynGen_DirectRead( u32 bits, bool sign )
/*template< u32 ReadOrWrite, u32 bitType >
static __naked void _indirectMagicNaked()
{
enum
{
OffsetRWFT = (128*4*2*bitType) + (128*4*ReadOrWrite)
};
__asm
{
movzx eax, al
push ebx // return address - the indirect handler will return to this.
sub ecx, 0x80000000
sub ecx, eax
// jump to the indirect handler, which is a __fastcall C++ function.
// [edx is address, ecx is data, and the stack si the return address]
jmp [eax*4 + vtlbdata.RWFT + OffsetRWFT]
}
}*/
namespace vtlb_private
{
static void DynGen_DirectRead( u32 bits, bool sign )
{
switch( bits )
{
case 8:
@ -192,11 +212,11 @@ static void _vtlb_DynGen_DirectRead( u32 bits, bool sign )
jNO_DEFAULT
}
}
}
// ------------------------------------------------------------------------
static void _vtlb_DynGen_IndirectRead( u32 bits )
{
// ------------------------------------------------------------------------
static void DynGen_IndirectRead( u32 bits )
{
int szidx;
switch( bits )
@ -210,34 +230,131 @@ static void _vtlb_DynGen_IndirectRead( u32 bits )
}
MOVZX32R8toR(EAX,EAX);
SUB32RtoR(ECX,EAX);
//eax=[funct+eax]
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.RWFT[szidx][0],2);
SUB32ItoR(ECX,0x80000000);
CALL32R(EAX);
SUB32RtoR(ECX,EAX);
xCALL( ptr32[(eax*4) + vtlbdata.RWFT[szidx][0]] );
}
// ------------------------------------------------------------------------
static void DynGen_DirectWrite( u32 bits )
{
switch(bits)
{
//8 , 16, 32 : data on EDX
case 8:
MOV8RtoRm(ECX,EDX);
break;
case 16:
MOV16RtoRm(ECX,EDX);
break;
case 32:
MOV32RtoRm(ECX,EDX);
break;
case 64:
iMOV64_Smart(ptr[ecx],ptr[edx]);
break;
case 128:
iMOV128_SSE(ptr[ecx],ptr[edx]);
break;
}
}
}
// ------------------------------------------------------------------------
// Recompiled input registers:
// ecx = source addr to read from
// edx = ptr to dest to write to
// allocate one page for our naked indirect dispatcher function.
// this *must* be a full page, since we'll give it execution permission later.
// If it were smaller than a page we'd end up allowing execution rights on some
// other vars additionally (bad!).
//
PCSX2_ALIGNED( 0x1000, static u8 m_IndirectDispatchers[0x1000] );
// ------------------------------------------------------------------------
// mode - 0 for read, 1 for write!
// operandsize - 0 thru 4 represents 8, 16, 32, 64, and 128 bits.
//
static u8* GetIndirectDispatcherPtr( int mode, int operandsize )
{
// Each dispatcher is aligned to 64 bytes. The actual dispatchers are only like
// 20-some bytes each, but 64 byte alignment on functions that are called
// more frequently than a hot sex hotline at 1:15am is probably a good thing.
// 5*64? Because 5 operand types per each mode :D
return &m_IndirectDispatchers[(mode*(5*64)) + (operandsize*64)];
}
// ------------------------------------------------------------------------
// Generates a JS instruction that targets the appropriate templated instance of
// the vtlb Indirect Dispatcher.
//
static void DynGen_IndirectDispatch( int mode, int bits )
{
int szidx;
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;
jNO_DEFAULT;
}
xJS( GetIndirectDispatcherPtr( mode, szidx ) );
}
//////////////////////////////////////////////////////////////////////////////////////////
// One-time initialization procedure. Calling it multiple times shouldn't
// hurt anything tho.
//
void vtlb_dynarec_init()
{
// In case init gets called multiple times:
HostSys::MemProtect( m_IndirectDispatchers, 0x1000, Protect_ReadWrite, false );
// clear the buffer to 0xcc (easier debugging).
memset_8<0xcc,0x1000>( m_IndirectDispatchers );
u8* baseptr = m_IndirectDispatchers;
for( int mode=0; mode<2; ++mode )
{
for( int bits=0; bits<5; ++bits )
{
xSetPtr( GetIndirectDispatcherPtr( mode, bits ) );
xMOVZX( eax, al );
xSUB( ecx, 0x80000000 );
xSUB( ecx, eax );
// jump to the indirect handler, which is a __fastcall C++ function.
// [edx is address, ecx is data]
xCALL( ptr32[(eax*4) + vtlbdata.RWFT[bits][mode]] );
xJMP( ebx );
}
}
HostSys::MemProtect( m_IndirectDispatchers, 0x1000, Protect_ReadOnly, true );
}
//////////////////////////////////////////////////////////////////////////////////////////
// Dynarec Load Implementations
void vtlb_DynGenRead64(u32 bits)
{
jASSUME( bits == 64 || bits == 128 );
MOV32RtoR(EAX,ECX);
SHR32ItoR(EAX,VTLB_PAGE_BITS);
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2);
ADD32RtoR(ECX,EAX);
xForwardJS8 _fullread;
xMOV( eax, ecx );
xSHR( eax, VTLB_PAGE_BITS );
xMOV( eax, ptr[(eax*4) + vtlbdata.vmap] );
xMOV( ebx, 0xcdcdcdcd );
uptr* writeback = ((uptr*)xGetPtr()) - 1;
xADD( ecx, eax );
_vtlb_DynGen_DirectRead( bits, false );
xForwardJump8 cont;
DynGen_IndirectDispatch( 0, bits );
DynGen_DirectRead( bits, false );
_fullread.SetTarget();
_vtlb_DynGen_IndirectRead( bits );
cont.SetTarget();
*writeback = (uptr)xGetPtr(); // return target for indirect's call/ret
}
// ------------------------------------------------------------------------
@ -248,17 +365,17 @@ void vtlb_DynGenRead32(u32 bits, bool sign)
{
jASSUME( bits <= 32 );
MOV32RtoR(EAX,ECX);
SHR32ItoR(EAX,VTLB_PAGE_BITS);
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2);
ADD32RtoR(ECX,EAX);
xForwardJS8 _fullread;
xMOV( eax, ecx );
xSHR( eax, VTLB_PAGE_BITS );
xMOV( eax, ptr[(eax*4) + vtlbdata.vmap] );
xMOV( ebx, 0xcdcdcdcd );
uptr* writeback = ((uptr*)xGetPtr()) - 1;
xADD( ecx, eax );
_vtlb_DynGen_DirectRead( bits, sign );
xForwardJump8 cont;
DynGen_IndirectDispatch( 0, bits );
DynGen_DirectRead( bits, sign );
_fullread.SetTarget();
_vtlb_DynGen_IndirectRead( bits );
*writeback = (uptr)xGetPtr();
// perform sign extension on the result:
@ -276,7 +393,6 @@ void vtlb_DynGenRead32(u32 bits, bool sign)
else
MOVZX32R16toR(EAX,EAX);
}
cont.SetTarget();
}
// ------------------------------------------------------------------------
@ -326,6 +442,7 @@ void vtlb_DynGenRead64_Const( u32 bits, u32 addr_const )
//
// 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 )
{
u32 vmv_ptr = vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS];
@ -336,16 +453,16 @@ void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const )
{
case 8:
if( sign )
MOVSX32M8toR(EAX,ppf);
xMOVSX( eax, ptr8[ppf] );
else
MOVZX32M8toR(EAX,ppf);
xMOVZX( eax, ptr8[ppf] );
break;
case 16:
if( sign )
MOVSX32M16toR(EAX,ppf);
xMOVSX( eax, ptr16[ppf] );
else
MOVZX32M16toR(EAX,ppf);
xMOVZX( eax, ptr16[ppf] );
break;
case 32:
@ -382,16 +499,16 @@ void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const )
if( bits==8 )
{
if( sign )
MOVSX32R8toR(EAX,EAX);
xMOVSX( eax, al );
else
MOVZX32R8toR(EAX,EAX);
xMOVZX( eax, al );
}
else if( bits==16 )
{
if( sign )
MOVSX32R16toR(EAX,EAX);
xMOVSX( eax, ax );
else
MOVZX32R16toR(EAX,EAX);
xMOVZX( eax, ax );
}
}
}
@ -400,67 +517,19 @@ void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const )
//////////////////////////////////////////////////////////////////////////////////////////
// Dynarec Store Implementations
static void _vtlb_DynGen_DirectWrite( u32 bits )
{
switch(bits)
{
//8 , 16, 32 : data on EDX
case 8:
MOV8RtoRm(ECX,EDX);
break;
case 16:
MOV16RtoRm(ECX,EDX);
break;
case 32:
MOV32RtoRm(ECX,EDX);
break;
case 64:
iMOV64_Smart(ptr[ecx],ptr[edx]);
break;
case 128:
iMOV128_SSE(ptr[ecx],ptr[edx]);
break;
}
}
// ------------------------------------------------------------------------
static void _vtlb_DynGen_IndirectWrite( u32 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;
}
MOVZX32R8toR(EAX,EAX);
SUB32RtoR(ECX,EAX);
//eax=[funct+eax]
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.RWFT[szidx][1],2);
SUB32ItoR(ECX,0x80000000);
CALL32R(EAX);
}
// ------------------------------------------------------------------------
void vtlb_DynGenWrite(u32 sz)
{
MOV32RtoR(EAX,ECX);
SHR32ItoR(EAX,VTLB_PAGE_BITS);
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2);
ADD32RtoR(ECX,EAX);
xForwardJS8 _full;
xMOV( eax, ecx );
xSHR( eax, VTLB_PAGE_BITS );
xMOV( eax, ptr[(eax*4) + vtlbdata.vmap] );
xMOV( ebx, 0xcdcdcdcd );
uptr* writeback = ((uptr*)xGetPtr()) - 1;
xADD( ecx, eax );
_vtlb_DynGen_DirectWrite( sz );
xForwardJump8 cont;
DynGen_IndirectDispatch( 1, sz );
DynGen_DirectWrite( sz );
_full.SetTarget();
_vtlb_DynGen_IndirectWrite( sz );
cont.SetTarget();
*writeback = (uptr)xGetPtr();
}

View File

@ -68,6 +68,11 @@ namespace x86Emitter
return xAddressInfo( *this, right );
}
__forceinline xAddressInfo xAddressReg::operator+( const void* right ) const
{
return xAddressInfo( *this, (s32)right );
}
__forceinline xAddressInfo xAddressReg::operator*( u32 right ) const
{
return xAddressInfo( Empty, *this, right );

View File

@ -317,6 +317,7 @@ __forceinline void xWrite( T val )
xAddressInfo operator+( const xAddressReg& right ) const;
xAddressInfo operator+( const xAddressInfo& right ) const;
xAddressInfo operator+( s32 right ) const;
xAddressInfo operator+( const void* right ) const;
xAddressInfo operator*( u32 factor ) const;
xAddressInfo operator<<( u32 shift ) const;
@ -381,6 +382,7 @@ __forceinline void xWrite( T val )
__forceinline xAddressInfo operator+( const xAddressInfo& right ) const { return xAddressInfo( *this ).Add( right ); }
__forceinline xAddressInfo operator+( s32 imm ) const { return xAddressInfo( *this ).Add( imm ); }
__forceinline xAddressInfo operator-( s32 imm ) const { return xAddressInfo( *this ).Add( -imm ); }
__forceinline xAddressInfo operator+( const void* addr ) const { return xAddressInfo( *this ).Add( (uptr)addr ); }
};
extern const xRegisterSSE

View File

@ -296,4 +296,7 @@ Global
{F38D9DF0-F68D-49D9-B3A0-932E74FB74A0} = {E1828E40-2FBB-48FE-AE7F-5587755DCE0E}
{0FADC26C-0E9D-4DD7-84B1-BF4F7754E90C} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
AMDCaProjectFile = C:\pcsx2dev\pcsx2\CodeAnalyst\pcsx2_suite_2008.caw
EndGlobalSection
EndGlobal