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) if (tlb[i].S)
{ {
DevCon::WriteLn("OMG SPRAM MAPPING %08X %08X\n",params tlb[i].VPN2,tlb[i].Mask); 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 ... if (tlb[i].VPN2 == 0x70000000) return; //uh uhh right ...

View File

@ -384,8 +384,8 @@ void hwReset();
void hwShutdown(); void hwShutdown();
// hw read functions // hw read functions
extern u8 hwRead8 (u32 mem); extern mem8_t hwRead8 (u32 mem);
extern u16 hwRead16(u32 mem); extern mem16_t hwRead16(u32 mem);
extern mem32_t __fastcall hwRead32_page_00(u32 mem); extern mem32_t __fastcall hwRead32_page_00(u32 mem);
extern mem32_t __fastcall hwRead32_page_01(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 hwWrite8 (u32 mem, u8 value);
extern void hwWrite16(u32 mem, u16 value); extern void hwWrite16(u32 mem, u16 value);
extern void __fastcall hwWrite32_page_00( u32 mem, u32 value ); extern void __fastcall hwWrite32_page_00( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_01( u32 mem, u32 value ); extern void __fastcall hwWrite32_page_01( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_02( u32 mem, u32 value ); extern void __fastcall hwWrite32_page_02( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_03( u32 mem, u32 value ); extern void __fastcall hwWrite32_page_03( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_0B( u32 mem, u32 value ); extern void __fastcall hwWrite32_page_0B( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_0E( u32 mem, u32 value ); extern void __fastcall hwWrite32_page_0E( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_page_0F( u32 mem, u32 value ); extern void __fastcall hwWrite32_page_0F( u32 mem, mem32_t value );
extern void __fastcall hwWrite32_generic( u32 mem, u32 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_02( u32 mem, const mem64_t* srcval );
extern void __fastcall hwWrite64_page_03( 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 // Hardware READ 8 bit
__forceinline u8 hwRead8(u32 mem) __forceinline mem8_t hwRead8(u32 mem)
{ {
u8 ret; u8 ret;
@ -117,7 +117,7 @@ __forceinline u8 hwRead8(u32 mem)
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// Hardware READ 16 bit // Hardware READ 16 bit
__forceinline u16 hwRead16(u32 mem) __forceinline mem16_t hwRead16(u32 mem)
{ {
u16 ret; u16 ret;

View File

@ -98,39 +98,39 @@ void psxRecMemWrite32();
namespace IopMemory namespace IopMemory
{ {
// Sif functions not made yet (will for future Iop improvements): // Sif functions not made yet (will for future Iop improvements):
extern u8 __fastcall SifRead8( u32 iopaddr ); extern mem8_t __fastcall SifRead8( u32 iopaddr );
extern u16 __fastcall SifRead16( u32 iopaddr ); extern mem16_t __fastcall SifRead16( u32 iopaddr );
extern u32 __fastcall SifRead32( u32 iopaddr ); extern mem32_t __fastcall SifRead32( u32 iopaddr );
extern void __fastcall SifWrite8( u32 iopaddr, u8 data ); extern void __fastcall SifWrite8( u32 iopaddr, mem8_t data );
extern void __fastcall SifWrite16( u32 iopaddr, u16 data ); extern void __fastcall SifWrite16( u32 iopaddr, mem16_t data );
extern void __fastcall SifWrite32( u32 iopaddr, u32 data ); extern void __fastcall SifWrite32( u32 iopaddr, mem32_t data );
extern u8 __fastcall iopHwRead8_generic( u32 addr ); extern mem8_t __fastcall iopHwRead8_generic( u32 addr );
extern u16 __fastcall iopHwRead16_generic( u32 addr ); extern mem16_t __fastcall iopHwRead16_generic( u32 addr );
extern u32 __fastcall iopHwRead32_generic( u32 addr ); extern mem32_t __fastcall iopHwRead32_generic( u32 addr );
extern void __fastcall iopHwWrite8_generic( u32 addr, u8 val ); extern void __fastcall iopHwWrite8_generic( u32 addr, mem8_t val );
extern void __fastcall iopHwWrite16_generic( u32 addr, u16 val ); extern void __fastcall iopHwWrite16_generic( u32 addr, mem16_t val );
extern void __fastcall iopHwWrite32_generic( u32 addr, u32 val ); extern void __fastcall iopHwWrite32_generic( u32 addr, mem32_t val );
extern u8 __fastcall iopHwRead8_Page1( u32 iopaddr ); extern mem8_t __fastcall iopHwRead8_Page1( u32 iopaddr );
extern u8 __fastcall iopHwRead8_Page3( u32 iopaddr ); extern mem8_t __fastcall iopHwRead8_Page3( u32 iopaddr );
extern u8 __fastcall iopHwRead8_Page8( u32 iopaddr ); extern mem8_t __fastcall iopHwRead8_Page8( u32 iopaddr );
extern u16 __fastcall iopHwRead16_Page1( u32 iopaddr ); extern mem16_t __fastcall iopHwRead16_Page1( u32 iopaddr );
extern u16 __fastcall iopHwRead16_Page3( u32 iopaddr ); extern mem16_t __fastcall iopHwRead16_Page3( u32 iopaddr );
extern u16 __fastcall iopHwRead16_Page8( u32 iopaddr ); extern mem16_t __fastcall iopHwRead16_Page8( u32 iopaddr );
extern u32 __fastcall iopHwRead32_Page1( u32 iopaddr ); extern mem32_t __fastcall iopHwRead32_Page1( u32 iopaddr );
extern u32 __fastcall iopHwRead32_Page3( u32 iopaddr ); extern mem32_t __fastcall iopHwRead32_Page3( u32 iopaddr );
extern u32 __fastcall iopHwRead32_Page8( u32 iopaddr ); extern mem32_t __fastcall iopHwRead32_Page8( u32 iopaddr );
extern void __fastcall iopHwWrite8_Page1( u32 iopaddr, u8 data ); extern void __fastcall iopHwWrite8_Page1( u32 iopaddr, mem8_t data );
extern void __fastcall iopHwWrite8_Page3( u32 iopaddr, u8 data ); extern void __fastcall iopHwWrite8_Page3( u32 iopaddr, mem8_t data );
extern void __fastcall iopHwWrite8_Page8( u32 iopaddr, u8 data ); extern void __fastcall iopHwWrite8_Page8( u32 iopaddr, mem8_t data );
extern void __fastcall iopHwWrite16_Page1( u32 iopaddr, u16 data ); extern void __fastcall iopHwWrite16_Page1( u32 iopaddr, mem16_t data );
extern void __fastcall iopHwWrite16_Page3( u32 iopaddr, u16 data ); extern void __fastcall iopHwWrite16_Page3( u32 iopaddr, mem16_t data );
extern void __fastcall iopHwWrite16_Page8( u32 iopaddr, u16 data ); extern void __fastcall iopHwWrite16_Page8( u32 iopaddr, mem16_t data );
extern void __fastcall iopHwWrite32_Page1( u32 iopaddr, u32 data ); extern void __fastcall iopHwWrite32_Page1( u32 iopaddr, mem32_t data );
extern void __fastcall iopHwWrite32_Page3( u32 iopaddr, u32 data ); extern void __fastcall iopHwWrite32_Page3( u32 iopaddr, mem32_t data );
extern void __fastcall iopHwWrite32_Page8( u32 iopaddr, u32 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> template<int p>
void __fastcall _ext_memWrite8 (u32 mem, u8 value) void __fastcall _ext_memWrite8 (u32 mem, mem8_t value)
{ {
switch (p) { switch (p) {
case 1: // hwm case 1: // hwm
@ -367,7 +367,7 @@ void __fastcall _ext_memWrite8 (u32 mem, u8 value)
cpuTlbMissW(mem, cpuRegs.branch); cpuTlbMissW(mem, cpuRegs.branch);
} }
template<int p> template<int p>
void __fastcall _ext_memWrite16(u32 mem, u16 value) void __fastcall _ext_memWrite16(u32 mem, mem16_t value)
{ {
switch (p) { switch (p) {
case 1: // hwm case 1: // hwm
@ -392,7 +392,7 @@ void __fastcall _ext_memWrite16(u32 mem, u16 value)
} }
template<int p> template<int p>
void __fastcall _ext_memWrite32(u32 mem, u32 value) void __fastcall _ext_memWrite32(u32 mem, mem32_t value)
{ {
switch (p) { switch (p) {
case 6: // gsm case 6: // gsm
@ -407,7 +407,7 @@ void __fastcall _ext_memWrite32(u32 mem, u32 value)
} }
template<int p> template<int p>
void __fastcall _ext_memWrite64(u32 mem, const u64* value) void __fastcall _ext_memWrite64(u32 mem, const mem64_t* value)
{ {
/*switch (p) { /*switch (p) {
@ -423,7 +423,7 @@ void __fastcall _ext_memWrite64(u32 mem, const u64* value)
} }
template<int p> template<int p>
void __fastcall _ext_memWrite128(u32 mem, const u64 *value) void __fastcall _ext_memWrite128(u32 mem, const mem128_t *value)
{ {
/*switch (p) { /*switch (p) {
//case 1: // hwm //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: // all addresses are assumed to be prefixed with 0x1f801xxx:
jASSUME( (addr >> 12) == 0x1f801 ); jASSUME( (addr >> 12) == 0x1f801 );
u32 masked_addr = addr & 0x0fff; 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 ) switch( masked_addr )
{ {
mcase(HW_SIO_DATA): ret = sioRead8(); break; mcase(HW_SIO_DATA): ret = sioRead8(); break;
@ -71,42 +71,42 @@ u8 __fastcall iopHwRead8_Page1( u32 addr )
return ret; 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; return ret;
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
u8 __fastcall iopHwRead8_Page3( u32 addr ) mem8_t __fastcall iopHwRead8_Page3( u32 addr )
{ {
// all addresses are assumed to be prefixed with 0x1f803xxx: // all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 ); jASSUME( (addr >> 12) == 0x1f803 );
u8 ret; mem8_t ret;
if( addr == 0x1f803100 ) // PS/EE/IOP conf related if( addr == 0x1f803100 ) // PS/EE/IOP conf related
ret = 0x10; // Dram 2M ret = 0x10; // Dram 2M
else else
ret = psxHu8( addr ); 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; return ret;
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
u8 __fastcall iopHwRead8_Page8( u32 addr ) mem8_t __fastcall iopHwRead8_Page8( u32 addr )
{ {
// all addresses are assumed to be prefixed with 0x1f808xxx: // all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 ); jASSUME( (addr >> 12) == 0x1f808 );
u8 ret; mem8_t ret;
if( addr == HW_SIO2_FIFO ) if( addr == HW_SIO2_FIFO )
ret = sio2_fifoOut();//sio2 serial data feed/fifo_out ret = sio2_fifoOut();//sio2 serial data feed/fifo_out
else else
ret = psxHu8( addr ); 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; 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: // all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 ); jASSUME( (addr >> 12) == 0x1f803 );
u16 ret = psxHu16(addr); mem16_t ret = psxHu16(addr);
PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, ret ); PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<mem16_t>( addr ), addr, ret );
return 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: // all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 ); jASSUME( (addr >> 12) == 0x1f808 );
u16 ret = psxHu16(addr); mem16_t ret = psxHu16(addr);
PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, ret ); PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<mem16_t>( addr ), addr, ret );
return 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: // all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 ); jASSUME( (addr >> 12) == 0x1f803 );
const u32 ret = psxHu32(addr); const mem32_t ret = psxHu32(addr);
PSXHW_LOG( "HwRead32 from %s, addr 0x%08x = 0x%08x", _log_GetIopHwName<u32>( addr ), addr, ret ); PSXHW_LOG( "HwRead32 from %s, addr 0x%08x = 0x%08x", _log_GetIopHwName<mem32_t>( addr ), addr, ret );
return 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: // all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 ); jASSUME( (addr >> 12) == 0x1f808 );
u32 masked_addr = addr & 0x0fff; u32 masked_addr = addr & 0x0fff;
u32 ret; mem32_t ret;
if( masked_addr >= 0x200 ) if( masked_addr >= 0x200 )
{ {
@ -426,7 +426,7 @@ u32 __fastcall iopHwRead32_Page8( u32 addr )
} }
else ret = psxHu32(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; return ret;
} }

View File

@ -37,9 +37,9 @@ static __forceinline void _generic_write( u32 addr, T val )
psxHu(addr) = val; psxHu(addr) = val;
} }
void __fastcall iopHwWrite8_generic( u32 addr, u8 val ) { _generic_write<u8>( addr, val ); } void __fastcall iopHwWrite8_generic( u32 addr, mem8_t val ) { _generic_write<mem8_t>( addr, val ); }
void __fastcall iopHwWrite16_generic( u32 addr, u16 val ) { _generic_write<u16>( addr, val ); } void __fastcall iopHwWrite16_generic( u32 addr, mem16_t val ) { _generic_write<mem16_t>( addr, val ); }
void __fastcall iopHwWrite32_generic( u32 addr, u32 val ) { _generic_write<u32>( 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; return ret;
} }
u8 __fastcall iopHwRead8_generic( u32 addr ) { return _generic_read<u8>( addr ); } mem8_t __fastcall iopHwRead8_generic( u32 addr ) { return _generic_read<mem8_t>( addr ); }
u16 __fastcall iopHwRead16_generic( u32 addr ) { return _generic_read<u16>( addr ); } mem16_t __fastcall iopHwRead16_generic( u32 addr ) { return _generic_read<mem16_t>( addr ); }
u32 __fastcall iopHwRead32_generic( u32 addr ) { return _generic_read<u32>( 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: // all addresses are assumed to be prefixed with 0x1f801xxx:
jASSUME( (addr >> 12) == 0x1f801 ); jASSUME( (addr >> 12) == 0x1f801 );
@ -103,13 +103,13 @@ void __fastcall iopHwWrite8_Page1( u32 addr, u8 val )
break; 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 char g_pbuf[1024];
static int g_pbufi; 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: // all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 ); 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; 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: // all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 ); jASSUME( (addr >> 12) == 0x1f808 );
@ -147,7 +147,7 @@ void __fastcall iopHwWrite8_Page8( u32 addr, u8 val )
else else
psxHu8( addr ) = val; 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: // all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 ); jASSUME( (addr >> 12) == 0x1f803 );
psxHu16(addr) = val; 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: // all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 ); jASSUME( (addr >> 12) == 0x1f808 );
psxHu16(addr) = val; 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: // all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 ); jASSUME( (addr >> 12) == 0x1f803 );
psxHu16(addr) = val; 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: // all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 ); jASSUME( (addr >> 12) == 0x1f808 );
@ -539,7 +539,7 @@ void __fastcall iopHwWrite32_Page8( u32 addr, u32 val )
} }
else psxHu32(addr) = 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 UnmappedPhyHandler0;
vtlbHandler UnmappedPhyHandler1; 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. // 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 //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 :) //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>, UnmappedVirtHandler0 = vtlb_RegisterHandler(
vtlbUnmappedVWrite8<0>,vtlbUnmappedVWrite16<0>,vtlbUnmappedVWrite32<0>,vtlbUnmappedVWrite64<0>,vtlbUnmappedVWrite128<0>); 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>, UnmappedVirtHandler1 = vtlb_RegisterHandler(
vtlbUnmappedVRead64<0x80000000>,vtlbUnmappedVRead128<0x80000000>, vtlbUnmappedVRead8<0x80000000>,vtlbUnmappedVRead16<0x80000000>,vtlbUnmappedVRead32<0x80000000>, vtlbUnmappedVRead64<0x80000000>,vtlbUnmappedVRead128<0x80000000>,
vtlbUnmappedVWrite8<0x80000000>,vtlbUnmappedVWrite16<0x80000000>,vtlbUnmappedVWrite32<0x80000000>, vtlbUnmappedVWrite8<0x80000000>,vtlbUnmappedVWrite16<0x80000000>,vtlbUnmappedVWrite32<0x80000000>, vtlbUnmappedVWrite64<0x80000000>,vtlbUnmappedVWrite128<0x80000000>
vtlbUnmappedVWrite64<0x80000000>,vtlbUnmappedVWrite128<0x80000000>); );
UnmappedPhyHandler0=vtlb_RegisterHandler(vtlbUnmappedPRead8<0>,vtlbUnmappedPRead16<0>,vtlbUnmappedPRead32<0>,vtlbUnmappedPRead64<0>,vtlbUnmappedPRead128<0>, UnmappedPhyHandler0 = vtlb_RegisterHandler(
vtlbUnmappedPWrite8<0>,vtlbUnmappedPWrite16<0>,vtlbUnmappedPWrite32<0>,vtlbUnmappedPWrite64<0>,vtlbUnmappedPWrite128<0>); 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>, UnmappedPhyHandler1 = vtlb_RegisterHandler(
vtlbUnmappedPRead64<0x80000000>,vtlbUnmappedPRead128<0x80000000>, vtlbUnmappedPRead8<0x80000000>,vtlbUnmappedPRead16<0x80000000>,vtlbUnmappedPRead32<0x80000000>, vtlbUnmappedPRead64<0x80000000>,vtlbUnmappedPRead128<0x80000000>,
vtlbUnmappedPWrite8<0x80000000>,vtlbUnmappedPWrite16<0x80000000>,vtlbUnmappedPWrite32<0x80000000>, vtlbUnmappedPWrite8<0x80000000>,vtlbUnmappedPWrite16<0x80000000>,vtlbUnmappedPWrite32<0x80000000>, vtlbUnmappedPWrite64<0x80000000>,vtlbUnmappedPWrite128<0x80000000>
vtlbUnmappedPWrite64<0x80000000>,vtlbUnmappedPWrite128<0x80000000>); );
DefaultPhyHandler=vtlb_RegisterHandler(0,0,0,0,0,0,0,0,0,0);
DefaultPhyHandler = vtlb_RegisterHandler(0,0,0,0,0,0,0,0,0,0);
//done ! //done !
@ -542,6 +523,9 @@ void vtlb_Init()
vtlb_VMapUnmap(0,(VTLB_VMAP_ITEMS-1)*VTLB_PAGE_SIZE); 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 //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); 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 //Memory functions
extern u8 __fastcall vtlb_memRead8(u32 mem); extern mem8_t __fastcall vtlb_memRead8(u32 mem);
extern u16 __fastcall vtlb_memRead16(u32 mem); extern mem16_t __fastcall vtlb_memRead16(u32 mem);
extern u32 __fastcall vtlb_memRead32(u32 mem); extern u32 __fastcall vtlb_memRead32(u32 mem);
extern void __fastcall vtlb_memRead64(u32 mem, u64 *out); extern void __fastcall vtlb_memRead64(u32 mem, u64 *out);
extern void __fastcall vtlb_memRead128(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_memWrite8 (u32 mem, mem8_t value);
extern void __fastcall vtlb_memWrite16(u32 mem, u16 value); extern void __fastcall vtlb_memWrite16(u32 mem, mem16_t value);
extern void __fastcall vtlb_memWrite32(u32 mem, u32 value); extern void __fastcall vtlb_memWrite32(u32 mem, u32 value);
extern void __fastcall vtlb_memWrite64(u32 mem, const u64* value); extern void __fastcall vtlb_memWrite64(u32 mem, const u64* value);
extern void __fastcall vtlb_memWrite128(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" RelativePath="..\..\x86\ix86\ix86_types.h"
> >
</File> </File>
<File
RelativePath="..\..\x86\ix86\ix86_writers.inl"
>
</File>
<Filter <Filter
Name="Implement" Name="Implement"
> >

View File

@ -340,14 +340,22 @@ int _flushUnusedConstReg()
return 0; 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) u32* recAllocStackMem(int size, int align)
{ {
// write to a temp loc, trick recStackPtr += align - ((u32)recStackPtr % align);
if( (u32)recStackPtr % align ) recStackPtr += align - ((u32)recStackPtr%align);
recStackPtr += size; recStackPtr += size;
return (u32*)(recStackPtr-size); return (u32*)(recStackPtr-size);
} }
//////////////////////////////////////////////////////////////////////////////////////////
//
static const int REC_CACHEMEM = 0x01000000; static const int REC_CACHEMEM = 0x01000000;
static void __fastcall dyna_block_discard(u32 start,u32 sz); 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 )
*/ */
////////////////////////////////////////////////////////////////////////////////////////// /*template< u32 ReadOrWrite, u32 bitType >
// Dynarec Load Implementations static __naked void _indirectMagicNaked()
static void _vtlb_DynGen_DirectRead( u32 bits, bool sign )
{ {
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 ) switch( bits )
{ {
case 8: case 8:
@ -192,11 +212,11 @@ static void _vtlb_DynGen_DirectRead( u32 bits, bool sign )
jNO_DEFAULT jNO_DEFAULT
} }
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
static void _vtlb_DynGen_IndirectRead( u32 bits ) static void DynGen_IndirectRead( u32 bits )
{ {
int szidx; int szidx;
switch( bits ) switch( bits )
@ -210,34 +230,131 @@ static void _vtlb_DynGen_IndirectRead( u32 bits )
} }
MOVZX32R8toR(EAX,EAX); MOVZX32R8toR(EAX,EAX);
SUB32RtoR(ECX,EAX);
//eax=[funct+eax]
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.RWFT[szidx][0],2);
SUB32ItoR(ECX,0x80000000); 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: // allocate one page for our naked indirect dispatcher function.
// ecx = source addr to read from // this *must* be a full page, since we'll give it execution permission later.
// edx = ptr to dest to write to // 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) void vtlb_DynGenRead64(u32 bits)
{ {
jASSUME( bits == 64 || bits == 128 ); jASSUME( bits == 64 || bits == 128 );
MOV32RtoR(EAX,ECX); xMOV( eax, ecx );
SHR32ItoR(EAX,VTLB_PAGE_BITS); xSHR( eax, VTLB_PAGE_BITS );
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2); xMOV( eax, ptr[(eax*4) + vtlbdata.vmap] );
ADD32RtoR(ECX,EAX); xMOV( ebx, 0xcdcdcdcd );
xForwardJS8 _fullread; uptr* writeback = ((uptr*)xGetPtr()) - 1;
xADD( ecx, eax );
_vtlb_DynGen_DirectRead( bits, false ); DynGen_IndirectDispatch( 0, bits );
xForwardJump8 cont; DynGen_DirectRead( bits, false );
_fullread.SetTarget(); *writeback = (uptr)xGetPtr(); // return target for indirect's call/ret
_vtlb_DynGen_IndirectRead( bits );
cont.SetTarget();
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -248,17 +365,17 @@ void vtlb_DynGenRead32(u32 bits, bool sign)
{ {
jASSUME( bits <= 32 ); jASSUME( bits <= 32 );
MOV32RtoR(EAX,ECX); xMOV( eax, ecx );
SHR32ItoR(EAX,VTLB_PAGE_BITS); xSHR( eax, VTLB_PAGE_BITS );
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2); xMOV( eax, ptr[(eax*4) + vtlbdata.vmap] );
ADD32RtoR(ECX,EAX); xMOV( ebx, 0xcdcdcdcd );
xForwardJS8 _fullread; uptr* writeback = ((uptr*)xGetPtr()) - 1;
xADD( ecx, eax );
_vtlb_DynGen_DirectRead( bits, sign ); DynGen_IndirectDispatch( 0, bits );
xForwardJump8 cont; DynGen_DirectRead( bits, sign );
_fullread.SetTarget(); *writeback = (uptr)xGetPtr();
_vtlb_DynGen_IndirectRead( bits );
// perform sign extension on the result: // perform sign extension on the result:
@ -276,7 +393,6 @@ void vtlb_DynGenRead32(u32 bits, bool sign)
else else
MOVZX32R16toR(EAX,EAX); 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 // TLB lookup is performed in const, with the assumption that the COP0/TLB will clear the
// recompiler if the TLB is changed. // 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 )
{ {
u32 vmv_ptr = vtlbdata.vmap[addr_const>>VTLB_PAGE_BITS]; 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: case 8:
if( sign ) if( sign )
MOVSX32M8toR(EAX,ppf); xMOVSX( eax, ptr8[ppf] );
else else
MOVZX32M8toR(EAX,ppf); xMOVZX( eax, ptr8[ppf] );
break; break;
case 16: case 16:
if( sign ) if( sign )
MOVSX32M16toR(EAX,ppf); xMOVSX( eax, ptr16[ppf] );
else else
MOVZX32M16toR(EAX,ppf); xMOVZX( eax, ptr16[ppf] );
break; break;
case 32: case 32:
@ -382,16 +499,16 @@ void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const )
if( bits==8 ) if( bits==8 )
{ {
if( sign ) if( sign )
MOVSX32R8toR(EAX,EAX); xMOVSX( eax, al );
else else
MOVZX32R8toR(EAX,EAX); xMOVZX( eax, al );
} }
else if( bits==16 ) else if( bits==16 )
{ {
if( sign ) if( sign )
MOVSX32R16toR(EAX,EAX); xMOVSX( eax, ax );
else 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 // 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) void vtlb_DynGenWrite(u32 sz)
{ {
MOV32RtoR(EAX,ECX); xMOV( eax, ecx );
SHR32ItoR(EAX,VTLB_PAGE_BITS); xSHR( eax, VTLB_PAGE_BITS );
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2); xMOV( eax, ptr[(eax*4) + vtlbdata.vmap] );
ADD32RtoR(ECX,EAX); xMOV( ebx, 0xcdcdcdcd );
xForwardJS8 _full; uptr* writeback = ((uptr*)xGetPtr()) - 1;
xADD( ecx, eax );
_vtlb_DynGen_DirectWrite( sz ); DynGen_IndirectDispatch( 1, sz );
xForwardJump8 cont; DynGen_DirectWrite( sz );
_full.SetTarget(); *writeback = (uptr)xGetPtr();
_vtlb_DynGen_IndirectWrite( sz );
cont.SetTarget();
} }

View File

@ -68,6 +68,11 @@ namespace x86Emitter
return xAddressInfo( *this, right ); return xAddressInfo( *this, right );
} }
__forceinline xAddressInfo xAddressReg::operator+( const void* right ) const
{
return xAddressInfo( *this, (s32)right );
}
__forceinline xAddressInfo xAddressReg::operator*( u32 right ) const __forceinline xAddressInfo xAddressReg::operator*( u32 right ) const
{ {
return xAddressInfo( Empty, *this, right ); 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 xAddressReg& right ) const;
xAddressInfo operator+( const xAddressInfo& right ) const; xAddressInfo operator+( const xAddressInfo& right ) const;
xAddressInfo operator+( s32 right ) const; xAddressInfo operator+( s32 right ) const;
xAddressInfo operator+( const void* right ) const;
xAddressInfo operator*( u32 factor ) const; xAddressInfo operator*( u32 factor ) const;
xAddressInfo operator<<( u32 shift ) 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+( 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-( 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 extern const xRegisterSSE

View File

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