rendered paste bodyIndex: pcsx2/x86/BaseblockEx.h===================================================================--- pcsx2/x86/BaseblockEx.h (revision 685)+++ pcsx2/x86/BaseblockEx.h (working copy)@@ -20,7 +20,6 @@ #define _BASEBLOCKEX_H_ // used to keep block information-#define BLOCKTYPE_STARTPC 4 // startpc offset #define BLOCKTYPE_DELAYSLOT 1 // if bit set, delay slot // Every potential jump point in the PS2's addressable memory has a BASEBLOCK@@ -28,17 +27,14 @@ // addressable memory. Yay! struct BASEBLOCK {- u32 m_pFnptr : 28;- u32 uType : 4;- u32 startpc;+ u32 m_pFnptr;+ u32 startpc : 30;+ u32 uType : 2; - const uptr GetFnptr() const { return ((u32)m_pFnptr)<<4; }- void SetFnptr( uptr ptr )- {- // 16 byte alignments only, please!- jASSUME( (ptr & 0xf) == 0 );- m_pFnptr = ptr>>4;- }+ const __inline uptr GetFnptr() const { return m_pFnptr; }+ void __inline SetFnptr( uptr ptr ) { m_pFnptr = ptr; }+ const __inline uptr GetStartPC() const { return startpc << 2; }+ void __inline SetStartPC( uptr pc ) { startpc = pc >> 2; } }; // extra block info (only valid for start of fn)@@ -60,7 +56,10 @@ // This is an asinine macro that bases indexing on sizeof(BASEBLOCK) for no reason. (air) #define GET_BLOCKTYPE(b) ((b)->Type)-#define PC_GETBLOCK_(x, reclut) ((BASEBLOCK*)(reclut[((u32)(x)) >> 16] + (sizeof(BASEBLOCK)/4)*((x) & 0xffff)))+// x * (sizeof(BASEBLOCK) / 4) sacrifices safety for speed compared to+// x / 4 * sizeof(BASEBLOCK) or a higher level approach.+#define PC_GETBLOCK_(x, reclut) ((BASEBLOCK*)(reclut[((u32)(x)) >> 16] + (x)*(sizeof(BASEBLOCK)/4)))+#define RECLUT_SETPAGE(reclut, page, p) do { reclut[page] = (uptr)(p) - ((page) << 14) * sizeof(BASEBLOCK); } while (0) // This is needed because of the retarded GETBLOCK macro above. C_ASSERT( sizeof(BASEBLOCK) == 8 );Index: pcsx2/x86/iR3000A.cpp===================================================================--- pcsx2/x86/iR3000A.cpp (revision 685)+++ pcsx2/x86/iR3000A.cpp (working copy)@@ -44,7 +44,7 @@ u32 g_psxMaxRecMem = 0; u32 s_psxrecblocks[] = {0}; -uptr *psxRecLUT;+uptr psxRecLUT[0x10000]; #define PSX_NUMBLOCKS (1<<12) #define MAPBASE 0x48000000@@ -101,7 +101,7 @@ #define PSX_GETBLOCK(x) PC_GETBLOCK_(x, psxRecLUT) #define PSXREC_CLEARM(mem) { \- if ((mem) < g_psxMaxRecMem && psxRecLUT[(mem) >> 16]) { \+ if ((mem) < g_psxMaxRecMem && (psxRecLUT[(mem) >> 16] + mem)) { \ BASEBLOCK* p = PSX_GETBLOCK(mem); \ if( *(u32*)p ) psxRecClearMem(p); \ } \@@ -114,7 +114,7 @@ // return pex; // otherwise, use the sorted list- return GetBaseBlockEx(p->startpc, 1);+ return GetBaseBlockEx(p->GetStartPC(), 1); } ////////////////////////////////////////////////////@@ -546,9 +546,6 @@ if( recMem == NULL ) throw Exception::OutOfMemory( "R3000a Init > failed to allocate memory for the recompiler." ); - if( psxRecLUT == NULL )- psxRecLUT = (uptr*) malloc(0x010000 * sizeof(uptr));- // Goal: Allocate BASEBLOCKs for every possible branch target in IOP memory. // Any 4-byte aligned address makes a valid branch target as per MIPS design (all instructions are // always 4 bytes long).@@ -586,7 +583,7 @@ DbgCon::Status( "iR3000A > Resetting recompiler memory and structures!" ); - memzero_ptr<0x010000 * sizeof(uptr)>( psxRecLUT );+ memzero_ptr<sizeof(psxRecLUT)>( psxRecLUT ); memset_8<0xcd,RECMEM_SIZE>( recMem ); memzero_ptr<m_recBlockAllocSize>( m_recBlockAlloc ); @@ -594,23 +591,23 @@ // 0x80 comes from : (Ps2MemSize::IopRam / 0x10000) * 4 for (int i=0; i<0x80; i++) {- psxRecLUT[i + 0x0000] = (uptr)&recRAM[(i & 0x1f) << 14];- psxRecLUT[i + 0x8000] = (uptr)&recRAM[(i & 0x1f) << 14];- psxRecLUT[i + 0xa000] = (uptr)&recRAM[(i & 0x1f) << 14];+ RECLUT_SETPAGE(psxRecLUT, i + 0x0000, &recRAM[(i & 0x1f) << 14]);+ RECLUT_SETPAGE(psxRecLUT, i + 0x8000, &recRAM[(i & 0x1f) << 14]);+ RECLUT_SETPAGE(psxRecLUT, i + 0xa000, &recRAM[(i & 0x1f) << 14]); } for (int i=0; i<(Ps2MemSize::Rom / 0x10000); i++) {- psxRecLUT[i + 0x1fc0] = (uptr)&recROM[i << 14];- psxRecLUT[i + 0x9fc0] = (uptr)&recROM[i << 14];- psxRecLUT[i + 0xbfc0] = (uptr)&recROM[i << 14];+ RECLUT_SETPAGE(psxRecLUT, i + 0x1fc0, &recROM[i << 14]);+ RECLUT_SETPAGE(psxRecLUT, i + 0x9fc0, &recROM[i << 14]);+ RECLUT_SETPAGE(psxRecLUT, i + 0xbfc0, &recROM[i << 14]); } for (int i=0; i<(Ps2MemSize::Rom1 / 0x10000); i++) {- psxRecLUT[i + 0x1e00] = (uptr)&recROM1[i << 14];- psxRecLUT[i + 0x9e00] = (uptr)&recROM1[i << 14];- psxRecLUT[i + 0xbe00] = (uptr)&recROM1[i << 14];+ RECLUT_SETPAGE(psxRecLUT, i + 0x1e00, &recROM1[i << 14]);+ RECLUT_SETPAGE(psxRecLUT, i + 0x9e00, &recROM1[i << 14]);+ RECLUT_SETPAGE(psxRecLUT, i + 0xbe00, &recROM1[i << 14]); } if( s_pInstCache )@@ -630,7 +627,6 @@ SafeSysMunmap(recMem, RECMEM_SIZE); safe_aligned_free( m_recBlockAlloc ); - safe_free(psxRecLUT); safe_free( s_pInstCache ); s_nInstCacheSize = 0; }@@ -644,7 +640,7 @@ pblock = PSX_GETBLOCK(psxRegs.pc); - if ( !pblock->GetFnptr() || (pblock->startpc&PSX_MEMMASK) != (psxRegs.pc&PSX_MEMMASK) ) {+ if ( !pblock->GetFnptr() || (pblock->GetStartPC()&PSX_MEMMASK) != (psxRegs.pc&PSX_MEMMASK) ) { psxRecRecompile(psxRegs.pc); } @@ -692,85 +688,66 @@ static u32 g_temp; // jumped to when invalid psxpc address+// EDX contains the jump addr to modify __declspec(naked) void psxDispatcher() {- // EDX contains the current psxpc to jump to, stack contains the jump addr to modify- __asm push edx+ __asm {+ mov eax, dword ptr [psxRegs.pc]+ mov ebx, eax+ shr eax, 16+ mov ecx, dword ptr [psxRecLUT+eax*4]+ mov eax, dword ptr [ecx+ebx*2]+ test eax, eax+ je notcompiled+ lea ebx, [eax-4]+ sub ebx, edx+ mov dword ptr [edx], ebx+ jmp eax - //jASSUME( psxRegs.pc <= PSX_MEMMASK );- s_pDispatchBlock = PSX_GETBLOCK( psxRegs.pc );+ align 16+notcompiled:+ mov esi, edx+ lea edi, [ecx+ebx*2]+ push ebx+ call psxRecRecompile+ add esp, 4 - if( s_pDispatchBlock->startpc != psxRegs.pc )- psxRecRecompile(psxRegs.pc);-- __asm- {- mov eax, s_pDispatchBlock- mov eax, dword ptr [eax]- }--#ifdef _DEBUG- __asm mov g_temp, eax- assert( g_temp );-#endif-- // Modify the prev block's jump address, and jump to the new block:- __asm- {- shl eax,4- pop ecx // x86Ptr[0] to mod- mov edx, eax- sub edx, ecx- sub edx, 4- mov dword ptr [ecx], edx-+ mov eax, dword ptr [edi]+ lea ebx, [eax-4]+ sub ebx, esi+ mov dword ptr [esi], ebx jmp eax } } +// edx - baseblock->GetStartPC()+// stack - x86Ptr[0] __declspec(naked) void psxDispatcherClear() {- // EDX contains the current psxpc- __asm mov psxRegs.pc, edx- __asm push edx+ __asm {+ mov [psxRegs.pc], edx+ mov ebx, edx+ shr edx, 16+ mov ecx, dword ptr [psxRecLUT+edx*4]+ mov eax, dword ptr [ecx+ebx*2]+ test eax, eax+ je notcompiled+ add esp, 4+ jmp eax - //jASSUME( psxRegs.pc <= PSX_MEMMASK );-- // calc PSX_GETBLOCK- s_pDispatchBlock = PSX_GETBLOCK(psxRegs.pc);-- if( s_pDispatchBlock->startpc == psxRegs.pc ) {- assert( s_pDispatchBlock->GetFnptr() != 0 );-- // already modded the code, jump to the new place- __asm- {- pop edx- add esp, 4 // ignore stack- mov eax, s_pDispatchBlock- mov eax, dword ptr [eax]- //and eax, 0x0fffffff- shl eax,4- jmp eax- }- }-- __asm- {+ align 16+notcompiled:+ lea edi, [ecx+ebx*2]+ push ebx call psxRecRecompile- add esp, 4 // pop old param- mov eax, s_pDispatchBlock- mov eax, dword ptr [eax]+ add esp, 4+ mov eax, dword ptr [edi] - pop ecx // old fnptr-- //and eax, 0x0fffffff- shl eax,4+ pop ecx mov byte ptr [ecx], 0xe9 // jmp32- mov edx, eax- sub edx, ecx- sub edx, 5- mov dword ptr [ecx+1], edx+ lea ebx, [eax-5]+ sub ebx, ecx+ mov dword ptr [ecx+1], ebx jmp eax }@@ -779,26 +756,24 @@ // called when jumping to variable psxpc address __declspec(naked) void psxDispatcherReg() {- //jASSUME( psxRegs.pc <= PSX_MEMMASK );- s_pDispatchBlock = PSX_GETBLOCK( psxRegs.pc );+ __asm {+ mov eax, dword ptr [psxRegs.pc]+ mov ebx, eax+ shr eax, 16+ mov ecx, dword ptr [psxRecLUT+eax*4]+ mov eax, dword ptr [ecx+ebx*2]+ test eax, eax+ je notcompiled+ jmp eax - if( s_pDispatchBlock->startpc != psxRegs.pc )- psxRecRecompile(psxRegs.pc);+ align 16+notcompiled:+ lea edi, [ecx+ebx*2]+ push ebx+ call psxRecRecompile+ add esp, 4 - __asm- {- mov eax, s_pDispatchBlock- mov eax, dword ptr [eax]- }--#ifdef _DEBUG- __asm mov g_temp, eax- assert( g_temp );-#endif-- __asm- {- shl eax, 4+ mov eax, dword ptr [edi] jmp eax } }@@ -869,7 +844,7 @@ void rpsxMemConstClear(u32 mem) { // NOTE! This assumes recLUT never changes its mapping- if( !psxRecLUT[mem>>16] )+ if( !(psxRecLUT[mem>>16] + mem) ) return; CMP32ItoM((uptr)PSX_GETBLOCK(mem), 0);@@ -894,20 +869,20 @@ } assert( p->GetFnptr() != 0 );- assert( p->startpc );+ assert( p->GetStartPC() ); x86Ptr[0] = (u8*)p->GetFnptr(); // there is a small problem: mem can be ored with 0xa<<28 or 0x8<<28, and don't know which- MOV32ItoR(EDX, p->startpc);+ MOV32ItoR(EDX, p->GetStartPC()); assert( (uptr)x86Ptr[0] <= 0xffffffff ); PUSH32I((uptr)x86Ptr[0]); JMP32((uptr)psxDispatcherClear - ( (uptr)x86Ptr[0] + 5 )); assert( x86Ptr[0] == (u8*)p->GetFnptr() + IOP_MIN_BLOCK_BYTES ); - pstart = PSX_GETBLOCK(p->startpc);+ pstart = PSX_GETBLOCK(p->GetStartPC()); pexblock = PSX_GETBLOCKEX(pstart);- assert( pexblock->startpc == pstart->startpc );+ assert( pexblock->startpc == pstart->GetStartPC() ); // don't delete if last is delay lastdelay = pexblock->size;@@ -1073,8 +1048,8 @@ { BASEBLOCK* pblock = PSX_GETBLOCK(temppc); - if( pblock->GetFnptr() != 0 && pblock->startpc != s_pCurBlock->startpc ) {- if( psxpc == pblock->startpc )+ if( pblock->GetFnptr() != 0 && pblock->GetStartPC() != s_pCurBlock->GetStartPC() ) {+ if( psxpc == pblock->GetStartPC() ) return 0; } @@ -1088,11 +1063,11 @@ BASEBLOCK* pblock = PSX_GETBLOCK(psxpc); // need *ppblock != s_pCurBlock because of branches- if( pblock->GetFnptr() != 0 && pblock->startpc != s_pCurBlock->startpc ) {+ if( pblock->GetFnptr() != 0 && pblock->GetStartPC() != s_pCurBlock->GetStartPC() ) { - if( !delayslot && psxpc == pblock->startpc ) {+ if( !delayslot && psxpc == pblock->GetStartPC() ) { // code already in place, so jump to it and exit recomp- assert( PSX_GETBLOCKEX(pblock)->startpc == pblock->startpc );+ assert( PSX_GETBLOCKEX(pblock)->startpc == pblock->GetStartPC() ); _psxFlushCall(FLUSH_EVERYTHING); MOV32ItoM((uptr)&psxRegs.pc, psxpc);@@ -1110,9 +1085,9 @@ } else { - if( !(delayslot && pblock->startpc == psxpc) ) {+ if( !(delayslot && pblock->GetStartPC() == psxpc) ) { u8* oldX86 = x86Ptr[0];- //__Log("clear block %x\n", pblock->startpc);+ //__Log("clear block %x\n", pblock->GetStartPC()); psxRecClearMem(pblock); x86Ptr[0] = oldX86; if( delayslot )@@ -1248,11 +1223,11 @@ if( s_pCurBlock->GetFnptr() ) { // clear if already taken- assert( s_pCurBlock->startpc < startpc );+ assert( s_pCurBlock->GetStartPC() < startpc ); psxRecClearMem(s_pCurBlock); } - if( s_pCurBlock->startpc == startpc ) {+ if( s_pCurBlock->GetStartPC() == startpc ) { s_pCurBlockEx = PSX_GETBLOCKEX(s_pCurBlock); assert( s_pCurBlockEx->startpc == startpc ); }@@ -1282,7 +1257,7 @@ psxbranch = 0; - s_pCurBlock->startpc = startpc;+ s_pCurBlock->SetStartPC(startpc); s_pCurBlock->SetFnptr( (uptr)x86Ptr[0] ); s_psxBlockCycles = 0; @@ -1305,9 +1280,9 @@ while(1) { BASEBLOCK* pblock = PSX_GETBLOCK(i);- if( pblock->GetFnptr() != 0 && pblock->startpc != s_pCurBlock->startpc ) {+ if( pblock->GetFnptr() != 0 && pblock->GetStartPC() != s_pCurBlock->GetStartPC() ) { - if( i == pblock->startpc ) {+ if( i == pblock->GetStartPC() ) { // branch = 3 willbranch3 = 1; s_nEndBlock = i;@@ -1407,16 +1382,20 @@ assert( (psxpc-startpc)>>2 <= 0xffff ); s_pCurBlockEx->size = (psxpc-startpc)>>2; +// This is just wrong, right? How can setting a jump to any point in this block+// to jump to the beginning of the block possibly be right?+#ifdef ZERO_TOLERANCE for(i = 1; i < (u32)s_pCurBlockEx->size-1; ++i) { s_pCurBlock[i].SetFnptr( s_pCurBlock->GetFnptr() );- s_pCurBlock[i].startpc = s_pCurBlock->startpc;+ s_pCurBlock[i].SetStartPC( p_CurBlock->startpc ); } // don't overwrite if delay slot if( i < (u32)s_pCurBlockEx->size && !(s_pCurBlock[i].uType & BLOCKTYPE_DELAYSLOT) ) {- s_pCurBlock[i].SetFnptr( s_pCurBlock->GetFnptr() );- s_pCurBlock[i].startpc = s_pCurBlock->startpc;+ s_pCurBlock[i].SetFnptr(0);+ s_pCurBlock[i].SetStartPC(0); }+#endif // set the block ptr AddBaseBlockEx(s_pCurBlockEx, 1);@@ -1472,14 +1451,14 @@ s_pCurBlock = PSX_GETBLOCK(psxpc); assert( ptr != NULL ); - if( s_pCurBlock->startpc != psxpc ){+ if( s_pCurBlock->GetStartPC() != psxpc ){ psxRecRecompile(psxpc); } // could have reset- if( pcurblock->startpc == startpc ) {+ if( pcurblock->GetStartPC() == startpc ) { assert( pcurblock->GetFnptr() );- assert( s_pCurBlock->startpc == nEndBlock );+ assert( s_pCurBlock->GetStartPC() == nEndBlock ); *ptr = (u32)((uptr)s_pCurBlock->GetFnptr() - ( (uptr)ptr + 4 )); } else {Index: pcsx2/x86/iR3000A.h===================================================================--- pcsx2/x86/iR3000A.h (revision 685)+++ pcsx2/x86/iR3000A.h (working copy)@@ -38,7 +38,7 @@ #define PSX_HI XMMGPR_HI #define PSX_LO XMMGPR_LO -extern uptr *psxRecLUT;+extern uptr psxRecLUT[]; u8 _psxLoadWritesRs(u32 tempcode); u8 _psxIsLoadStore(u32 tempcode);Index: pcsx2/x86/iR5900.h===================================================================--- pcsx2/x86/iR5900.h (revision 685)+++ pcsx2/x86/iR5900.h (working copy)@@ -51,7 +51,7 @@ extern u32 pc; extern int branch;-extern uptr* recLUT;+extern uptr recLUT[]; extern u32 maxrecmem; extern u32 pc; // recompiler pc (also used by the SuperVU! .. why? (air))Index: pcsx2/x86/ix86-32/iR5900-32.cpp===================================================================--- pcsx2/x86/ix86-32/iR5900-32.cpp (revision 685)+++ pcsx2/x86/ix86-32/iR5900-32.cpp (working copy)@@ -52,7 +52,7 @@ bool g_EEFreezeRegs = false; u32 maxrecmem = 0;-uptr *recLUT = NULL;+uptr recLUT[0x10000]; u32 s_nBlockCycles = 0; // cycles of current block recompiling //u8* dyna_block_discard_recmem=0;@@ -120,7 +120,7 @@ // return pex; // otherwise, use the sorted list- return GetBaseBlockEx(p->startpc, 0);+ return GetBaseBlockEx(p->GetStartPC(), 0); } ////////////////////////////////////////////////////@@ -480,9 +480,6 @@ if ( !( cpucaps.hasStreamingSIMD2Extensions ) ) throw Exception::HardwareDeficiency( _( "Processor doesn't support SSE2" ) ); - if( recLUT == NULL )- recLUT = (uptr*) _aligned_malloc( 0x010000 * sizeof(uptr), 16 );- if( recMem == NULL ) { // Note: the VUrec depends on being able to grab an allocatione below the 0x10000000 line,@@ -552,32 +549,34 @@ __asm__("emms"); #endif - memzero_ptr<0x010000 * sizeof(uptr)>( recLUT );+ memzero_ptr<sizeof recLUT>( recLUT ); for ( int i = 0x0000; i < 0x0200; i++ ) {- recLUT[ i + 0x0000 ] = (uptr)&recRAM[ i << 14 ];- recLUT[ i + 0x2000 ] = (uptr)&recRAM[ i << 14 ];- recLUT[ i + 0x3000 ] = (uptr)&recRAM[ i << 14 ];+ RECLUT_SETPAGE(recLUT, i + 0x0000, &recRAM[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0x2000, &recRAM[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0x3000, &recRAM[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0x8000, &recRAM[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0xa000, &recRAM[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0xb000, &recRAM[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0xc000, &recRAM[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0xd000, &recRAM[ i << 14 ]); } for ( int i = 0x0000; i < 0x0040; i++ ) {- recLUT[ i + 0x1fc0 ] = (uptr)&recROM[ i << 14 ];- recLUT[ i + 0x9fc0 ] = (uptr)&recROM[ i << 14 ];- recLUT[ i + 0xbfc0 ] = (uptr)&recROM[ i << 14 ];+ RECLUT_SETPAGE(recLUT, i + 0x1fc0, &recROM[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0x9fc0, &recROM[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0xbfc0, &recROM[ i << 14 ]); } for ( int i = 0x0000; i < 0x0004; i++ ) {- recLUT[ i + 0x1e00 ] = (uptr)&recROM1[ i << 14 ];- recLUT[ i + 0x9e00 ] = (uptr)&recROM1[ i << 14 ];- recLUT[ i + 0xbe00 ] = (uptr)&recROM1[ i << 14 ];+ RECLUT_SETPAGE(recLUT, i + 0x1e00, &recROM1[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0x9e00, &recROM1[ i << 14 ]);+ RECLUT_SETPAGE(recLUT, i + 0xbe00, &recROM1[ i << 14 ]); } - memcpy_fast( recLUT + 0x8000, recLUT, 0x2000 * sizeof(uptr) );- memcpy_fast( recLUT + 0xa000, recLUT, 0x2000 * sizeof(uptr) );- // drk||Raziel says this is useful but I'm not sure why. Something to do with forward jumps. // Anyways, it causes random crashing for some reasom, possibly because of memory // corrupition elsewhere in the recs. I can't reproduce the problem here though,@@ -604,7 +603,6 @@ ResetBaseBlockEx(0); SafeSysMunmap( recMem, REC_CACHEMEM );- safe_aligned_free( recLUT ); safe_aligned_free( m_recBlockAlloc ); recRAM = recROM = recROM1 = NULL; recBlocks = NULL;@@ -649,105 +647,89 @@ // EDX contains the jump addr to modify static __naked void Dispatcher() {- // EDX contains the jump addr to modify- __asm push edx-- // calc PC_GETBLOCK- s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc);- - if( s_pDispatchBlock->startpc != cpuRegs.pc )- recRecompile(cpuRegs.pc);-- __asm- {- mov eax, s_pDispatchBlock- mov eax, dword ptr [eax]- }--#ifdef _DEBUG- __asm mov g_EEDispatchTemp, eax- assert( g_EEDispatchTemp );-#endif-- // Modify the prev block's jump address, and jump to the new block: __asm {- shl eax, 4- pop ecx // x86Ptr[0] to mod- mov edx, eax- sub edx, ecx- sub edx, 4- mov dword ptr [ecx], edx+ mov eax, dword ptr [cpuRegs.pc]+ mov ebx, eax+ shr eax, 16+ mov ecx, dword ptr [recLUT+eax*4]+ mov eax, dword ptr [ecx+ebx*2]+ test eax, eax+ je notcompiled+ lea ebx, [eax-4]+ sub ebx, edx+ mov dword ptr [edx], ebx+ jmp eax + align 16+notcompiled:+ mov esi, edx+ lea edi, [ecx+ebx*2]+ push ebx+ call recRecompile+ add esp, 4++ mov eax, dword ptr [edi]+ lea ebx, [eax-4]+ sub ebx, esi+ mov dword ptr [esi], ebx jmp eax } } -// edx - baseblock->startpc+// edx - baseblock->GetStartPC() // stack - x86Ptr[0] static __naked void DispatcherClear() {- // EDX contains the current pc- __asm mov cpuRegs.pc, edx- __asm push edx-- // calc PC_GETBLOCK- s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc);-- if( s_pDispatchBlock != NULL && s_pDispatchBlock->startpc == cpuRegs.pc )- {- assert( s_pDispatchBlock->GetFnptr() != 0 );-- // already modded the code, jump to the new place- __asm {- pop edx- mov eax, s_pDispatchBlock- add esp, 4 // ignore stack- mov eax, dword ptr [eax]- shl eax, 4- jmp eax- }- }- __asm {+ mov [cpuRegs.pc], edx+ mov ebx, edx+ shr edx, 16+ mov ecx, dword ptr [recLUT+edx*4]+ mov eax, dword ptr [ecx+ebx*2]+ test eax, eax+ je notcompiled+ add esp, 4+ jmp eax++ align 16+notcompiled:+ lea edi, [ecx+ebx*2]+ push ebx call recRecompile- add esp, 4 // pop old param- mov eax, s_pDispatchBlock- mov eax, dword ptr [eax]+ add esp, 4+ mov eax, dword ptr [edi] - pop ecx // old fnptr-- shl eax, 4+ pop ecx mov byte ptr [ecx], 0xe9 // jmp32- mov edx, eax- sub edx, ecx- sub edx, 5- mov dword ptr [ecx+1], edx+ lea ebx, [eax-5]+ sub ebx, ecx+ mov dword ptr [ecx+1], ebx jmp eax } } // called when jumping to variable pc address-static __naked void DispatcherReg()+static void __naked DispatcherReg() {- s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc);+ __asm {+ mov eax, dword ptr [cpuRegs.pc]+ mov ebx, eax+ shr eax, 16+ mov ecx, dword ptr [recLUT+eax*4]+ mov eax, dword ptr [ecx+ebx*2]+ test eax, eax+ je notcompiled+ jmp eax - if( s_pDispatchBlock->startpc != cpuRegs.pc )- recRecompile(cpuRegs.pc);+ align 16+notcompiled:+ lea edi, [ecx+ebx*2]+ push ebx+ call recRecompile+ add esp, 4 - __asm- {- mov eax, s_pDispatchBlock- mov eax, dword ptr [eax]- }--#ifdef _DEBUG- __asm mov g_EEDispatchTemp, eax- assert( g_EEDispatchTemp );-#endif-- __asm {- shl eax, 4+ mov eax, dword ptr [edi] jmp eax } }@@ -928,21 +910,21 @@ } assert( p->GetFnptr() != 0 );- assert( p->startpc );+ assert( p->GetStartPC() ); x86Ptr[0] = (u8*)p->GetFnptr(); // there is a small problem: mem can be ored with 0xa<<28 or 0x8<<28, and don't know which- MOV32ItoR(EDX, p->startpc);+ MOV32ItoR(EDX, p->GetStartPC()); PUSH32I((u32)x86Ptr[0]); // will be replaced by JMP32 JMP32((u32)DispatcherClear - ( (u32)x86Ptr[0] + 5 )); assert( x86Ptr[0] == (u8*)p->GetFnptr() + EE_MIN_BLOCK_BYTES ); - pstart = PC_GETBLOCK(p->startpc);+ pstart = PC_GETBLOCK(p->GetStartPC()); pexblock = PC_GETBLOCKEX(pstart);- assert( pexblock->startpc == pstart->startpc );+ assert( pexblock->startpc == pstart->GetStartPC() ); - if( pexblock->startpc != pstart->startpc ) {+ if( pexblock->startpc != pstart->GetStartPC() ) { // some bug with ffx after beating a big snake in sewers RemoveBaseBlockEx(pexblock, 0); pexblock->size = 0;@@ -969,7 +951,7 @@ void REC_CLEARM( u32 mem ) {- if ((mem) < maxrecmem && recLUT[(mem) >> 16]) {+ if ((mem) < maxrecmem && (recLUT[(mem) >> 16] + mem)) { BASEBLOCK* p = PC_GETBLOCK(mem); if( *(u32*)p ) recClearMem(p); }@@ -1283,8 +1265,8 @@ { BASEBLOCK* pblock = PC_GETBLOCK(temppc); - if( pblock->GetFnptr() != 0 && pblock->startpc != s_pCurBlock->startpc ) {- if( pc == pblock->startpc )+ if( pblock->GetFnptr() != 0 && pblock->GetStartPC() != s_pCurBlock->GetStartPC() ) {+ if( pc == pblock->GetStartPC() ) return 0; } @@ -1299,11 +1281,11 @@ BASEBLOCK* pblock = PC_GETBLOCK(pc); // need *ppblock != s_pCurBlock because of branches- if( pblock->GetFnptr() != 0 && pblock->startpc != s_pCurBlock->startpc ) {+ if( pblock->GetFnptr() != 0 && pblock->GetStartPC() != s_pCurBlock->GetStartPC() ) { - if( !delayslot && pc == pblock->startpc ) {+ if( !delayslot && pc == pblock->GetStartPC() ) { // code already in place, so jump to it and exit recomp- assert( PC_GETBLOCKEX(pblock)->startpc == pblock->startpc );+ assert( PC_GETBLOCKEX(pblock)->startpc == pblock->GetStartPC() ); iFlushCall(FLUSH_EVERYTHING); MOV32ItoM((uptr)&cpuRegs.pc, pc);@@ -1321,9 +1303,9 @@ } else { - if( !(delayslot && pblock->startpc == pc) ) {+ if( !(delayslot && pblock->GetStartPC() == pc) ) { u8* oldX86 = x86Ptr[0];- //__Log("clear block %x\n", pblock->startpc);+ //__Log("clear block %x\n", pblock->GetStartPC()); recClearMem(pblock); x86Ptr[0] = oldX86; if( delayslot )@@ -1332,8 +1314,10 @@ } } +#if 1 if( delayslot ) pblock->uType = BLOCKTYPE_DELAYSLOT;+#endif s_pCode = (int *)PSM( pc ); assert(s_pCode);@@ -1543,11 +1527,11 @@ if( s_pCurBlock->GetFnptr() ) { // clear if already taken- assert( s_pCurBlock->startpc < startpc );+ assert( s_pCurBlock->GetStartPC() < startpc ); recClearMem(s_pCurBlock); } - if( s_pCurBlock->startpc == startpc ) {+ if( s_pCurBlock->GetStartPC() == startpc ) { s_pCurBlockEx = PC_GETBLOCKEX(s_pCurBlock); assert( s_pCurBlockEx->startpc == startpc ); }@@ -1575,7 +1559,7 @@ x86Align(16); recPtr = x86Ptr[0]; s_pCurBlock->SetFnptr( (uptr)x86Ptr[0] );- s_pCurBlock->startpc = startpc;+ s_pCurBlock->SetStartPC(startpc); branch = 0; @@ -1612,9 +1596,9 @@ while(1) { BASEBLOCK* pblock = PC_GETBLOCK(i);- if( pblock->GetFnptr() != 0 && pblock->startpc != s_pCurBlock->startpc ) {+ if( pblock->GetFnptr() != 0 && pblock->GetStartPC() != s_pCurBlock->GetStartPC() ) { - if( i == pblock->startpc ) {+ if( i == pblock->GetStartPC() ) { // branch = 3 willbranch3 = 1; s_nEndBlock = i;@@ -1943,16 +1927,20 @@ assert( (pc-startpc)>>2 <= 0xffff ); s_pCurBlockEx->size = (pc-startpc)>>2; +// This is just wrong, right? How can setting a jump to any point in this block+// to jump to the beginning of the block possibly be right?+#ifdef ZERO_TOLERANCE for(i = 1; i < (u32)s_pCurBlockEx->size-1; ++i) { s_pCurBlock[i].SetFnptr( s_pCurBlock->GetFnptr() );- s_pCurBlock[i].startpc = s_pCurBlock->startpc;+ s_pCurBlock[i].SetStartPC( p_CurBlock->startpc ); } // don't overwrite if delay slot if( i < (u32)s_pCurBlockEx->size && !(s_pCurBlock[i].uType & BLOCKTYPE_DELAYSLOT) ) {- s_pCurBlock[i].SetFnptr( s_pCurBlock->GetFnptr() );- s_pCurBlock[i].startpc = s_pCurBlock->startpc;+ s_pCurBlock[i].SetFnptr(0);+ s_pCurBlock[i].SetStartPC(0); }+#endif // set the block ptr AddBaseBlockEx(s_pCurBlockEx, 0);@@ -2022,12 +2010,12 @@ s_pCurBlock = PC_GETBLOCK(pc); assert( ptr != NULL ); - if( s_pCurBlock->startpc != pc ) + if( s_pCurBlock->GetStartPC() != pc ) recRecompile(pc); - if( pcurblock->startpc == startpc ) {+ if( pcurblock->GetStartPC() == startpc ) { assert( pcurblock->GetFnptr() );- assert( s_pCurBlock->startpc == nEndBlock );+ assert( s_pCurBlock->GetStartPC() == nEndBlock ); *ptr = s_pCurBlock->GetFnptr() - ( (u32)ptr + 4 ); } else {