diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 86e499bd1..6d3c1a551 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -169,7 +169,8 @@ void Jit::Compile(u32 em_address) int block_num = blocks.AllocateBlock(em_address); ArmJitBlock *b = blocks.GetBlock(block_num); - blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, b)); + DoJit(em_address, b); + blocks.FinalizeBlock(block_num, jo.enableBlocklink); // Drat. The VFPU hit an uneaten prefix at the end of a block. if (js.startDefaultPrefix && js.MayHavePrefix()) diff --git a/Core/MIPS/ARM/ArmJitCache.cpp b/Core/MIPS/ARM/ArmJitCache.cpp index c0b95c543..2743ce7e3 100644 --- a/Core/MIPS/ARM/ArmJitCache.cpp +++ b/Core/MIPS/ARM/ArmJitCache.cpp @@ -160,10 +160,10 @@ int ArmJitBlockCache::AllocateBlock(u32 em_address) return num_blocks - 1; } -void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr) +void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link) { - blockCodePointers[block_num] = code_ptr; ArmJitBlock &b = blocks[block_num]; + blockCodePointers[block_num] = b.normalEntry; b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress); u32 opcode = MIPS_MAKE_EMUHACK(0, block_num); @@ -189,7 +189,7 @@ void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *c #if defined USE_OPROFILE && USE_OPROFILE char buf[100]; sprintf(buf, "EmuCode%x", b.originalAddress); - const u8* blockStart = blockCodePointers[block_num]; + const u8* blockStart = blocks[block_num].checkedEntry; op_write_native_code(agent, buf, (uint64_t)blockStart, blockStart, b.codeSize); #endif @@ -201,7 +201,7 @@ void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *c jmethod.method_id = iJIT_GetNewMethodID(); jmethod.class_file_name = ""; jmethod.source_file_name = __FILE__; - jmethod.method_load_address = (void*)blockCodePointers[block_num]; + jmethod.method_load_address = (void*)blocks[block_num].checkedEntry; jmethod.method_size = b.codeSize; jmethod.line_number_size = 0; jmethod.method_name = b.blockName; @@ -246,29 +246,6 @@ u32 ArmJitBlockCache::GetOriginalFirstOp(int block_num) return blocks[block_num].originalFirstOpcode; } -CompiledCode ArmJitBlockCache::GetCompiledCodeFromBlock(int block_num) -{ - return (CompiledCode)blockCodePointers[block_num]; -} - -std::string ArmJitBlockCache::GetCompiledDisassembly(int block_num) -{ - /* - std::string buf; - const u8 *ptr = blockCodePointers[block_num]; - - while (ptr < blockCodePointers[block_num] + blocks[block_num].codeSize) - { - int len; - buf += std::string(disasmx86((unsigned char*)ptr, 0, &len)) + "\n"; - ptr += len; - }*/ - return "No ARM disassembler"; -} - - -//Make sure to have as many blocks as possible compiled before calling this -//It's O(1), so it's fast :) void ArmJitBlockCache::LinkBlockExits(int i) { ArmJitBlock &b = blocks[i]; @@ -328,6 +305,10 @@ void ArmJitBlockCache::UnlinkBlock(int i) } } +u32 ArmJitBlockCache::GetEmuHackOpForBlock(int blockNum) const { + return (MIPS_EMUHACK_OPCODE | blockNum); +} + void ArmJitBlockCache::DestroyBlock(int block_num, bool invalidate) { if (block_num < 0 || block_num >= num_blocks) @@ -343,12 +324,14 @@ void ArmJitBlockCache::DestroyBlock(int block_num, bool invalidate) return; } b.invalid = true; - if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == (MIPS_EMUHACK_OPCODE | block_num)) + if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == GetEmuHackOpForBlock(block_num)) Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress); UnlinkBlock(block_num); - + b.normalEntry = 0; + // TODO: remove blockCodePointers[block_num] = 0; + // Send anyone who tries to run this block back to the dispatcher. // Not entirely ideal, but .. pretty good. // I hope there's enough space... diff --git a/Core/MIPS/ARM/ArmJitCache.h b/Core/MIPS/ARM/ArmJitCache.h index ffa72a768..46725ec42 100644 --- a/Core/MIPS/ARM/ArmJitCache.h +++ b/Core/MIPS/ARM/ArmJitCache.h @@ -30,17 +30,6 @@ // emulate CPU with unlimited instruction cache // the only way to invalidate a region is the "icbi" instruction -#define JIT_ICACHE_SIZE 0x2000000 -#define JIT_ICACHE_MASK 0x1ffffff -#define JIT_ICACHEEX_SIZE 0x4000000 -#define JIT_ICACHEEX_MASK 0x3ffffff -#define JIT_ICACHE_EXRAM_BIT 0x10000000 -#define JIT_ICACHE_VMEM_BIT 0x20000000 -// this corresponds to opcode 5 which is invalid in PowerPC -#define JIT_ICACHE_INVALID_BYTE 0x14 -#define JIT_ICACHE_INVALID_WORD 0x14141414 - -#define JIT_OPCODE 0xFFCCCCCC // yeah this ain't gonna work struct ArmJitBlock { @@ -85,7 +74,7 @@ public: MAX_NUM_BLOCKS(0) { } ~ArmJitBlockCache(); int AllocateBlock(u32 em_address); - void FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr); + void FinalizeBlock(int block_num, bool block_link); void Clear(); void ClearSafe(); @@ -110,18 +99,18 @@ public: void GetBlockNumbersFromAddress(u32 em_address, std::vector *block_numbers); u32 GetOriginalFirstOp(int block_num); - CompiledCode GetCompiledCodeFromBlock(int block_num); // DOES NOT WORK CORRECTLY WITH INLINING void InvalidateICache(u32 address, const u32 length); void DestroyBlock(int block_num, bool invalidate); - std::string GetCompiledDisassembly(int block_num); - - // Not currently used - //void DestroyBlocksWithFlag(BlockFlag death_flag); - private: + bool RangeIntersect(int s1, int e1, int s2, int e2) const; + void LinkBlockExits(int i); + void LinkBlock(int i); + void UnlinkBlock(int i); + u32 GetEmuHackOpForBlock(int blockNum) const; + MIPSState *mips; const u8 **blockCodePointers; ArmJitBlock *blocks; @@ -130,9 +119,4 @@ private: std::map, u32> block_map; // (end_addr, start_addr) -> number int MAX_NUM_BLOCKS; - - bool RangeIntersect(int s1, int e1, int s2, int e2) const; - void LinkBlockExits(int i); - void LinkBlock(int i); - void UnlinkBlock(int i); }; diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index f9b18a9a3..350ea7202 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -220,7 +220,8 @@ void Jit::Compile(u32 em_address) int block_num = blocks.AllocateBlock(em_address); JitBlock *b = blocks.GetBlock(block_num); - blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, b)); + DoJit(em_address, b); + blocks.FinalizeBlock(block_num, jo.enableBlocklink); // Drat. The VFPU hit an uneaten prefix at the end of a block. if (js.startDefaultPrefix && js.MayHavePrefix()) diff --git a/Core/MIPS/x86/JitCache.cpp b/Core/MIPS/x86/JitCache.cpp index b1e8cb3a1..34580e5bf 100644 --- a/Core/MIPS/x86/JitCache.cpp +++ b/Core/MIPS/x86/JitCache.cpp @@ -173,10 +173,10 @@ int JitBlockCache::AllocateBlock(u32 em_address) return num_blocks - 1; } -void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr) +void JitBlockCache::FinalizeBlock(int block_num, bool block_link) { - blockCodePointers[block_num] = code_ptr; JitBlock &b = blocks[block_num]; + blockCodePointers[block_num] = b.normalEntry; b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress); u32 opcode = MIPS_MAKE_EMUHACK(0, block_num); @@ -202,9 +202,8 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code #if defined USE_OPROFILE && USE_OPROFILE char buf[100]; sprintf(buf, "EmuCode%x", b.originalAddress); - const u8* blockStart = blockCodePointers[block_num]; - op_write_native_code(agent, buf, (uint64_t)blockStart, - blockStart, b.codeSize); + const u8* blockStart = blocks[block_num].checkedEntry; + op_write_native_code(agent, buf, (uint64_t)blockStart, blockStart, b.codeSize); #endif #ifdef USE_VTUNE @@ -214,7 +213,7 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code jmethod.method_id = iJIT_GetNewMethodID(); jmethod.class_file_name = ""; jmethod.source_file_name = __FILE__; - jmethod.method_load_address = (void*)blockCodePointers[block_num]; + jmethod.method_load_address = (void*)blocks[block_num].checkedEntry; jmethod.method_size = b.codeSize; jmethod.line_number_size = 0; jmethod.method_name = b.blockName; @@ -259,19 +258,6 @@ u32 JitBlockCache::GetOriginalFirstOp(int block_num) return blocks[block_num].originalFirstOpcode; } -CompiledCode JitBlockCache::GetCompiledCodeFromBlock(int block_num) -{ - return (CompiledCode)blockCodePointers[block_num]; -} - - - -//Block linker -//Make sure to have as many blocks as possible compiled before calling this -//It's O(N), so it's fast :) -//Can be faster by doing a queue for blocks to link up, and only process those -//Should probably be done - void JitBlockCache::LinkBlockExits(int i) { JitBlock &b = blocks[i]; @@ -330,6 +316,10 @@ void JitBlockCache::UnlinkBlock(int i) } } +u32 JitBlockCache::GetEmuHackOpForBlock(int blockNum) { + return (MIPS_EMUHACK_OPCODE | blockNum); +} + void JitBlockCache::DestroyBlock(int block_num, bool invalidate) { if (block_num < 0 || block_num >= num_blocks) @@ -345,7 +335,7 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate) return; } b.invalid = true; - if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == (MIPS_EMUHACK_OPCODE | block_num)) + if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == GetEmuHackOpForBlock(block_num)) Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress); UnlinkBlock(block_num); @@ -356,13 +346,6 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate) XEmitter emit((u8 *)b.checkedEntry); emit.MOV(32, M(&mips->pc), Imm32(b.originalAddress)); emit.JMP(MIPSComp::jit->Asm().dispatcher, true); - - // this is not needed really - /* - emit.SetCodePtr((u8 *)blockCodePointers[blocknum]); - emit.MOV(32, M(&PC), Imm32(b.originalAddress)); - emit.JMP(asm_routines.dispatcher, true); - */ } void JitBlockCache::InvalidateICache(u32 address, const u32 length) diff --git a/Core/MIPS/x86/JitCache.h b/Core/MIPS/x86/JitCache.h index d508b8311..c12baab03 100644 --- a/Core/MIPS/x86/JitCache.h +++ b/Core/MIPS/x86/JitCache.h @@ -79,20 +79,6 @@ typedef void (*CompiledCode)(); class JitBlockCache { - MIPSState *mips; - const u8 **blockCodePointers; - JitBlock *blocks; - int num_blocks; - std::multimap links_to; - std::map, u32> block_map; // (end_addr, start_addr) -> number - - int MAX_NUM_BLOCKS; - - bool RangeIntersect(int s1, int e1, int s2, int e2) const; - void LinkBlockExits(int i); - void LinkBlock(int i); - void UnlinkBlock(int i); - public: JitBlockCache(MIPSState *mips_) : mips(mips_), blockCodePointers(0), blocks(0), num_blocks(0), @@ -100,7 +86,7 @@ public: ~JitBlockCache(); int AllocateBlock(u32 em_address); - void FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr); + void FinalizeBlock(int block_num, bool block_link); void Clear(); void Init(); @@ -124,12 +110,26 @@ public: void GetBlockNumbersFromAddress(u32 em_address, std::vector *block_numbers); u32 GetOriginalFirstOp(int block_num); - CompiledCode GetCompiledCodeFromBlock(int block_num); // DOES NOT WORK CORRECTLY WITH JIT INLINING void InvalidateICache(u32 address, const u32 length); void DestroyBlock(int block_num, bool invalidate); - // Not currently used - //void DestroyBlocksWithFlag(BlockFlag death_flag); +private: + bool RangeIntersect(int s1, int e1, int s2, int e2) const; + void LinkBlockExits(int i); + void LinkBlock(int i); + void UnlinkBlock(int i); + + u32 GetEmuHackOpForBlock(int block_num); + + MIPSState *mips; + const u8 **blockCodePointers; + JitBlock *blocks; + int num_blocks; + std::multimap links_to; + std::map, u32> block_map; // (end_addr, start_addr) -> number + + int MAX_NUM_BLOCKS; }; +