mirror of https://github.com/PCSX2/pcsx2.git
EE: reviewed, simplified and corrected (at least three bugs including issue 1078) left and right loads and stores. Probably a waste since there's a much smarter way to do these.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4799 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
1b294e1443
commit
78a3c30648
|
@ -21,6 +21,8 @@
|
||||||
#include "iR5900LoadStore.h"
|
#include "iR5900LoadStore.h"
|
||||||
#include "iR5900.h"
|
#include "iR5900.h"
|
||||||
|
|
||||||
|
using namespace x86Emitter;
|
||||||
|
|
||||||
#define REC_STORES
|
#define REC_STORES
|
||||||
#define REC_LOADS
|
#define REC_LOADS
|
||||||
#define NEWLWC1
|
#define NEWLWC1
|
||||||
|
@ -267,83 +269,43 @@ void recSD( void ) { recStore(64); }
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
|
|
||||||
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 )
|
void recLWL( void )
|
||||||
{
|
{
|
||||||
if(!_Rt_) return;
|
|
||||||
#ifdef REC_LOADS
|
#ifdef REC_LOADS
|
||||||
|
|
||||||
iFlushCall(FLUSH_EXCEPTION);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
|
|
||||||
if( GPR_IS_CONST1( _Rs_ ) )
|
_eeMoveGPRtoR(ECX, _Rs_);
|
||||||
{
|
if (_Imm_ != 0)
|
||||||
u32 srcadr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_;
|
xADD(ecx, _Imm_);
|
||||||
u32 shift = srcadr & 0x3;
|
|
||||||
srcadr &= ~0x3;
|
|
||||||
|
|
||||||
vtlb_DynGenRead32_Const( 32, true, srcadr );
|
// ebx = bit offset in word
|
||||||
|
xMOV(ebx, ecx);
|
||||||
|
xAND(ebx, 0x3);
|
||||||
|
xSHL(ebx, 3);
|
||||||
|
|
||||||
if( GPR_IS_CONST1( _Rt_ ) )
|
xAND(ecx, ~0x3);
|
||||||
{
|
vtlb_DynGenRead32(32, true);
|
||||||
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);
|
// mask off bytes loaded
|
||||||
AND32ItoR(EDX, 0x3);
|
xMOV(ecx, ebx);
|
||||||
SHL32ItoR(EDX, 3);
|
xMOV(edx, 0xffffff);
|
||||||
|
xSHR(edx, cl);
|
||||||
AND32ItoR(ECX,~0x3);
|
xAND(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]], edx);
|
||||||
|
|
||||||
|
|
||||||
vtlb_DynGenRead32(32, true);
|
|
||||||
|
|
||||||
MOV32RtoR(ECX, EDX);
|
// OR in bytes loaded
|
||||||
MOV32ItoR( EBX, 0xffffff );
|
xMOV(ecx, 24);
|
||||||
SHR32CLtoR( EBX );
|
xSUB(ecx, ebx);
|
||||||
|
xSHL(eax, cl);
|
||||||
|
xOR(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]], eax);
|
||||||
|
|
||||||
MOV32ItoR( ECX, 24 );
|
// eax will always have the sign bit
|
||||||
SUB32RtoR(ECX, EDX);
|
xCDQ();
|
||||||
SHL32CLtoR( EAX );// eax << ecx
|
xMOV(ptr32[&cpuRegs.GPR.r[_Rt_].UL[1]], edx);
|
||||||
|
|
||||||
_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
|
#else
|
||||||
|
|
||||||
iFlushCall(FLUSH_EXCEPTION);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
|
|
||||||
recCall(LWL);
|
recCall(LWL);
|
||||||
|
@ -351,165 +313,89 @@ void recLWL( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recLWR( void )
|
void recLWR(void)
|
||||||
{
|
{
|
||||||
if(!_Rt_) return;
|
|
||||||
#ifdef REC_LOADS
|
#ifdef REC_LOADS
|
||||||
iFlushCall(FLUSH_EXCEPTION);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
|
|
||||||
if( GPR_IS_CONST1( _Rs_ ) )
|
_eeMoveGPRtoR(ECX, _Rs_);
|
||||||
{
|
if (_Imm_ != 0)
|
||||||
u32 srcadr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_;
|
xADD(ecx, _Imm_);
|
||||||
u32 shift = srcadr & 0x3;
|
|
||||||
srcadr &= ~0x3;
|
|
||||||
//DevCon.Warning("LWR Const");
|
|
||||||
vtlb_DynGenRead32_Const( 32, true, srcadr );
|
|
||||||
|
|
||||||
if( GPR_IS_CONST1( _Rt_ ) )
|
// ebx = bit offset in word
|
||||||
{
|
xMOV(ebx, ecx);
|
||||||
int res = g_cpuConstRegs[_Rt_].UL[0] & LWR_MASK[shift];
|
xAND(ebx, 0x3);
|
||||||
MOV32ItoR( EDX, res );
|
xSHL(ebx, 3);
|
||||||
}
|
|
||||||
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);
|
xAND(ecx,~0x3);
|
||||||
AND32ItoR(EDX, 0x3);
|
vtlb_DynGenRead32(32, true);
|
||||||
SHL32ItoR(EDX, 3);
|
|
||||||
|
|
||||||
AND32ItoR(ECX,~0x3);
|
|
||||||
|
|
||||||
vtlb_DynGenRead32(32, true);
|
// mask off bytes loaded
|
||||||
MOV32RtoR(ECX, EDX);
|
xMOV(ecx, 24);
|
||||||
MOV32ItoR( EBX, 0xffffff00 );
|
xSUB(ecx, ebx);
|
||||||
SHR32CLtoR( EAX ); // eax << ecx
|
xMOV(edx, 0xffffff00);
|
||||||
|
xSHL(edx, cl);
|
||||||
|
xAND(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]], edx);
|
||||||
|
|
||||||
MOV32ItoR( ECX, 24 );
|
// OR in bytes loaded
|
||||||
SUB32RtoR(ECX, EDX);
|
xMOV(ecx, ebx);
|
||||||
SHL32CLtoR( EBX );// ebx << ecx
|
xSHR(eax, cl);
|
||||||
|
xOR(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]], eax);
|
||||||
_eeMoveGPRtoR(EDX, _Rt_);
|
|
||||||
|
|
||||||
AND32RtoR( EDX, EBX );
|
xCMP(ebx, 0);
|
||||||
|
xForwardJump8 nosignextend(Jcc_NotEqual);
|
||||||
OR32RtoR( EAX, EDX );
|
// if ((addr & 3) == 0)
|
||||||
}
|
xCDQ();
|
||||||
|
xMOV(ptr32[&cpuRegs.GPR.r[_Rt_].UL[1]], edx);
|
||||||
// EAX holds the loaded value, so sign extend as needed:
|
nosignextend.SetTarget();
|
||||||
CDQ();
|
#else
|
||||||
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
|
|
||||||
#else
|
|
||||||
iFlushCall(FLUSH_EXCEPTION);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
|
|
||||||
recCall(LWR);
|
recCall(LWR);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0x00000000 };
|
|
||||||
static const u32 SWR_MASK[4] = { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
|
|
||||||
|
|
||||||
static const u8 SWR_SHIFT[4] = { 0, 8, 16, 24 };
|
|
||||||
static const u8 SWL_SHIFT[4] = { 24, 16, 8, 0 };
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recSWL( void )
|
void recSWL(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef REC_STORES
|
#ifdef REC_STORES
|
||||||
iFlushCall(FLUSH_EXCEPTION);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
|
||||||
|
|
||||||
if( GPR_IS_CONST1( _Rs_ ) )
|
_eeMoveGPRtoR(ECX, _Rs_);
|
||||||
|
if (_Imm_ != 0)
|
||||||
|
xADD(ecx, _Imm_);
|
||||||
|
|
||||||
|
// ebx = bit offset in word
|
||||||
|
xMOV(ebx, ecx);
|
||||||
|
xAND(ebx, 0x3);
|
||||||
|
xSHL(ebx, 3);
|
||||||
|
|
||||||
|
xAND(ecx, ~0x3);
|
||||||
|
// edi = word address
|
||||||
|
xMOV(edi, ecx);
|
||||||
|
vtlb_DynGenRead32(32, false);
|
||||||
|
|
||||||
|
// mask read -> edx
|
||||||
|
xMOV(ecx, ebx);
|
||||||
|
xMOV(edx, 0xffffff00);
|
||||||
|
xSHL(edx, cl);
|
||||||
|
xAND(edx, eax);
|
||||||
|
|
||||||
|
if (_Rt_)
|
||||||
{
|
{
|
||||||
u32 addr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_;
|
// mask write and OR -> edx
|
||||||
u32 shift = addr & 3;
|
xMOV(ecx, 24);
|
||||||
vtlb_DynGenRead32_Const( 32, false, addr & ~3 );
|
xSUB(ecx, ebx);
|
||||||
|
_eeMoveGPRtoR(EAX, _Rt_);
|
||||||
// Prep eax/edx for producing the writeback result:
|
xSHR(eax, cl);
|
||||||
//DevCon.Warning("SWL Const");
|
xOR(edx, eax);
|
||||||
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 );
|
|
||||||
|
|
||||||
AND32ItoR( EAX, SWL_MASK[shift] );
|
|
||||||
OR32RtoR( EDX, EAX );
|
|
||||||
|
|
||||||
vtlb_DynGenWrite_Const( 32, addr & ~0x3 );
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
_eeMoveGPRtoR(ECX, _Rs_);
|
xMOV(ecx, edi);
|
||||||
//DevCon.Warning("SWL No Const");
|
vtlb_DynGenWrite(32);
|
||||||
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
|
#else
|
||||||
iFlushCall(FLUSH_EXCEPTION);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
|
@ -519,81 +405,43 @@ void recSWL( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recSWR( void )
|
void recSWR(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef REC_STORES
|
#ifdef REC_STORES
|
||||||
iFlushCall(FLUSH_EXCEPTION);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
_eeMoveGPRtoR(ECX, _Rs_);
|
||||||
if( GPR_IS_CONST1( _Rs_ ) )
|
if (_Imm_ != 0)
|
||||||
|
xADD(ecx, _Imm_);
|
||||||
|
|
||||||
|
// ebx = bit offset in word
|
||||||
|
xMOV(ebx, ecx);
|
||||||
|
xAND(ebx, 0x3);
|
||||||
|
xSHL(ebx, 3);
|
||||||
|
|
||||||
|
xAND(ecx, ~0x3);
|
||||||
|
// edi = word address
|
||||||
|
xMOV(edi, ecx);
|
||||||
|
vtlb_DynGenRead32(32, false);
|
||||||
|
|
||||||
|
// mask read -> edx
|
||||||
|
xMOV(ecx, 24);
|
||||||
|
xSUB(ecx, ebx);
|
||||||
|
xMOV(edx, 0xffffff);
|
||||||
|
xSHR(edx, cl);
|
||||||
|
xAND(edx, eax);
|
||||||
|
|
||||||
|
if(_Rt_)
|
||||||
{
|
{
|
||||||
u32 addr = g_cpuConstRegs[_Rs_].UL[0] + _Imm_;
|
// mask write and OR -> edx
|
||||||
u32 shift = addr & 3;
|
xMOV(ecx, ebx);
|
||||||
vtlb_DynGenRead32_Const( 32, false, addr & ~3 );
|
_eeMoveGPRtoR(EAX, _Rt_);
|
||||||
|
xSHL(eax, cl);
|
||||||
// Prep eax/edx for producing the writeback result:
|
xOR(edx, eax);
|
||||||
//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
|
xMOV(ecx, edi);
|
||||||
SHL32ItoR(EDX, 3); //Multiply by 8
|
vtlb_DynGenWrite(32);
|
||||||
|
|
||||||
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
|
#else
|
||||||
iFlushCall(FLUSH_EXCEPTION);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
|
@ -605,216 +453,38 @@ void recSWR( void )
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recLDL( void )
|
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);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
recCall(LDL);
|
recCall(LDL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recLDR( void )
|
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);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
recCall(LDR);
|
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 )
|
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);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
recCall(SDL);
|
recCall(SDL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recSDR( void )
|
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);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
recCall(SDR);
|
recCall(SDR);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -844,7 +514,7 @@ void recLWC1( void )
|
||||||
ADD32ItoR( ECX, _Imm_ );
|
ADD32ItoR( ECX, _Imm_ );
|
||||||
vtlb_DynGenRead32(32, false);
|
vtlb_DynGenRead32(32, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
MOV32RtoM( (int)&fpuRegs.fpr[ _Rt_ ].UL, EAX );
|
MOV32RtoM( (int)&fpuRegs.fpr[ _Rt_ ].UL, EAX );
|
||||||
#else
|
#else
|
||||||
iFlushCall(FLUSH_EXCEPTION);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
|
@ -912,7 +582,6 @@ void recSWC1( void )
|
||||||
|
|
||||||
void recLQC2( void )
|
void recLQC2( void )
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef NEWLQC
|
#ifdef NEWLQC
|
||||||
iFlushCall(FLUSH_EXCEPTION);
|
iFlushCall(FLUSH_EXCEPTION);
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
|
@ -934,7 +603,7 @@ void recLQC2( void )
|
||||||
MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
||||||
|
|
||||||
if ( _Imm_ != 0 )
|
if ( _Imm_ != 0 )
|
||||||
ADD32ItoR( ECX, _Imm_);
|
ADD32ItoR( ECX, _Imm_);
|
||||||
|
|
||||||
vtlb_DynGenRead64(128);
|
vtlb_DynGenRead64(128);
|
||||||
}
|
}
|
||||||
|
@ -993,7 +662,6 @@ void recSQC2( void )
|
||||||
MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] );
|
MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] );
|
||||||
vtlb_DynGenWrite(128);
|
vtlb_DynGenWrite(128);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue