Index: pcsx2/x86/BaseblockEx.cpp =================================================================== --- pcsx2/x86/BaseblockEx.cpp (revision 789) +++ pcsx2/x86/BaseblockEx.cpp (working copy) @@ -18,7 +18,35 @@ #include "PrecompiledHeader.h" #include "BaseblockEx.h" +#include "Common.h" +void BaseBlocks::RewriteJump(uptr jmp, uptr dest, u8 type) +{ + sptr rel = dest - (jmp + 2); + u8 *ptr = reinterpret_cast(jmp); + + if (rel >= -128 && rel <= 127) { + *ptr++ = type ? type : 0xEB; + *(s8*)ptr++ = (s8)rel; + if (type) { + *ptr++ = 0xC3; + } else { // it's unconditional but this makes the disasm line up + *ptr++ = 0x0F; + *ptr++ = 0x1F; + *ptr++ = 0x00; + } + } else { + rel = dest - (jmp + (type ? 6 : 5)); + if (type) { + *ptr++ = 0x0F; + *ptr++ = type + 0x10; + } else + *ptr++ = 0xE9; + *(s32*)ptr = rel; + ptr += 4; + } +} + BASEBLOCKEX* BaseBlocks::New(u32 startpc, uptr fnptr) { if (blocks.size() == size) @@ -46,7 +74,7 @@ std::pair range = links.equal_range(startpc); for (linkiter_t i = range.first; i != range.second; ++i) - *(u32*)i->second = fnptr - (i->second + 4); + RewriteJump(i->second.jumpptr, fnptr, i->second.type); return &*iter; } @@ -76,12 +104,15 @@ return 0; } -void BaseBlocks::Link(u32 pc, uptr jumpptr) +void BaseBlocks::Link(u32 pc, uptr jumpptr, u8 type) { BASEBLOCKEX *targetblock = Get(pc); + BlockLink link; + link.jumpptr = jumpptr; link.type = type; + if (targetblock && targetblock->startpc == pc) - *(u32*)jumpptr = targetblock->fnptr - (jumpptr + 4); + RewriteJump(jumpptr, targetblock->fnptr, type); else - *(u32*)jumpptr = recompiler - (jumpptr + 4); - links.insert(std::pair(pc, jumpptr)); + RewriteJump(jumpptr, recompiler, type); + links.insert(std::pair(pc, link)); } \ No newline at end of file Index: pcsx2/x86/BaseblockEx.h =================================================================== --- pcsx2/x86/BaseblockEx.h (revision 789) +++ pcsx2/x86/BaseblockEx.h (working copy) @@ -52,16 +52,24 @@ }; +struct BlockLink +{ + u8 type; + uptr jumpptr; +}; + class BaseBlocks { private: std::vector blocks; // switch to a hash map later? - std::multimap links; - typedef std::multimap::iterator linkiter_t; + std::multimap links; + typedef std::multimap::iterator linkiter_t; unsigned long size; uptr recompiler; + static void RewriteJump(uptr jmp, uptr dest, u8 type); + public: BaseBlocks(unsigned long size_, uptr recompiler_) : size(size_), @@ -102,12 +110,12 @@ u32 startpc = blocks[idx].startpc; std::pair range = links.equal_range(blocks[idx].startpc); for (linkiter_t i = range.first; i != range.second; ++i) - *(u32*)i->second = recompiler - (i->second + 4); + RewriteJump(i->second.jumpptr, recompiler, i->second.type); // TODO: remove links from this block? blocks.erase(blocks.begin() + idx); } - void Link(u32 pc, uptr jumpptr); + void Link(u32 pc, uptr jumpptr, u8 type); inline void Reset() { Index: pcsx2/x86/iR3000A.cpp =================================================================== --- pcsx2/x86/iR3000A.cpp (revision 789) +++ pcsx2/x86/iR3000A.cpp (working copy) @@ -777,7 +777,6 @@ void psxSetBranchImm( u32 imm ) { - u32* ptr; psxbranch = 1; assert( imm ); @@ -786,8 +785,9 @@ _psxFlushCall(FLUSH_EVERYTHING); iPsxBranchTest(imm, imm <= psxpc); - ptr = JMP32(0); - recBlocks.Link(HWADDR(imm), (uptr)ptr); + uptr ptr = (uptr)x86Ptr[_EmitterId_]; + JMP32(0); + recBlocks.Link(HWADDR(imm), ptr, 0); } //fixme : this is all a huge hack, we base the counter advancements on the average an opcode should take (wtf?) @@ -1174,8 +1174,9 @@ assert( psxpc == s_nEndBlock ); _psxFlushCall(FLUSH_EVERYTHING); MOV32ItoM((uptr)&psxRegs.pc, psxpc); - u32 *ptr = JMP32(0); - recBlocks.Link(HWADDR(s_nEndBlock), (uptr)ptr); + uptr ptr = (uptr)x86Ptr[_EmitterId_]; + JMP32(0); + recBlocks.Link(HWADDR(s_nEndBlock), ptr, 0); psxbranch = 3; } } Index: pcsx2/x86/ix86-32/iR5900-32.cpp =================================================================== --- pcsx2/x86/ix86-32/iR5900-32.cpp (revision 789) +++ pcsx2/x86/ix86-32/iR5900-32.cpp (working copy) @@ -1110,15 +1110,14 @@ static void iBranch(u32 newpc, int type) { - u32* ptr; - MOV32ItoM((uptr)&cpuRegs.pc, newpc); + uptr ptr = (uptr)x86Ptr[_EmitterId_]; if (type == 0) - ptr = JMP32(0); - else if (type == 1) - ptr = JS32(0); + JMP32(0); + else + JS32(0); // immediately replaced with appropriate op - recBlocks.Link(HWADDR(newpc), (uptr)ptr); + recBlocks.Link(HWADDR(newpc), ptr, type); } // Generates dynarec code for Event tests followed by a block dispatch (branch). @@ -1152,7 +1151,7 @@ if (newpc == 0xffffffff) JS32((uptr)DispatcherReg - ( (uptr)x86Ptr[0] + 6 )); else - iBranch(newpc, 1); + iBranch(newpc, 0x78); // JS } RET();