From 3bf7df410fa0749136a7d68ad6ab1dee1522a952 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Thu, 15 Jan 2009 22:03:37 +0000 Subject: [PATCH] Yay! Stack corruption bugs squashed! Much rejoicing! Pcsx2 is usable again! Oh, and emulation speeds are a good measure faster now too. git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@595 a6443dda-0b58-4228-96e9-037be469359c --- pcsx2/windows/VCprojects/pcsx2_2008.vcproj | 56 ------ pcsx2/x86/iCP0.cpp | 4 +- pcsx2/x86/ix86-32/iR5900-32.cpp | 222 +++++++-------------- pcsx2/x86/ix86-32/iR5900AritImm.cpp | 18 +- 4 files changed, 79 insertions(+), 221 deletions(-) diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index f3105f6bcd..e1975fbafc 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -1146,14 +1146,6 @@ UsePrecompiledHeader="2" /> - - - @@ -1194,14 +1186,6 @@ UsePrecompiledHeader="0" /> - - - @@ -1238,14 +1222,6 @@ UsePrecompiledHeader="2" /> - - - - - - @@ -1318,14 +1286,6 @@ UsePrecompiledHeader="0" /> - - - @@ -1362,14 +1322,6 @@ UsePrecompiledHeader="0" /> - - - @@ -1382,14 +1334,6 @@ - - - pFnptr || pblock->startpc != cpuRegs.pc ) { + if ( !pblock->pFnptr || pblock->startpc != cpuRegs.pc ) recRecompile(cpuRegs.pc); - } assert( pblock->pFnptr != 0 ); + g_EEFreezeRegs = true; - - // skip the POPs - -#ifdef _DEBUG - fnptr = (u8*)pblock->pFnptr; - -#ifdef _MSC_VER - __asm { - // save data - mov oldesi, esi - mov s_uSaveESP, esp - sub s_uSaveESP, 8 - mov s_uSaveEBP, ebp - push ebp - - call fnptr // jump into function - // restore data - pop ebp - mov esi, oldesi - } -#else - - __asm__("movl %%esi, %0\n" - "movl %%esp, %1\n" - "sub $8, %1\n" - "push %%ebp\n" - "call *%2\n" - "pop %%ebp\n" - "movl %0, %%esi\n" : "=m"(oldesi), "=m"(s_uSaveESP) : "c"(fnptr) ); -#endif // _MSC_VER - -#else - -#ifdef _MSC_VER - //pfn = ((R5900FNPTR)pblock->pFnptr); - __asm push ebp; // FIXME: need to preserve ebp or else the bios crashes, should find where ebp is getting corrupted instead. ((R5900FNPTR)pblock->pFnptr)(); - __asm pop ebp; // restore ebp for the reason above -#else - __asm__("push %%ebp\n"); - ((R5900FNPTR)pblock->pFnptr)(); - __asm__("pop %%ebp\n"); -#endif +#ifdef _MSC_VER + __asm popa; +#else + __asm__("popa\n"); #endif g_EEFreezeRegs = false; -} +}*/ void recStep( void ) { } @@ -663,28 +625,6 @@ static __forceinline bool recEventTest() return retval; } -__forceinline void recExecute() -{ - // Mem protection should be handled by the caller here so that it can be - // done in a more optimized fashion. - - while( true ) - { - //Console::WriteLn( "Begin Block Execution" ); - execute(); - //Console::WriteLn( "Cycle > %x", params cpuRegs.cycle ); - if( recEventTest() ) break; - } -} - -static void recExecuteBlock() -{ - PCSX2_MEM_PROTECT_BEGIN() - recEventTest(); - execute(); - PCSX2_MEM_PROTECT_END() -} - //////////////////////////////////////////////////// static u32 g_lastpc = 0; @@ -693,7 +633,8 @@ static u32 g_EEDispatchTemp; #ifdef _MSC_VER // jumped to when invalid pc address -__declspec(naked,noreturn) void Dispatcher() +// EDX contains the jump addr to modify +static __declspec(naked,noreturn) void Dispatcher() { // EDX contains the jump addr to modify __asm push edx @@ -702,11 +643,9 @@ __declspec(naked,noreturn) void Dispatcher() s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); __asm { - mov eax, s_pDispatchBlock - // check if startpc == cpuRegs.pc + mov eax, s_pDispatchBlock mov ecx, cpuRegs.pc - //and ecx, 0x5fffffff // remove higher bits cmp ecx, dword ptr [eax+BLOCKTYPE_STARTPC] je CheckPtr @@ -724,14 +663,6 @@ CheckPtr: assert( g_EEDispatchTemp ); #endif -// __asm { -// test eax, 0x40000000 // BLOCKTYPE_NEEDCLEAR -// jz Done -// // move new pc -// and eax, 0x0fffffff -// mov ecx, cpuRegs.pc -// mov dword ptr [eax+1], ecx -// } __asm { and eax, 0x0fffffff pop ecx // x86Ptr to mod @@ -744,7 +675,9 @@ CheckPtr: } } -__declspec(naked,noreturn) void DispatcherClear() +// edx - baseblock->startpc +// stack - x86Ptr +static __declspec(naked,noreturn) void DispatcherClear() { // EDX contains the current pc __asm mov cpuRegs.pc, edx @@ -753,7 +686,8 @@ __declspec(naked,noreturn) void DispatcherClear() // calc PC_GETBLOCK s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); - if( s_pDispatchBlock->startpc == cpuRegs.pc ) { + if( s_pDispatchBlock->startpc == cpuRegs.pc ) + { assert( s_pDispatchBlock->pFnptr != 0 ); // already modded the code, jump to the new place @@ -787,16 +721,13 @@ __declspec(naked,noreturn) void DispatcherClear() } // called when jumping to variable pc address -__declspec(naked,noreturn) void DispatcherReg() +static __declspec(naked,noreturn) void DispatcherReg() { - __asm { - //s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); - mov edx, cpuRegs.pc - mov ecx, edx - } + s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); - __asm { - shr edx, 14 + __asm + { + /*shr edx, 14 and edx, 0xfffffffc add edx, recLUT mov edx, dword ptr [edx] @@ -805,15 +736,22 @@ __declspec(naked,noreturn) void DispatcherReg() and eax, 0xfffc // edx += 2*eax shl eax, 1 - add edx, eax - - // check if startpc == cpuRegs.pc - mov eax, ecx - //and eax, 0x5fffffff // remove higher bits - cmp eax, dword ptr [edx+BLOCKTYPE_STARTPC] - jne recomp + add edx, eax*/ - mov eax, dword ptr [edx] + // check if startpc == cpuRegs.pc + mov eax, s_pDispatchBlock + mov ecx, cpuRegs.pc + cmp ecx, dword ptr [eax+BLOCKTYPE_STARTPC] + je CheckPtrReg + + // recompile + + push cpuRegs.pc // pc + call recRecompile + add esp, 4 // pop old param + mov eax, s_pDispatchBlock +CheckPtrReg: + mov eax, dword ptr [eax] } #ifdef _DEBUG @@ -823,22 +761,35 @@ __declspec(naked,noreturn) void DispatcherReg() __asm { and eax, 0x0fffffff - jmp eax // fnptr - -recomp: - sub esp, 8 - mov dword ptr [esp+4], edx - mov dword ptr [esp], ecx - call recRecompile - mov edx, dword ptr [esp+4] - add esp, 8 - - mov eax, dword ptr [edx] - and eax, 0x0fffffff - jmp eax // fnptr + jmp eax } } +__forceinline void recExecute() +{ + do { + __asm { + pushad + call DispatcherReg + popad + } + } + while( !recEventTest() ); +} + +static void recExecuteBlock() +{ + PCSX2_MEM_PROTECT_BEGIN() + __asm + { + pushad + call DispatcherReg + popad + } + recEventTest(); + PCSX2_MEM_PROTECT_END() +} + #else // _MSC_VER // Linux uses an assembly version of these routines. extern "C" { @@ -1616,7 +1567,7 @@ void __fastcall dyna_block_discard(u32 start,u32 sz) return; } -void recRecompile( u32 startpc ) +void recRecompile( const u32 startpc ) { u32 i = 0; u32 branchTo; @@ -1680,43 +1631,6 @@ void recRecompile( u32 startpc ) s_pCurBlock->pFnptr = (u32)x86Ptr; s_pCurBlock->startpc = startpc; - // slower -// if( startpc == 0x81fc0 ) { -// -// MOV32MtoR(ECX, (u32)&g_nextBranchCycle); -// MOV32RtoM((u32)&cpuRegs.cycle, ECX); -// //ADD32ItoR(ECX, 9); -// //ADD32ItoM((u32)&cpuRegs.cycle, 512); -// CALLFunc((uptr)cpuBranchTest); -// CMP32ItoM((u32)&cpuRegs.pc, 0x81fc0); -// JE8(s_pCurBlock->pFnptr - (u32)(x86Ptr+2) ); -// JMP32((u32)DispatcherReg - (u32)(x86Ptr+5)); -// -// pc = startpc + 9*4; -// assert( (pc-startpc)>>2 <= 0xffff ); -// s_pCurBlockEx->size = (pc-startpc)>>2; -// -// for(i = 1; i < (u32)s_pCurBlockEx->size-1; ++i) { -// s_pCurBlock[i].pFnptr = s_pCurBlock->pFnptr; -// s_pCurBlock[i].startpc = s_pCurBlock->startpc; -// } -// -// // don't overwrite if delay slot -// if( i < (u32)s_pCurBlockEx->size && !(s_pCurBlock[i].uType & BLOCKTYPE_DELAYSLOT) ) { -// s_pCurBlock[i].pFnptr = s_pCurBlock->pFnptr; -// s_pCurBlock[i].startpc = s_pCurBlock->startpc; -// } -// -// // set the block ptr -// AddBaseBlockEx(s_pCurBlockEx, 0); -// -// if( !(pc&0x10000000) ) -// maxrecmem = max( (pc&~0xa0000000), maxrecmem ); -// -// recPtr = x86Ptr; -// return; -// } - branch = 0; // reset recomp state variables diff --git a/pcsx2/x86/ix86-32/iR5900AritImm.cpp b/pcsx2/x86/ix86-32/iR5900AritImm.cpp index 3d0ad4cd22..2c9f5f3c7a 100644 --- a/pcsx2/x86/ix86-32/iR5900AritImm.cpp +++ b/pcsx2/x86/ix86-32/iR5900AritImm.cpp @@ -37,16 +37,16 @@ namespace OpcodeImpl namespace Interp = R5900::Interpreter::OpcodeImpl; -REC_FUNC(ADDI); -REC_FUNC(ADDIU); -REC_FUNC(DADDI); -REC_FUNC(DADDIU); -REC_FUNC(ANDI); -REC_FUNC(ORI); -REC_FUNC(XORI); +REC_FUNC_DEL(ADDI, _Rt_); +REC_FUNC_DEL(ADDIU, _Rt_); +REC_FUNC_DEL(DADDI, _Rt_); +REC_FUNC_DEL(DADDIU, _Rt_); +REC_FUNC_DEL(ANDI, _Rt_); +REC_FUNC_DEL(ORI, _Rt_); +REC_FUNC_DEL(XORI, _Rt_); -REC_FUNC(SLTI); -REC_FUNC(SLTIU); +REC_FUNC_DEL(SLTI, _Rt_); +REC_FUNC_DEL(SLTIU, _Rt_); #elif defined(EE_CONST_PROP)