From 1cf028ccf50ebadc52f703ce3669a66b9b79a826 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Wed, 6 May 2009 02:15:43 +0000 Subject: [PATCH] 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 --- pcsx2/COP0.cpp | 2 +- pcsx2/Hw.h | 20 +- pcsx2/HwRead.cpp | 4 +- pcsx2/IopMem.h | 60 ++-- pcsx2/Memory.cpp | 10 +- pcsx2/ps2/Iop/IopHwRead.cpp | 50 +-- pcsx2/ps2/Iop/IopHwWrite.cpp | 48 +-- pcsx2/vtlb.cpp | 58 ++-- pcsx2/vtlb.h | 8 +- pcsx2/windows/VCprojects/pcsx2_2008.vcproj | 4 - pcsx2/x86/ix86-32/iR5900-32.cpp | 12 +- pcsx2/x86/ix86-32/recVTLB.cpp | 335 +++++++++++++-------- pcsx2/x86/ix86/ix86_inlines.inl | 5 + pcsx2/x86/ix86/ix86_types.h | 2 + pcsx2_suite_2008.sln | 3 + 15 files changed, 344 insertions(+), 277 deletions(-) diff --git a/pcsx2/COP0.cpp b/pcsx2/COP0.cpp index a59f054525..6042250b18 100644 --- a/pcsx2/COP0.cpp +++ b/pcsx2/COP0.cpp @@ -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 ... diff --git a/pcsx2/Hw.h b/pcsx2/Hw.h index 996cbbc3a8..9a915ce5ba 100644 --- a/pcsx2/Hw.h +++ b/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 ); diff --git a/pcsx2/HwRead.cpp b/pcsx2/HwRead.cpp index 2104c8acb8..60a9eb6ab5 100644 --- a/pcsx2/HwRead.cpp +++ b/pcsx2/HwRead.cpp @@ -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; diff --git a/pcsx2/IopMem.h b/pcsx2/IopMem.h index ad618c6b7f..b5a6e9e28e 100644 --- a/pcsx2/IopMem.h +++ b/pcsx2/IopMem.h @@ -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 ); } \ No newline at end of file diff --git a/pcsx2/Memory.cpp b/pcsx2/Memory.cpp index b791ce559a..217e72bc0b 100644 --- a/pcsx2/Memory.cpp +++ b/pcsx2/Memory.cpp @@ -347,7 +347,7 @@ void __fastcall _ext_memRead128(u32 mem, mem128_t *out) } template -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 -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 -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 -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 -void __fastcall _ext_memWrite128(u32 mem, const u64 *value) +void __fastcall _ext_memWrite128(u32 mem, const mem128_t *value) { /*switch (p) { //case 1: // hwm diff --git a/pcsx2/ps2/Iop/IopHwRead.cpp b/pcsx2/ps2/Iop/IopHwRead.cpp index f9ad47252a..b89c3bfae1 100644 --- a/pcsx2/ps2/Iop/IopHwRead.cpp +++ b/pcsx2/ps2/Iop/IopHwRead.cpp @@ -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( addr ), addr, ret ); + PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( 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( addr ), addr, psxHu8(addr) ); + PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( 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( addr ), addr, psxHu8(addr) ); + PSXHW_LOG( "HwRead8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( 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( addr ); + return _HwRead_16or32_Page1( 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( addr ), addr, ret ); + mem16_t ret = psxHu16(addr); + PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( 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( addr ), addr, ret ); + mem16_t ret = psxHu16(addr); + PSXHW_LOG( "HwRead16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, ret ); return ret; } ////////////////////////////////////////////////////////////////////////////////////////// // -u32 __fastcall iopHwRead32_Page1( u32 addr ) +mem32_t __fastcall iopHwRead32_Page1( u32 addr ) { - return _HwRead_16or32_Page1( addr ); + return _HwRead_16or32_Page1( 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( addr ), addr, ret ); + const mem32_t ret = psxHu32(addr); + PSXHW_LOG( "HwRead32 from %s, addr 0x%08x = 0x%08x", _log_GetIopHwName( 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( addr ), addr, ret ); + PSXHW_LOG( "HwRead32 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, ret ); return ret; } diff --git a/pcsx2/ps2/Iop/IopHwWrite.cpp b/pcsx2/ps2/Iop/IopHwWrite.cpp index 24c5bb9ba8..d8e413375d 100644 --- a/pcsx2/ps2/Iop/IopHwWrite.cpp +++ b/pcsx2/ps2/Iop/IopHwWrite.cpp @@ -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( addr, val ); } -void __fastcall iopHwWrite16_generic( u32 addr, u16 val ) { _generic_write( addr, val ); } -void __fastcall iopHwWrite32_generic( u32 addr, u32 val ) { _generic_write( addr, val ); } +void __fastcall iopHwWrite8_generic( u32 addr, mem8_t val ) { _generic_write( addr, val ); } +void __fastcall iopHwWrite16_generic( u32 addr, mem16_t val ) { _generic_write( addr, val ); } +void __fastcall iopHwWrite32_generic( u32 addr, mem32_t val ) { _generic_write( addr, val ); } ////////////////////////////////////////////////////////////////////////////////////////// // @@ -53,14 +53,14 @@ static __forceinline T _generic_read( u32 addr ) return ret; } -u8 __fastcall iopHwRead8_generic( u32 addr ) { return _generic_read( addr ); } -u16 __fastcall iopHwRead16_generic( u32 addr ) { return _generic_read( addr ); } -u32 __fastcall iopHwRead32_generic( u32 addr ) { return _generic_read( addr ); } +mem8_t __fastcall iopHwRead8_generic( u32 addr ) { return _generic_read( addr ); } +mem16_t __fastcall iopHwRead16_generic( u32 addr ) { return _generic_read( addr ); } +mem32_t __fastcall iopHwRead32_generic( u32 addr ) { return _generic_read( 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(addr), addr, val ); + PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x\n", _log_GetIopHwName(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(addr), addr, psxHu8(addr) ); + PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName(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(addr), addr, psxHu8(addr) ); + PSXHW_LOG( "HwWrite8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName(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( addr, val ); + _HwWrite_16or32_Page1( 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( addr ), addr, val ); + PSXHW_LOG( "HwWrite16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( 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( addr ), addr, val ); + PSXHW_LOG( "HwWrite16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( addr ), addr, val ); } ////////////////////////////////////////////////////////////////////////////////////////// // -void __fastcall iopHwWrite32_Page1( u32 addr, u32 val ) +void __fastcall iopHwWrite32_Page1( u32 addr, mem32_t val ) { - _HwWrite_16or32_Page1( addr, val ); + _HwWrite_16or32_Page1( 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( addr ), addr, val ); + PSXHW_LOG( "HwWrite32 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName( 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( addr ), addr, val ); + PSXHW_LOG( "HwWrite32 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName( addr ), addr, val ); } } diff --git a/pcsx2/vtlb.cpp b/pcsx2/vtlb.cpp index 2a016c61bf..76edac5fb4 100644 --- a/pcsx2/vtlb.cpp +++ b/pcsx2/vtlb.cpp @@ -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(); } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/pcsx2/vtlb.h b/pcsx2/vtlb.h index b1674fc79d..2e37093489 100644 --- a/pcsx2/vtlb.h +++ b/pcsx2/vtlb.h @@ -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); diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index 8b979de20d..88492c37a1 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -3028,10 +3028,6 @@ RelativePath="..\..\x86\ix86\ix86_types.h" > - - diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index 96575543f7..e0e64c5fa7 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -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); diff --git a/pcsx2/x86/ix86-32/recVTLB.cpp b/pcsx2/x86/ix86-32/recVTLB.cpp index b4ff537b44..03e9c06b65 100644 --- a/pcsx2/x86/ix86-32/recVTLB.cpp +++ b/pcsx2/x86/ix86-32/recVTLB.cpp @@ -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(); } diff --git a/pcsx2/x86/ix86/ix86_inlines.inl b/pcsx2/x86/ix86/ix86_inlines.inl index 9eedcb0b1a..a88a7881b9 100644 --- a/pcsx2/x86/ix86/ix86_inlines.inl +++ b/pcsx2/x86/ix86/ix86_inlines.inl @@ -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 ); diff --git a/pcsx2/x86/ix86/ix86_types.h b/pcsx2/x86/ix86/ix86_types.h index 95a6a3b3cd..3dc26befd5 100644 --- a/pcsx2/x86/ix86/ix86_types.h +++ b/pcsx2/x86/ix86/ix86_types.h @@ -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 diff --git a/pcsx2_suite_2008.sln b/pcsx2_suite_2008.sln index fbaf270f39..57f5664f52 100644 --- a/pcsx2_suite_2008.sln +++ b/pcsx2_suite_2008.sln @@ -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