Recompiler Bugfix: for crashes in Ace Combat 4, and likely other games that use COP2 extensively.

Explanation: EBP was being used by mVU macro-mode (COP2), which violated the new EErec aligned stack setup.  ie, register/stack corruption resulted.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2123 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-11-03 20:35:40 +00:00
parent b9e372ec75
commit d868edc17c
3 changed files with 32 additions and 14 deletions

View File

@ -41,6 +41,9 @@ class Group2ImplAll
public:
template< typename T > __forceinline void operator()( const xRegister<T>& to, const xRegisterCL& /* from */ ) const
{
//if( !Is8BitOp<T>() )
// pxAssert( to != xRegister<T>( ebp.Id ) );
prefix16<T>();
xWrite8( Is8BitOp<T>() ? 0xd2 : 0xd3 );
EmitSibMagic( InstType, to );
@ -76,6 +79,9 @@ public:
{
if( imm == 0 ) return;
//if( !Is8BitOp<T>() )
// pxAssert( to != xRegister<T>( ebp.Id ) );
prefix16<T>();
if( imm == 1 )
{

View File

@ -218,14 +218,18 @@ class MovExtendImplAll
protected:
static const u16 Opcode = 0xb6 | (SignExtend ? 8 : 0 );
// Macro useful for trapping unwanted use of EBP.
//#define EbpAssert() pxAssert( to != ebp )
#define EbpAssert()
public:
__forceinline void operator()( const xRegister32& to, const xRegister16& from ) const { xOpWrite0F( Opcode+1, to, from ); }
__noinline void operator()( const xRegister32& to, const ModSibStrict<u16>& sibsrc ) const { xOpWrite0F( Opcode+1, to, sibsrc ); }
__noinline void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const { _DoI_helpermess( *this, to, src ); }
__forceinline void operator()( const xRegister32& to, const xRegister16& from ) const { EbpAssert(); xOpWrite0F( Opcode+1, to, from ); }
__noinline void operator()( const xRegister32& to, const ModSibStrict<u16>& sibsrc ) const { EbpAssert(); xOpWrite0F( Opcode+1, to, sibsrc ); }
__noinline void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const { EbpAssert(); _DoI_helpermess( *this, to, src ); }
__forceinline void operator()( const xRegister32& to, const xRegister8& from ) const { xOpWrite0F( Opcode, to, from ); }
__noinline void operator()( const xRegister32& to, const ModSibStrict<u8>& sibsrc ) const { xOpWrite0F( Opcode, to, sibsrc ); }
__noinline void operator()( const xRegister32& to, const xDirectOrIndirect8& src ) const { _DoI_helpermess( *this, to, src ); }
__forceinline void operator()( const xRegister32& to, const xRegister8& from ) const { EbpAssert(); xOpWrite0F( Opcode, to, from ); }
__noinline void operator()( const xRegister32& to, const ModSibStrict<u8>& sibsrc ) const { EbpAssert(); xOpWrite0F( Opcode, to, sibsrc ); }
__noinline void operator()( const xRegister32& to, const xDirectOrIndirect8& src ) const { EbpAssert(); _DoI_helpermess( *this, to, src ); }
__forceinline void operator()( const xRegister16& to, const xRegister8& from ) const { xOpWrite0F( 0x66, Opcode, to, from ); }
__noinline void operator()( const xRegister16& to, const ModSibStrict<u8>& sibsrc ) const { xOpWrite0F( 0x66, Opcode, to, sibsrc ); }

View File

@ -76,24 +76,32 @@ microVUt(void) mVUallocSFLAGc(int reg, int regT, int fInstance) {
// Denormalizes Status Flag
microVUt(void) mVUallocSFLAGd(uptr memAddr, bool setAllflags) {
// Cannot use EBP (gprF1) here; as this function is used by mVU0 macro and
// the EErec needs EBP preserved.
MOV32MtoR(gprF0, memAddr);
MOV32RtoR(gprF1, gprF0);
SHR32ItoR(gprF1, 3);
AND32ItoR(gprF1, 0x18);
MOV32RtoR(gprF3, gprF0);
SHR32ItoR(gprF3, 3);
AND32ItoR(gprF3, 0x18);
MOV32RtoR(gprF2, gprF0);
SHL32ItoR(gprF2, 11);
AND32ItoR(gprF2, 0x1800);
OR32RtoR (gprF1, gprF2);
OR32RtoR (gprF3, gprF2);
SHL32ItoR(gprF0, 14);
AND32ItoR(gprF0, 0x3cf0000);
OR32RtoR (gprF1, gprF0);
OR32RtoR (gprF3, gprF0);
if (setAllflags) {
MOV32RtoR(gprF0, gprF1);
MOV32RtoR(gprF2, gprF1);
MOV32RtoR(gprF3, gprF1);
// this code should be run in mVU micro mode only, so writing to
// EBP (gprF1) is ok (and needed for vuMicro optimizations).
MOV32RtoR(gprF0, gprF3);
MOV32RtoR(gprF1, gprF3);
MOV32RtoR(gprF2, gprF3);
}
}