mirror of https://github.com/PCSX2/pcsx2.git
Implemented some more vtlb optimizations: Regalloc should be working a bit better now, and removed some unneeded code on the LWL/SDL/etc interpreter callbacks.
Emitter: Added Rm/RmOffset forms for AND32 - Untested. I'm pretty sure they're valid instructions but I could be wrong. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@883 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
a0146d9db1
commit
4c8cf52c94
|
@ -103,8 +103,6 @@ struct SyncCounter
|
||||||
#define SCANLINES_VBLANK1_NTSC 19 // scanlines used for vblank1 (even interlace)
|
#define SCANLINES_VBLANK1_NTSC 19 // scanlines used for vblank1 (even interlace)
|
||||||
#define SCANLINES_VBLANK2_NTSC 20 // scanlines used for vblank2 (odd interlace)
|
#define SCANLINES_VBLANK2_NTSC 20 // scanlines used for vblank2 (odd interlace)
|
||||||
|
|
||||||
#define HSYNC_ERROR_NTSC ((s32)VSYNC_NTSC - (s32)(((HRENDER_TIME_NTSC+HBLANK_TIME_NTSC) * SCANLINES_TOTAL_NTSC)/2) )
|
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// PAL Timing Information!!! (some scanline info is guessed)
|
// PAL Timing Information!!! (some scanline info is guessed)
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -574,11 +574,10 @@ void LDR()
|
||||||
|
|
||||||
void LQ()
|
void LQ()
|
||||||
{
|
{
|
||||||
|
// MIPS Note: LQ and SQ are special and "silently" align memory addresses, thus
|
||||||
|
// an address error due to unaligned access isn't possible like it is on other loads/stores.
|
||||||
|
|
||||||
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
|
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
|
||||||
|
|
||||||
if( addr & 15 )
|
|
||||||
throw R5900Exception::AddressError( addr, false );
|
|
||||||
|
|
||||||
memRead128(addr & ~0xf, gpr_GetWritePtr(_Rt_));
|
memRead128(addr & ~0xf, gpr_GetWritePtr(_Rt_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,11 +703,10 @@ void SDR()
|
||||||
|
|
||||||
void SQ()
|
void SQ()
|
||||||
{
|
{
|
||||||
|
// MIPS Note: LQ and SQ are special and "silently" align memory addresses, thus
|
||||||
|
// an address error due to unaligned access isn't possible like it is on other loads/stores.
|
||||||
|
|
||||||
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
|
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
|
||||||
|
|
||||||
if( addr & 15 )
|
|
||||||
throw R5900Exception::AddressError( addr, true );
|
|
||||||
|
|
||||||
memWrite128(addr & ~0xf, &cpuRegs.GPR.r[_Rt_].UD[0]);
|
memWrite128(addr & ~0xf, &cpuRegs.GPR.r[_Rt_].UD[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -323,7 +323,9 @@ u32* _eeGetConstReg(int reg)
|
||||||
|
|
||||||
void _eeMoveGPRtoR(x86IntRegType to, int fromgpr)
|
void _eeMoveGPRtoR(x86IntRegType to, int fromgpr)
|
||||||
{
|
{
|
||||||
if( GPR_IS_CONST1(fromgpr) )
|
if( fromgpr == 0 )
|
||||||
|
XOR32RtoR( to, to ); // zero register should use xor, thanks --air
|
||||||
|
else if( GPR_IS_CONST1(fromgpr) )
|
||||||
MOV32ItoR( to, g_cpuConstRegs[fromgpr].UL[0] );
|
MOV32ItoR( to, g_cpuConstRegs[fromgpr].UL[0] );
|
||||||
else {
|
else {
|
||||||
int mmreg;
|
int mmreg;
|
||||||
|
|
|
@ -2070,6 +2070,8 @@ void SetFastMemory(int bSetFast)
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
void recLoad64( u32 bits, bool sign )
|
void recLoad64( u32 bits, bool sign )
|
||||||
{
|
{
|
||||||
jASSUME( bits == 64 || bits == 128 );
|
jASSUME( bits == 64 || bits == 128 );
|
||||||
|
@ -2096,22 +2098,23 @@ void recLoad64( u32 bits, bool sign )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
// Load ECX with the source memory address that we're reading from.
|
// Load ECX with the source memory address that we're reading from.
|
||||||
MOV32MtoR( ECX, (uptr)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
_eeMoveGPRtoR(ECX, _Rs_);
|
||||||
|
if ( _Imm_ != 0 )
|
||||||
|
ADD32ItoR( ECX, _Imm_ );
|
||||||
|
if( bits == 128 ) // force 16 byte alignment on 128 bit reads
|
||||||
|
AND32I8toR(ECX,0xF0);
|
||||||
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
_eeOnLoadWrite(_Rt_);
|
||||||
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
|
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
|
||||||
_deleteEEreg(_Rt_, 0);
|
_deleteEEreg(_Rt_, 0);
|
||||||
if ( _Imm_ != 0 )
|
|
||||||
ADD32ItoR( ECX, _Imm_ );
|
|
||||||
|
|
||||||
if( bits == 128 ) // force 16 byte alignment on 128 bit reads
|
|
||||||
AND32I8toR(ECX,0xF0);
|
|
||||||
|
|
||||||
vtlb_DynGenRead64(bits);
|
vtlb_DynGenRead64(bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
void recLoad32( u32 bits, bool sign )
|
void recLoad32( u32 bits, bool sign )
|
||||||
{
|
{
|
||||||
jASSUME( bits <= 32 );
|
jASSUME( bits <= 32 );
|
||||||
|
@ -2131,14 +2134,13 @@ void recLoad32(u32 bits,bool sign)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
// Load ECX with the source memory address that we're reading from.
|
// Load ECX with the source memory address that we're reading from.
|
||||||
MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
_eeMoveGPRtoR(ECX, _Rs_);
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
if ( _Imm_ != 0 )
|
if ( _Imm_ != 0 )
|
||||||
ADD32ItoR( ECX, _Imm_ );
|
ADD32ItoR( ECX, _Imm_ );
|
||||||
|
|
||||||
|
_eeOnLoadWrite(_Rt_);
|
||||||
|
_deleteEEreg(_Rt_, 0);
|
||||||
vtlb_DynGenRead32(bits, sign);
|
vtlb_DynGenRead32(bits, sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2155,338 +2157,32 @@ void recLoad32(u32 bits,bool sign)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
void recLB( void )
|
//
|
||||||
|
|
||||||
|
// edxAlreadyAssigned - set to true if edx already holds the value being written (used by SWL/SWR)
|
||||||
|
void recStore(u32 sz, bool edxAlreadyAssigned=false)
|
||||||
{
|
{
|
||||||
recLoad32(8,true);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
|
||||||
{
|
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
|
||||||
PUSH32I( (int)&dummyValue[0] );
|
|
||||||
PUSH32R( EAX );
|
|
||||||
|
|
||||||
CALLFunc( (int)memRead8 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
if ( _Rt_ )
|
|
||||||
{
|
|
||||||
u8* linkEnd;
|
|
||||||
TEST32RtoR( EAX, EAX );
|
|
||||||
linkEnd = JNZ8( 0 );
|
|
||||||
MOV32MtoR( EAX, (int)&dummyValue[0] );
|
|
||||||
MOVSX32R8toR( EAX, EAX );
|
|
||||||
CDQ( );
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
|
|
||||||
x86SetJ8( linkEnd );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
void recLBU( void )
|
|
||||||
{
|
|
||||||
recLoad32(8,false);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
|
||||||
{
|
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
|
||||||
PUSH32I( (int)&dummyValue[0] );
|
|
||||||
PUSH32R( EAX );
|
|
||||||
|
|
||||||
CALLFunc( (int)memRead8 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
if ( _Rt_ )
|
|
||||||
{
|
|
||||||
u8* linkEnd;
|
|
||||||
TEST32RtoR( EAX, EAX );
|
|
||||||
linkEnd = JNZ8( 0 );
|
|
||||||
MOV32MtoR( EAX, (int)&dummyValue[0] );
|
|
||||||
MOVZX32R8toR( EAX, EAX );
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
|
|
||||||
MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 );
|
|
||||||
x86SetJ8( linkEnd );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
void recLH( void )
|
|
||||||
{
|
|
||||||
recLoad32(16,true);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
|
||||||
{
|
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
|
||||||
PUSH32I( (int)&dummyValue[0] );
|
|
||||||
PUSH32R( EAX );
|
|
||||||
|
|
||||||
CALLFunc( (int)memRead16 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
if ( _Rt_ )
|
|
||||||
{
|
|
||||||
u8* linkEnd;
|
|
||||||
TEST32RtoR( EAX, EAX );
|
|
||||||
linkEnd = JNZ8( 0 );
|
|
||||||
MOV32MtoR( EAX, (int)&dummyValue[0]);
|
|
||||||
MOVSX32R16toR( EAX, EAX );
|
|
||||||
CDQ( );
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
|
|
||||||
x86SetJ8( linkEnd );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
void recLHU( void )
|
|
||||||
{
|
|
||||||
recLoad32(16,false);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
|
||||||
{
|
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
|
||||||
PUSH32I( (int)&dummyValue[0] );
|
|
||||||
PUSH32R( EAX );
|
|
||||||
CALLFunc( (int)memRead16 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
if ( _Rt_ )
|
|
||||||
{
|
|
||||||
u8* linkEnd;
|
|
||||||
TEST32RtoR( EAX, EAX );
|
|
||||||
linkEnd = JNZ8( 0 );
|
|
||||||
MOV32MtoR( EAX, (int)&dummyValue[0] );
|
|
||||||
MOVZX32R16toR( EAX, EAX );
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
|
|
||||||
MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 );
|
|
||||||
x86SetJ8( linkEnd );
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
void recLW( void )
|
|
||||||
{
|
|
||||||
recLoad32(32,true);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
|
||||||
{
|
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
PUSH32I( (int)&dummyValue[0]);
|
|
||||||
PUSH32R( EAX );
|
|
||||||
|
|
||||||
CALLFunc( (int)memRead32 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
|
|
||||||
if ( _Rt_ )
|
|
||||||
{
|
|
||||||
u8* linkEnd;
|
|
||||||
TEST32RtoR( EAX, EAX );
|
|
||||||
linkEnd = JNZ8( 0 );
|
|
||||||
MOV32MtoR( EAX, (int)&dummyValue[0]);
|
|
||||||
CDQ( );
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
|
|
||||||
x86SetJ8( linkEnd );
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
void recLWU( void )
|
|
||||||
{
|
|
||||||
recLoad32(32,false);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
|
||||||
{
|
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
PUSH32I( (int)&dummyValue[0]);
|
|
||||||
PUSH32R( EAX );
|
|
||||||
CALLFunc( (int)memRead32 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
if ( _Rt_ )
|
|
||||||
{
|
|
||||||
u8* linkEnd;
|
|
||||||
TEST32RtoR( EAX, EAX );
|
|
||||||
linkEnd = JNZ8( 0 );
|
|
||||||
MOV32MtoR( EAX, (int)&dummyValue[0]);
|
|
||||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
|
|
||||||
MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 );
|
|
||||||
x86SetJ8( linkEnd );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
void recLWL( void )
|
|
||||||
{
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
|
||||||
MOV32ItoM( (int)&cpuRegs.pc, pc );
|
|
||||||
CALLFunc( (int)LWL );
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
void recLWR( void )
|
|
||||||
{
|
|
||||||
iFlushCall(FLUSH_EVERYTHING);
|
|
||||||
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
|
||||||
MOV32ItoM( (int)&cpuRegs.pc, pc );
|
|
||||||
CALLFunc( (int)LWR );
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
extern void MOV64RmtoR( x86IntRegType to, x86IntRegType from );
|
|
||||||
|
|
||||||
void recLD( void )
|
|
||||||
{
|
|
||||||
recLoad64(64,false);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
|
||||||
{
|
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( _Rt_ )
|
|
||||||
{
|
|
||||||
PUSH32I( (int)&cpuRegs.GPR.r[ _Rt_ ].UD[ 0 ] );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PUSH32I( (int)&dummyValue[0] );
|
|
||||||
}
|
|
||||||
PUSH32R( EAX );
|
|
||||||
CALLFunc( (int)memRead64 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
void recLDL( void )
|
|
||||||
{
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
|
||||||
MOV32ItoM( (int)&cpuRegs.pc, pc );
|
|
||||||
CALLFunc( (int)LDL );
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
void recLDR( void )
|
|
||||||
{
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
|
||||||
MOV32ItoM( (int)&cpuRegs.pc, pc );
|
|
||||||
CALLFunc( (int)LDR );
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
void recLQ( void )
|
|
||||||
{
|
|
||||||
recLoad64(128,false);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_eeOnLoadWrite(_Rt_);
|
|
||||||
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
|
|
||||||
_deleteEEreg(_Rt_, 0);
|
|
||||||
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
|
||||||
{
|
|
||||||
ADD32ItoR( EAX, _Imm_);
|
|
||||||
}
|
|
||||||
AND32ItoR( EAX, ~0xf );
|
|
||||||
|
|
||||||
if ( _Rt_ )
|
|
||||||
{
|
|
||||||
PUSH32I( (int)&cpuRegs.GPR.r[ _Rt_ ].UD[ 0 ] );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PUSH32I( (int)&dummyValue[0] );
|
|
||||||
}
|
|
||||||
PUSH32R( EAX );
|
|
||||||
CALLFunc( (int)memRead128 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void recStore(u32 sz)
|
|
||||||
{
|
|
||||||
//no int 3? i love to get my hands dirty ;p - Raz
|
|
||||||
//write8(0xCC);
|
|
||||||
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
|
||||||
|
|
||||||
// Performance note: Const prop for the store address is good, always.
|
// 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
|
// Constprop for the value being stored is not really worthwhile (better to use register
|
||||||
// allocation -- simpler code and just as fast)
|
// allocation -- simpler code and just as fast)
|
||||||
|
|
||||||
|
|
||||||
// Load EDX first with the value being written, or the address of the value
|
// 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
|
// being written (64/128 bit modes). TODO: use register allocation, if the
|
||||||
// value is allocated to a register.
|
// value is allocated to a register.
|
||||||
|
|
||||||
|
if( !edxAlreadyAssigned )
|
||||||
|
{
|
||||||
if( sz < 64 )
|
if( sz < 64 )
|
||||||
{
|
{
|
||||||
if (_Rt_)
|
_eeMoveGPRtoR(EDX, _Rt_);
|
||||||
MOV32MtoR(EDX,(int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]);
|
|
||||||
else
|
|
||||||
XOR32RtoR(EDX,EDX);
|
|
||||||
}
|
}
|
||||||
else if (sz==128 || sz==64)
|
else if (sz==128 || sz==64)
|
||||||
{
|
{
|
||||||
|
_deleteEEreg(_Rt_, 1); // flush register to mem
|
||||||
MOV32ItoR(EDX,(int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]);
|
MOV32ItoR(EDX,(int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load ECX with the destination address, or issue a direct optimized write
|
// Load ECX with the destination address, or issue a direct optimized write
|
||||||
// if the address is a constant propagation.
|
// if the address is a constant propagation.
|
||||||
|
@ -2499,11 +2195,10 @@ void recStore(u32 sz)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_deleteEEreg(_Rs_, 1);
|
_eeMoveGPRtoR(ECX, _Rs_);
|
||||||
MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
if ( _Imm_ != 0 )
|
||||||
ADD32ItoR(ECX, _Imm_);
|
ADD32ItoR(ECX, _Imm_);
|
||||||
|
|
||||||
if (sz==128)
|
if (sz==128)
|
||||||
AND32I8toR(ECX,0xF0);
|
AND32I8toR(ECX,0xF0);
|
||||||
|
|
||||||
|
@ -2511,75 +2206,95 @@ void recStore(u32 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 recSB( void ) { recStore(8); }
|
||||||
|
void recSH( void ) { recStore(16); }
|
||||||
|
void recSW( void ) { recStore(32); }
|
||||||
|
void recSQ( void ) { recStore(128); }
|
||||||
|
void recSD( void ) { recStore(64); }
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Non-recompiled Implementations Start Here -->
|
||||||
|
// (LWL/SWL, LWR/SWR, etc)
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recSB( void )
|
void recLWL( void )
|
||||||
{
|
{
|
||||||
recStore(8);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
|
_eeOnLoadWrite(_Rt_);
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
||||||
{
|
//MOV32ItoM( (int)&cpuRegs.pc, pc );
|
||||||
ADD32ItoR( EAX, _Imm_);
|
CALLFunc( (int)LWL );
|
||||||
}
|
|
||||||
PUSH32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
|
||||||
PUSH32R( EAX );
|
|
||||||
CALLFunc( (int)memWrite8 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recSH( void )
|
void recLWR( void )
|
||||||
{
|
{
|
||||||
recStore(16);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
|
_eeOnLoadWrite(_Rt_);
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
||||||
if ( _Imm_ != 0 )
|
//MOV32ItoM( (int)&cpuRegs.pc, pc );
|
||||||
{
|
CALLFunc( (int)LWR );
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
|
||||||
PUSH32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
|
||||||
PUSH32R( EAX );
|
|
||||||
CALLFunc( (int)memWrite16 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
static const u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0x00000000 };
|
||||||
void recSW( void )
|
static const u32 SWR_MASK[4] = { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
|
||||||
{
|
|
||||||
recStore(32);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
|
||||||
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
static const u8 SWR_SHIFT[4] = { 0, 8, 16, 24 };
|
||||||
if ( _Imm_ != 0 )
|
static const u8 SWL_SHIFT[4] = { 24, 16, 8, 0 };
|
||||||
{
|
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
PUSH32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
|
||||||
PUSH32R( EAX );
|
|
||||||
CALLFunc( (int)memWrite32 );
|
|
||||||
ADD32ItoR( ESP, 8 );
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recSWL( void )
|
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_ ) )
|
||||||
|
{
|
||||||
|
_eeOnLoadWrite(_Rt_);
|
||||||
|
//_deleteEEreg(_Rt_, 0);
|
||||||
|
|
||||||
|
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:
|
||||||
|
// equiv to: (cpuRegs.GPR.r[_Rt_].UL[0] >> SWL_SHIFT[shift]) | (mem & SWL_MASK[shift])
|
||||||
|
|
||||||
|
//_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] );
|
||||||
|
OR32RtoR( EDX, EAX );
|
||||||
|
|
||||||
|
recStore( 32, true );
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
||||||
MOV32ItoM( (int)&cpuRegs.pc, pc );
|
//MOV32ItoM( (int)&cpuRegs.pc, pc ); // pc's not needed by SWL
|
||||||
CALLFunc( (int)SWL );
|
CALLFunc( (int)SWL );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recSWR( void )
|
void recSWR( void )
|
||||||
|
@ -2587,29 +2302,32 @@ void recSWR( void )
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
||||||
MOV32ItoM( (int)&cpuRegs.pc, pc );
|
//MOV32ItoM( (int)&cpuRegs.pc, pc );
|
||||||
CALLFunc( (int)SWR );
|
CALLFunc( (int)SWR );
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recSD( void )
|
void recLDL( void )
|
||||||
{
|
{
|
||||||
recStore(64);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
|
_eeOnLoadWrite(_Rt_);
|
||||||
|
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
||||||
if ( _Imm_ != 0 )
|
//MOV32ItoM( (int)&cpuRegs.pc, pc );
|
||||||
{
|
CALLFunc( (int)LDL );
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PUSH32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ] );
|
////////////////////////////////////////////////////
|
||||||
PUSH32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
void recLDR( void )
|
||||||
PUSH32R( EAX );
|
{
|
||||||
CALLFunc( (int)memWrite64 );
|
_deleteEEreg(_Rs_, 1);
|
||||||
ADD32ItoR( ESP, 12 );
|
_eeOnLoadWrite(_Rt_);
|
||||||
*/
|
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
|
||||||
|
_deleteEEreg(_Rt_, 1);
|
||||||
|
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
||||||
|
//MOV32ItoM( (int)&cpuRegs.pc, pc );
|
||||||
|
CALLFunc( (int)LDR );
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
|
@ -2618,7 +2336,7 @@ void recSDL( void )
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
||||||
MOV32ItoM( (int)&cpuRegs.pc, pc );
|
//MOV32ItoM( (int)&cpuRegs.pc, pc );
|
||||||
CALLFunc( (int)SDL );
|
CALLFunc( (int)SDL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2628,30 +2346,11 @@ void recSDR( void )
|
||||||
_deleteEEreg(_Rs_, 1);
|
_deleteEEreg(_Rs_, 1);
|
||||||
_deleteEEreg(_Rt_, 1);
|
_deleteEEreg(_Rt_, 1);
|
||||||
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
|
||||||
MOV32ItoM( (int)&cpuRegs.pc, pc );
|
//MOV32ItoM( (int)&cpuRegs.pc, pc );
|
||||||
CALLFunc( (int)SDR );
|
CALLFunc( (int)SDR );
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
void recSQ( void )
|
|
||||||
{
|
|
||||||
recStore(128);
|
|
||||||
/*
|
|
||||||
_deleteEEreg(_Rs_, 1);
|
|
||||||
_deleteEEreg(_Rt_, 1);
|
|
||||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
|
||||||
if ( _Imm_ != 0 )
|
|
||||||
{
|
|
||||||
ADD32ItoR( EAX, _Imm_ );
|
|
||||||
}
|
|
||||||
AND32ItoR( EAX, ~0xf );
|
|
||||||
|
|
||||||
PUSH32I( (int)&cpuRegs.GPR.r[ _Rt_ ].UD[ 0 ] );
|
|
||||||
PUSH32R( EAX );
|
|
||||||
CALLFunc( (int)memWrite128 );
|
|
||||||
ADD32ItoR( ESP, 8 );*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
* Load and store for COP1 *
|
* Load and store for COP1 *
|
||||||
* Format: OP rt, offset(base) *
|
* Format: OP rt, offset(base) *
|
||||||
|
@ -2667,8 +2366,6 @@ void recLWC1( void )
|
||||||
if ( _Imm_ != 0 )
|
if ( _Imm_ != 0 )
|
||||||
ADD32ItoR( ECX, _Imm_ );
|
ADD32ItoR( ECX, _Imm_ );
|
||||||
|
|
||||||
//MOV32ItoR(EDX, (int)&fpuRegs.fpr[ _Rt_ ].UL ); //no 0 for fpu ?
|
|
||||||
//CALLFunc( (int)memRead32 );
|
|
||||||
vtlb_DynGenRead32(32, false);
|
vtlb_DynGenRead32(32, false);
|
||||||
MOV32RtoM( (int)&fpuRegs.fpr[ _Rt_ ].UL, EAX );
|
MOV32RtoM( (int)&fpuRegs.fpr[ _Rt_ ].UL, EAX );
|
||||||
}
|
}
|
||||||
|
|
|
@ -2344,6 +2344,22 @@ emitterT void eAND32MtoR( x86IntRegType to, uptr from )
|
||||||
write32<I>( MEMADDR(from, 4) );
|
write32<I>( MEMADDR(from, 4) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warning: Untested form of AND.
|
||||||
|
emitterT void eAND32RmtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
RexRB(0,to,from);
|
||||||
|
write8<I>( 0x23 );
|
||||||
|
ModRM<I>( 0, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning: Untested form of AND.
|
||||||
|
emitterT void eAND32RmtoROffset( x86IntRegType to, x86IntRegType from, int offset )
|
||||||
|
{
|
||||||
|
RexRB(0,to,from);
|
||||||
|
write16<I>( 0x23 );
|
||||||
|
WriteRmOffsetFrom<I>(to,from,offset);
|
||||||
|
}
|
||||||
|
|
||||||
// and r16 to r16
|
// and r16 to r16
|
||||||
emitterT void eAND16RtoR( x86IntRegType to, x86IntRegType from )
|
emitterT void eAND16RtoR( x86IntRegType to, x86IntRegType from )
|
||||||
{
|
{
|
||||||
|
|
|
@ -274,6 +274,8 @@
|
||||||
#define AND32RtoR eAND32RtoR<_EmitterId_>
|
#define AND32RtoR eAND32RtoR<_EmitterId_>
|
||||||
#define AND32RtoM eAND32RtoM<_EmitterId_>
|
#define AND32RtoM eAND32RtoM<_EmitterId_>
|
||||||
#define AND32MtoR eAND32MtoR<_EmitterId_>
|
#define AND32MtoR eAND32MtoR<_EmitterId_>
|
||||||
|
#define AND32RmtoR eAND32RmtoR<_EmitterId_>
|
||||||
|
#define AND32RmtoROffset eAND32RmtoROffset<_EmitterId_>
|
||||||
#define AND16RtoR eAND16RtoR<_EmitterId_>
|
#define AND16RtoR eAND16RtoR<_EmitterId_>
|
||||||
#define AND16ItoR eAND16ItoR<_EmitterId_>
|
#define AND16ItoR eAND16ItoR<_EmitterId_>
|
||||||
#define AND16ItoM eAND16ItoM<_EmitterId_>
|
#define AND16ItoM eAND16ItoM<_EmitterId_>
|
||||||
|
|
Loading…
Reference in New Issue