mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
b9e372ec75
commit
d868edc17c
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 ); }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue