mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
6a075aca03
commit
1cf028ccf5
|
@ -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 ...
|
||||
|
|
20
pcsx2/Hw.h
20
pcsx2/Hw.h
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -3028,10 +3028,6 @@
|
|||
RelativePath="..\..\x86\ix86\ix86_types.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\x86\ix86\ix86_writers.inl"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Implement"
|
||||
>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -157,87 +157,204 @@ 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()
|
||||
{
|
||||
switch( bits )
|
||||
enum
|
||||
{
|
||||
case 8:
|
||||
if( sign )
|
||||
MOVSX32Rm8toR(EAX,ECX);
|
||||
else
|
||||
MOVZX32Rm8toR(EAX,ECX);
|
||||
break;
|
||||
OffsetRWFT = (128*4*2*bitType) + (128*4*ReadOrWrite)
|
||||
};
|
||||
|
||||
case 16:
|
||||
if( sign )
|
||||
MOVSX32Rm16toR(EAX,ECX);
|
||||
else
|
||||
MOVZX32Rm16toR(EAX,ECX);
|
||||
break;
|
||||
__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]
|
||||
}
|
||||
}*/
|
||||
|
||||
case 32:
|
||||
MOV32RmtoR(EAX,ECX);
|
||||
break;
|
||||
namespace vtlb_private
|
||||
{
|
||||
static void DynGen_DirectRead( u32 bits, bool sign )
|
||||
{
|
||||
switch( bits )
|
||||
{
|
||||
case 8:
|
||||
if( sign )
|
||||
MOVSX32Rm8toR(EAX,ECX);
|
||||
else
|
||||
MOVZX32Rm8toR(EAX,ECX);
|
||||
break;
|
||||
|
||||
case 64:
|
||||
iMOV64_Smart(ptr[edx],ptr[ecx]);
|
||||
break;
|
||||
case 16:
|
||||
if( sign )
|
||||
MOVSX32Rm16toR(EAX,ECX);
|
||||
else
|
||||
MOVZX32Rm16toR(EAX,ECX);
|
||||
break;
|
||||
|
||||
case 128:
|
||||
iMOV128_SSE(ptr[edx],ptr[ecx]);
|
||||
break;
|
||||
case 32:
|
||||
MOV32RmtoR(EAX,ECX);
|
||||
break;
|
||||
|
||||
jNO_DEFAULT
|
||||
case 64:
|
||||
iMOV64_Smart(ptr[edx],ptr[ecx]);
|
||||
break;
|
||||
|
||||
case 128:
|
||||
iMOV128_SSE(ptr[edx],ptr[ecx]);
|
||||
break;
|
||||
|
||||
jNO_DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
static void DynGen_IndirectRead( u32 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
|
||||
}
|
||||
|
||||
MOVZX32R8toR(EAX,EAX);
|
||||
SUB32ItoR(ECX,0x80000000);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
static void _vtlb_DynGen_IndirectRead( u32 bits )
|
||||
// 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
|
||||
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;
|
||||
}
|
||||
|
||||
MOVZX32R8toR(EAX,EAX);
|
||||
SUB32RtoR(ECX,EAX);
|
||||
//eax=[funct+eax]
|
||||
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.RWFT[szidx][0],2);
|
||||
SUB32ItoR(ECX,0x80000000);
|
||||
CALL32R(EAX);
|
||||
xJS( GetIndirectDispatcherPtr( mode, szidx ) );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Recompiled input registers:
|
||||
// ecx = source addr to read from
|
||||
// edx = ptr to dest to write to
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
|
||||
_fullread.SetTarget();
|
||||
DynGen_IndirectDispatch( 0, bits );
|
||||
DynGen_DirectRead( bits, false );
|
||||
|
||||
_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;
|
||||
|
||||
_fullread.SetTarget();
|
||||
_vtlb_DynGen_IndirectRead( bits );
|
||||
DynGen_IndirectDispatch( 0, bits );
|
||||
DynGen_DirectRead( bits, sign );
|
||||
|
||||
*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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue