From 0b6c8eaed43cce6c9d7d931b81e0b241322674a4 Mon Sep 17 00:00:00 2001 From: refraction Date: Tue, 24 May 2011 23:30:14 +0000 Subject: [PATCH] Altered changes and reuploaded, defines are inplace so parts can be switched off for bug testing. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4671 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/x86/ix86-32/iR5900LoadStore.cpp | 677 +++++++++++++++++++++++--- 1 file changed, 611 insertions(+), 66 deletions(-) diff --git a/pcsx2/x86/ix86-32/iR5900LoadStore.cpp b/pcsx2/x86/ix86-32/iR5900LoadStore.cpp index 3339223a09..635d805d45 100644 --- a/pcsx2/x86/ix86-32/iR5900LoadStore.cpp +++ b/pcsx2/x86/ix86-32/iR5900LoadStore.cpp @@ -21,6 +21,13 @@ #include "iR5900LoadStore.h" #include "iR5900.h" +#define REC_STORES +#define REC_LOADS +#define NEWLWC1 +#define NEWSWC +#define NEWLQC +#define NEWSQC + // Implemented at the bottom of the module: void SetFastMemory(int bSetFast); @@ -191,61 +198,62 @@ void recLoad32( u32 bits, bool sign ) // edxAlreadyAssigned - set to true if edx already holds the value being written (used by SWL/SWR) void recStore(u32 sz, bool edxAlreadyAssigned=false) { - // Performance note: Const prop for the store address is good, always. - // Constprop for the value being stored is not really worthwhile (better to use register - // allocation -- simpler code and just as fast) + // Performance note: Const prop for the store address is good, always. + // Constprop for the value being stored is not really worthwhile (better to use register + // allocation -- simpler code and just as fast) - // Load EDX first with the value being written, or the address of the value - // being written (64/128 bit modes). TODO: use register allocation, if the - // value is allocated to a register. + // Load EDX first with the value being written, or the address of the value + // being written (64/128 bit modes). TODO: use register allocation, if the + // value is allocated to a register. - if( !edxAlreadyAssigned ) - { - if( sz < 64 ) - { - _eeMoveGPRtoR(EDX, _Rt_); - } - else if (sz==128 || sz==64) - { - _deleteEEreg(_Rt_, 1); // flush register to mem - MOV32ItoR(EDX,(int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]); - } - } + if( !edxAlreadyAssigned ) + { + if( sz < 64 ) + { + _eeMoveGPRtoR(EDX, _Rt_); + } + else if (sz==128 || sz==64) + { + _deleteEEreg(_Rt_, 1); // flush register to mem + MOV32ItoR(EDX,(int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]); + } + } - // Load ECX with the destination address, or issue a direct optimized write - // if the address is a constant propagation. + // Load ECX with the destination address, or issue a direct optimized write + // if the address is a constant propagation. - if( GPR_IS_CONST1( _Rs_ ) ) - { - iFlushCall(FLUSH_EXCEPTION); - u32 dstadr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; - if( sz == 128 ) dstadr &= ~0x0f; - vtlb_DynGenWrite_Const( sz, dstadr ); - } - else - { - iFlushCall(FLUSH_EXCEPTION); - _eeMoveGPRtoR(ECX, _Rs_); + if( GPR_IS_CONST1( _Rs_ ) ) + { + iFlushCall(FLUSH_EXCEPTION); + u32 dstadr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + if( sz == 128 ) dstadr &= ~0x0f; + vtlb_DynGenWrite_Const( sz, dstadr ); + } + else + { + iFlushCall(FLUSH_EXCEPTION); + _eeMoveGPRtoR(ECX, _Rs_); - if ( _Imm_ != 0 ) - ADD32ItoR(ECX, _Imm_); - if (sz==128) - AND32ItoR(ECX,~0x0F); + if ( _Imm_ != 0 ) + ADD32ItoR(ECX, _Imm_); + if (sz==128) + AND32ItoR(ECX,~0x0F); - vtlb_DynGenWrite(sz); - } + vtlb_DynGenWrite(sz); + } } + ////////////////////////////////////////////////////////////////////////////////////////// // -void recLB( void ) { recLoad32(8,true); } -void recLBU( void ) { recLoad32(8,false); } -void recLH( void ) { recLoad32(16,true); } -void recLHU( void ) { recLoad32(16,false); } -void recLW( void ) { recLoad32(32,true); } -void recLWU( void ) { recLoad32(32,false); } -void recLD( void ) { recLoad64(64,false); } -void recLQ( void ) { recLoad64(128,false); } +void recLB( void ) { if(_Rt_) recLoad32(8,true); } +void recLBU( void ) { if(_Rt_) recLoad32(8,false); } +void recLH( void ) { if(_Rt_) recLoad32(16,true); } +void recLHU( void ) { if(_Rt_) recLoad32(16,false); } +void recLW( void ) { if(_Rt_) recLoad32(32,true); } +void recLWU( void ) { if(_Rt_) recLoad32(32,false); } +void recLD( void ) { if(_Rt_) recLoad64(64,false); } +void recLQ( void ) { if(_Rt_) recLoad64(128,false); } void recSB( void ) { recStore(8); } void recSH( void ) { recStore(16); } @@ -258,25 +266,165 @@ void recSD( void ) { recStore(64); } // (LWL/SWL, LWR/SWR, etc) //////////////////////////////////////////////////// + +static const s32 LWL_MASK[4] = { 0xffffff, 0x0000ffff, 0x000000ff, 0x00000000 }; +static const s32 LWR_MASK[4] = { 0x000000, 0xff000000, 0xffff0000, 0xffffff00 }; +static const u8 LWL_SHIFT[4] = { 24, 16, 8, 0 }; +static const u8 LWR_SHIFT[4] = { 0, 8, 16, 24 }; + void recLWL( void ) { + if(!_Rt_) return; +#ifdef REC_LOADS + + iFlushCall(FLUSH_EXCEPTION); + _eeOnLoadWrite(_Rt_); + _deleteEEreg(_Rt_, 1); + + if( GPR_IS_CONST1( _Rs_ ) ) + { + u32 srcadr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + u32 shift = srcadr & 0x3; + srcadr &= ~0x3; + + vtlb_DynGenRead32_Const( 32, true, srcadr ); + + if( GPR_IS_CONST1( _Rt_ ) ) + { + int res = g_cpuConstRegs[_Rt_].UL[0] & LWL_MASK[shift]; + MOV32ItoR( EDX, res ); + } + else + { + _eeMoveGPRtoR(EDX, _Rt_); + AND32ItoR( EDX, LWL_MASK[shift] ); + } + + SHL32ItoR( EAX, LWL_SHIFT[shift] ); + OR32RtoR( EAX, EDX ); + } + else + { + // Load ECX with the source memory address that we're reading from. + _eeMoveGPRtoR(ECX, _Rs_); + if ( _Imm_ != 0 ) + ADD32ItoR( ECX, _Imm_ ); + + MOV32RtoR(EDX, ECX); + AND32ItoR(EDX, 0x3); + SHL32ItoR(EDX, 3); + + AND32ItoR(ECX,~0x3); + + + vtlb_DynGenRead32(32, true); + + MOV32RtoR(ECX, EDX); + MOV32ItoR( EBX, 0xffffff ); + SHR32CLtoR( EBX ); + + MOV32ItoR( ECX, 24 ); + SUB32RtoR(ECX, EDX); + SHL32CLtoR( EAX );// eax << ecx + + _eeMoveGPRtoR(EDX, _Rt_); + + AND32RtoR( EDX, EBX ); + + OR32RtoR( EAX, EDX ); + } + + // EAX holds the loaded value, so sign extend as needed: + CDQ(); + + MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX ); + MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX ); +#else + iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); _deleteEEreg(_Rt_, 1); recCall(LWL); +#endif } //////////////////////////////////////////////////// void recLWR( void ) { + if(!_Rt_) return; +#ifdef REC_LOADS + iFlushCall(FLUSH_EXCEPTION); + _eeOnLoadWrite(_Rt_); + _deleteEEreg(_Rt_, 1); + + if( GPR_IS_CONST1( _Rs_ ) ) + { + u32 srcadr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + u32 shift = srcadr & 0x3; + srcadr &= ~0x3; + //DevCon.Warning("LWR Const"); + vtlb_DynGenRead32_Const( 32, true, srcadr ); + + if( GPR_IS_CONST1( _Rt_ ) ) + { + int res = g_cpuConstRegs[_Rt_].UL[0] & LWR_MASK[shift]; + MOV32ItoR( EDX, res ); + } + else + { + _eeMoveGPRtoR(EDX, _Rt_); + AND32ItoR( EDX, LWR_MASK[shift] ); + } + + SHR32ItoR( EAX, LWR_SHIFT[shift] ); + OR32RtoR( EAX, EDX ); + } + else + { + + //iFlushCall(FLUSH_EXCEPTION); + // Load ECX with the source memory address that we're reading from. + _eeMoveGPRtoR(ECX, _Rs_); + if ( _Imm_ != 0 ) + ADD32ItoR( ECX, _Imm_ ); + + MOV32RtoR(EDX, ECX); + AND32ItoR(EDX, 0x3); + SHL32ItoR(EDX, 3); + + AND32ItoR(ECX,~0x3); + + vtlb_DynGenRead32(32, true); + MOV32RtoR(ECX, EDX); + MOV32ItoR( EBX, 0xffffff00 ); + SHR32CLtoR( EAX ); // eax << ecx + + MOV32ItoR( ECX, 24 ); + SUB32RtoR(ECX, EDX); + SHL32CLtoR( EBX );// ebx << ecx + + _eeMoveGPRtoR(EDX, _Rt_); + + AND32RtoR( EDX, EBX ); + + OR32RtoR( EAX, EDX ); + } + + // EAX holds the loaded value, so sign extend as needed: + CDQ(); + + MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX ); + MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX ); +#else iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); _deleteEEreg(_Rt_, 1); recCall(LWR); +#endif } static const u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0x00000000 }; @@ -288,87 +436,385 @@ static const u8 SWL_SHIFT[4] = { 24, 16, 8, 0 }; //////////////////////////////////////////////////// void recSWL( void ) { - // Perform a translated memory read, followed by a translated memory write - // of the "merged" result. - // NOTE: Code incomplete. I'll fix/finish it soon. --air - if( 0 ) //GPR_IS_CONST1( _Rs_ ) ) +#ifdef REC_STORES + iFlushCall(FLUSH_EXCEPTION); + _eeOnLoadWrite(_Rt_); + _deleteEEreg(_Rt_, 1); + + if( GPR_IS_CONST1( _Rs_ ) ) { - iFlushCall(FLUSH_EXCEPTION); - _eeOnLoadWrite(_Rt_); - //_deleteEEreg(_Rt_, 0); - u32 addr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; u32 shift = addr & 3; - vtlb_DynGenRead32_Const( 32, false, addr & 3 ); + vtlb_DynGenRead32_Const( 32, false, addr & ~3 ); // Prep eax/edx for producing the writeback result: - // equiv to: (cpuRegs.GPR.r[_Rt_].UL[0] >> SWL_SHIFT[shift]) | (mem & SWL_MASK[shift]) + //DevCon.Warning("SWL Const"); + if(_Rt_) + { + if( GPR_IS_CONST1( _Rt_ ) ) + { + int res; + res = g_cpuConstRegs[_Rt_].UL[0] >> SWL_SHIFT[shift]; + } + else + { + _eeMoveGPRtoR(EDX, _Rt_); + SHR32ItoR( EDX, SWL_SHIFT[shift] ); + } + } + else XOR32RtoR( EDX, EDX ); - //_deleteEEreg(_Rt_, 1); - //MOV32MtoR( EDX, (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ); - - _eeMoveGPRtoR(EDX, _Rt_); - AND32ItoR( EAX, SWL_MASK[shift] ); - SHR32ItoR( EDX, SWL_SHIFT[shift] ); + AND32ItoR( EAX, SWL_MASK[shift] ); OR32RtoR( EDX, EAX ); - recStore( 32, true ); + vtlb_DynGenWrite_Const( 32, addr & ~0x3 ); } else { - iFlushCall(FLUSH_EXCEPTION); - _deleteEEreg(_Rs_, 1); - _deleteEEreg(_Rt_, 1); - recCall(SWL); + + _eeMoveGPRtoR(ECX, _Rs_); + //DevCon.Warning("SWL No Const"); + if ( _Imm_ != 0 ) + ADD32ItoR(ECX, _Imm_); + + + MOV32RtoR(EDX, ECX); + AND32ItoR(EDX, 0x3); + SHL32ItoR(EDX, 3); + + AND32ItoR(ECX,~0x3); + + vtlb_DynGenRead32(32, false); + MOV32RtoR( ECX, EDX ); + MOV32ItoR( EBX, 0xffffff00 ); + SHL32CLtoR( EBX ); // ebx << ecx + AND32RtoR( EAX, EBX ); + if(_Rt_) + { + MOV32ItoR( ECX, 24 ); + SUB32RtoR( ECX, EDX ); + + _eeMoveGPRtoR(EDX, _Rt_); + SHR32CLtoR( EDX ); // edx >> ecx + } + else XOR32RtoR( EDX, EDX ); + OR32RtoR( EDX, EAX ); + + _eeMoveGPRtoR(ECX, _Rs_); + + if ( _Imm_ != 0 ) + ADD32ItoR(ECX, _Imm_); + + AND32ItoR(ECX,~0x3); + + vtlb_DynGenWrite(32); } +#else + iFlushCall(FLUSH_EXCEPTION); + _deleteEEreg(_Rs_, 1); + _deleteEEreg(_Rt_, 1); + recCall(SWL); +#endif } //////////////////////////////////////////////////// void recSWR( void ) { + +#ifdef REC_STORES + iFlushCall(FLUSH_EXCEPTION); + _eeOnLoadWrite(_Rt_); + _deleteEEreg(_Rt_, 1); + if( GPR_IS_CONST1( _Rs_ ) ) + { + u32 addr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + u32 shift = addr & 3; + vtlb_DynGenRead32_Const( 32, false, addr & ~3 ); + + // Prep eax/edx for producing the writeback result: + //DevCon.Warning("SWR Const"); + if(_Rt_) + { + if( GPR_IS_CONST1( _Rt_ ) ) + { + int res; + res = g_cpuConstRegs[_Rt_].UL[0] << SWR_SHIFT[shift]; + MOV32ItoR( EDX, res ); + } + else + { + _eeMoveGPRtoR(EDX, _Rt_); + SHL32ItoR( EDX, SWR_SHIFT[shift] ); + } + } + else XOR32RtoR( EDX, EDX ); + AND32ItoR( EAX, SWR_MASK[shift] ); + OR32RtoR( EDX, EAX ); + + vtlb_DynGenWrite_Const( 32, addr & ~0x3 ); + } + else + { + _eeMoveGPRtoR(ECX, _Rs_); + //DevCon.Warning("SWR No Const"); + if ( _Imm_ != 0 ) + ADD32ItoR(ECX, _Imm_); + MOV32RtoR(EDX, ECX); //Move to EBX for shift + AND32ItoR(ECX,~0x3); //Mask final bit of address + + vtlb_DynGenRead32(32, false); //Read in to EAX + + AND32ItoR(EDX, 0x3); //Mask shift bits + SHL32ItoR(EDX, 3); //Multiply by 8 + + if(_Rt_) + { + MOV32RtoR( ECX, EDX ); //Copy shift in to ECX + _eeMoveGPRtoR(EBX, _Rt_); //Move Rt in to EDX + SHL32CLtoR( EBX ); // Rt << shift (ecx) + } + else XOR32RtoR( EBX, EBX ); + MOV32ItoR( ECX, 24 ); //Move 24 in to ECX + SUB32RtoR( ECX, EDX ); //Take the shift from it (so if shift is 1, itll do 24 - 8 = 16) + MOV32ItoR( EDX, 0xffffff ); //Move the mask in to where the shift was + SHR32CLtoR( EDX ); // mask >> 24-shift + + AND32RtoR( EAX, EDX ); //And the Mask with the original memory in EAX + + OR32RtoR( EBX, EAX ); //Or our result of the _Rt_ shift to it + MOV32RtoR( EDX, EBX ); + _eeMoveGPRtoR(ECX, _Rs_); + + if ( _Imm_ != 0 ) + ADD32ItoR(ECX, _Imm_); + + AND32ItoR(ECX,~0x3); + + //EDX holds data to be written back + vtlb_DynGenWrite(32); //Write back to memory + } +#else iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _deleteEEreg(_Rt_, 1); recCall(SWR); +#endif } //////////////////////////////////////////////////// void recLDL( void ) { + + if(!_Rt_) return; +#ifdef REC_LOADS + iFlushCall(FLUSH_EXCEPTION); + _eeOnLoadWrite(_Rt_); + _deleteEEreg(_Rt_, 1); + + if( GPR_IS_CONST1( _Rs_ ) ) + { + u32 srcadr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + u32 shift = srcadr & 0x7; + + if(shift == 7) + { + //DevCon.Warning("LDL 7"); + srcadr &= ~0x7; + MOV32ItoR(EDX, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ); + + vtlb_DynGenRead64_Const( 64, srcadr ); + } + else if(shift == 3) + { + //DevCon.Warning("LDL threeeee"); + srcadr &= ~0x7; + vtlb_DynGenRead32_Const( 32, false, srcadr ); + MOV32RtoM((uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ] , EAX); + + } + else + { + //DevCon.Warning("LDL Const Interpreter Drop Back %x", shift); + recCall(LDL); + } + } + else + { + + //DevCon.Warning("Interpreter %x", shift); + _deleteEEreg(_Rt_, 0); + _eeOnLoadWrite(_Rt_); + recCall(LDL); + } +#else iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); _deleteEEreg(_Rt_, 1); recCall(LDL); +#endif } //////////////////////////////////////////////////// void recLDR( void ) { + if(!_Rt_) return; + +#ifdef REC_LOADS + iFlushCall(FLUSH_EXCEPTION); + _eeOnLoadWrite(_Rt_); + _deleteEEreg(_Rt_, 1); + if( GPR_IS_CONST1( _Rs_ ) ) + { + u32 srcadr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + u32 shift = srcadr & 0x7; + + if(shift == 0) + { + //DevCon.Warning("LDR 0"); + + MOV32ItoR(EDX, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ); + + vtlb_DynGenRead64_Const( 64, srcadr ); + } + else if(shift == 4) + { + //DevCon.Warning("LDR 4"); + + vtlb_DynGenRead32_Const( 32, false, srcadr ); + MOV32RtoM((uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] , EAX); + } + else + { + //DevCon.Warning("LDR Const Interpreter Drop Back %x", shift); + recCall(LDR); + } + } + else + { + //DevCon.Warning("Interpreter %x", shift); + _deleteEEreg(_Rt_, 0); + _eeOnLoadWrite(_Rt_); + recCall(LDR); + } +#else iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); _deleteEEreg(_Rt_, 1); recCall(LDR); +#endif } //////////////////////////////////////////////////// + +static const u64 SDL_MASK[8] = +{ 0xffffffffffffff00LL, 0xffffffffffff0000LL, 0xffffffffff000000LL, 0xffffffff00000000LL, + 0xffffff0000000000LL, 0xffff000000000000LL, 0xff00000000000000LL, 0x0000000000000000LL +}; +static const u64 SDR_MASK[8] = +{ 0x0000000000000000LL, 0x00000000000000ffLL, 0x000000000000ffffLL, 0x0000000000ffffffLL, + 0x00000000ffffffffLL, 0x000000ffffffffffLL, 0x0000ffffffffffffLL, 0x00ffffffffffffffLL +}; + void recSDL( void ) { + +#ifdef REC_STORES + iFlushCall(FLUSH_EXCEPTION); + _eeOnLoadWrite(_Rt_); + _deleteEEreg(_Rt_, 1); + + if( GPR_IS_CONST1( _Rs_ ) ) + { + + if( GPR_IS_CONST1( _Rt_ ) )DevCon.Warning("Yay SDL!"); + u32 addr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + u32 shift = addr & 7; + //DevCon.Warning("SDL %x", shift); + if(shift == 7) + { + //DevCon.Warning("T SDL 7"); + if( GPR_IS_CONST1( _Rt_ ) ) MOV32ItoR(EDX, (uptr)&g_cpuConstRegs[_Rt_].UL[0]); + else MOV32ItoR(EDX, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ); + vtlb_DynGenWrite_Const( 64, addr & ~0x7 ); + } + else if(shift == 3) + { + //DevCon.Warning("T SDL 3"); + if( GPR_IS_CONST1( _Rt_ ) ) MOV32ItoR(EDX, (uptr)&g_cpuConstRegs[_Rt_].UL[1]); + else MOV32MtoR(EDX, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ] ); + vtlb_DynGenWrite_Const( 32, addr & ~0x7 ); + } + else + { + //DevCon.Warning("SDL Const Interpreter Drop Back %x", shift); + iFlushCall(FLUSH_INTERPRETER); + recCall(SDL); + } + } + else + { + iFlushCall(FLUSH_INTERPRETER); + recCall(SDL); + + } +#else iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _deleteEEreg(_Rt_, 1); recCall(SDL); +#endif } //////////////////////////////////////////////////// void recSDR( void ) { +#ifdef REC_STORES + if( GPR_IS_CONST1( _Rs_ ) ) + { + iFlushCall(FLUSH_EXCEPTION); + _eeOnLoadWrite(_Rt_); + _deleteEEreg(_Rt_, 1); + + u32 addr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + u32 shift = addr & 7; + + if( GPR_IS_CONST1( _Rt_ ) )DevCon.Warning("Yay SDR!"); + + if(shift == 0) + { + //DevCon.Warning("T SDR 0"); + if( GPR_IS_CONST1( _Rt_ ) ) MOV32ItoR(EDX, (uptr)&g_cpuConstRegs[_Rt_].UL[0]); + else MOV32ItoR(EDX, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ); + vtlb_DynGenWrite_Const( 64, addr ); + } + else if(shift == 4) + { + //DevCon.Warning("T SDR 4"); + if( GPR_IS_CONST1( _Rt_ ) ) MOV32ItoR(EDX, (uptr)&g_cpuConstRegs[_Rt_].UL[0]); + else MOV32MtoR(EDX, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ); + vtlb_DynGenWrite_Const( 32, addr ); + } + else + { + //DevCon.Warning("SDR Const Interpreter Drop Back %x", shift); + iFlushCall(FLUSH_INTERPRETER); + recCall(SDR); + } + } + else + { + iFlushCall(FLUSH_INTERPRETER); + recCall(SDR); + } +#else iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _deleteEEreg(_Rt_, 1); recCall(SDR); +#endif } ////////////////////////////////////////////////////////////////////////////////////////// @@ -378,8 +824,29 @@ void recSDR( void ) *********************************************************/ //////////////////////////////////////////////////// + void recLWC1( void ) { +#ifdef NEWLWC1 + iFlushCall(FLUSH_EXCEPTION); + _deleteEEreg(_Rs_, 1); + _deleteFPtoXMMreg(_Rt_, 2); + + if( GPR_IS_CONST1( _Rs_ ) ) + { + int addr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + vtlb_DynGenRead32_Const(32, false, addr); + } + else + { + MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); + if ( _Imm_ != 0 ) + ADD32ItoR( ECX, _Imm_ ); + vtlb_DynGenRead32(32, false); + } + + MOV32RtoM( (int)&fpuRegs.fpr[ _Rt_ ].UL, EAX ); +#else iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _deleteFPtoXMMreg(_Rt_, 2); @@ -390,11 +857,33 @@ void recLWC1( void ) vtlb_DynGenRead32(32, false); MOV32RtoM( (int)&fpuRegs.fpr[ _Rt_ ].UL, EAX ); +#endif } //////////////////////////////////////////////////// + void recSWC1( void ) { +#ifdef NEWSWC + iFlushCall(FLUSH_EXCEPTION); + _deleteEEreg(_Rs_, 1); + _deleteFPtoXMMreg(_Rt_, 1); + + MOV32MtoR(EDX, (int)&fpuRegs.fpr[ _Rt_ ].UL ); + + if( GPR_IS_CONST1( _Rs_ ) ) + { + int addr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + vtlb_DynGenWrite_Const(32, addr); + } + else + { + MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); + if ( _Imm_ != 0 ) + ADD32ItoR( ECX, _Imm_ ); + vtlb_DynGenWrite(32); + } +#else iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _deleteFPtoXMMreg(_Rt_, 0); @@ -405,6 +894,7 @@ void recSWC1( void ) MOV32MtoR(EDX, (int)&fpuRegs.fpr[ _Rt_ ].UL ); vtlb_DynGenWrite(32); +#endif } //////////////////////////////////////////////////// @@ -418,8 +908,37 @@ void recSWC1( void ) #define _Fs_ _Rd_ #define _Fd_ _Sa_ + + void recLQC2( void ) { + +#ifdef NEWLQC + iFlushCall(FLUSH_EXCEPTION); + _deleteEEreg(_Rs_, 1); + _deleteVFtoXMMreg(_Ft_, 0, 2); + + if ( _Rt_ ) + MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] ); + else + MOV32ItoR(EDX, (int)&dummyValue[0] ); + + if( GPR_IS_CONST1( _Rs_ ) ) + { + int addr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + + vtlb_DynGenRead64_Const(128, addr); + } + else + { + MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); + + if ( _Imm_ != 0 ) + ADD32ItoR( ECX, _Imm_); + + vtlb_DynGenRead64(128); + } +#else iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _deleteVFtoXMMreg(_Ft_, 0, 2); @@ -434,11 +953,35 @@ void recLQC2( void ) MOV32ItoR(EDX, (int)&dummyValue[0] ); vtlb_DynGenRead64(128); +#endif } //////////////////////////////////////////////////// + + + void recSQC2( void ) { +#ifdef NEWSQC + iFlushCall(FLUSH_EXCEPTION); + _deleteEEreg(_Rs_, 1); + _deleteVFtoXMMreg(_Ft_, 0, 1); //Want to flush it but not clear it + + MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] ); + if( GPR_IS_CONST1( _Rs_ ) ) + { + int addr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_; + vtlb_DynGenWrite_Const(128, addr); + } + else + { + MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); + if ( _Imm_ != 0 ) + ADD32ItoR( ECX, _Imm_ ); + + vtlb_DynGenWrite(128); + } +#else iFlushCall(FLUSH_EXCEPTION); _deleteEEreg(_Rs_, 1); _deleteVFtoXMMreg(_Ft_, 0, 0); @@ -449,6 +992,8 @@ void recSQC2( void ) MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] ); vtlb_DynGenWrite(128); +#endif + } #endif