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
This commit is contained in:
refraction 2011-05-24 23:30:14 +00:00
parent 1bb055bf10
commit 0b6c8eaed4
1 changed files with 611 additions and 66 deletions

View File

@ -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