diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj index 6a95657e88..05619e6f0c 100644 --- a/Source/Core/Core/Core.vcproj +++ b/Source/Core/Core/Core.vcproj @@ -492,7 +492,7 @@ OmitFramePointers="true" EnableFiberSafeOptimizations="false" AdditionalIncludeDirectories=".\Core\Core\Src\Debugger;..\Common\Src;..\DiscIO\Src;..\..\Core\InputCommon\Src;..\..\PluginSpecs;..\..\..\Externals\LZO;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\zlib" - PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;JITTEST" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;JITTEST=1" StringPooling="true" RuntimeLibrary="0" BufferSecurityCheck="false" @@ -1258,26 +1258,6 @@ /> - - - - - - - - @@ -1302,50 +1282,6 @@ RelativePath=".\Src\PowerPC\Jit64\JitAsm.h" > - - - - - - - - - - - - - - - - - - @@ -1902,58 +1838,6 @@ /> - - - - - - - - - - - - - - - - - - - - @@ -2010,114 +1894,6 @@ RelativePath=".\Src\PowerPC\Jit64IL\JitAsm.h" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2175,6 +1951,26 @@ > + + + + + + + + + + = 4) { - PanicAlert("WARNING: likely incorrect use of UnsafeWriteRegToReg!"); - } - BSWAP(accessSize, reg_value); -#ifdef _M_IX86 - AND(32, R(reg_addr), Imm32(Memory::MEMVIEW32_MASK)); - MOV(accessSize, MDisp(reg_addr, (u32)Memory::base + offset), R(reg_value)); -#else - MOV(accessSize, MComplex(RBX, reg_addr, SCALE_1, offset), R(reg_value)); -#endif -} - -// Destroys both arg registers -void Jit64::SafeWriteRegToReg(X64Reg reg_value, X64Reg reg_addr, int accessSize, s32 offset) -{ - if (offset) - ADD(32, R(reg_addr), Imm32(offset)); - TEST(32, R(reg_addr), Imm32(0x0C000000)); - FixupBranch argh = J_CC(CC_Z); - switch (accessSize) - { - case 32: ABI_CallFunctionRR(thunks.ProtectFunction((void *)&Memory::Write_U32, 2), reg_value, reg_addr); break; - case 16: ABI_CallFunctionRR(thunks.ProtectFunction((void *)&Memory::Write_U16, 2), reg_value, reg_addr); break; - case 8: ABI_CallFunctionRR(thunks.ProtectFunction((void *)&Memory::Write_U8, 2), reg_value, reg_addr); break; - } - FixupBranch arg2 = J(); - SetJumpTarget(argh); - UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, 0); - SetJumpTarget(arg2); -} - -void Jit64::WriteToConstRamAddress(int accessSize, const Gen::OpArg& arg, u32 address) -{ -#ifdef _M_X64 - MOV(accessSize, MDisp(RBX, address & 0x3FFFFFFF), arg); -#else - MOV(accessSize, M((void*)(Memory::base + (address & Memory::MEMVIEW32_MASK))), arg); -#endif -} - -void Jit64::WriteFloatToConstRamAddress(const Gen::X64Reg& xmm_reg, u32 address) -{ -#ifdef _M_X64 - MOV(32, R(RAX), Imm32(address)); - MOVSS(MComplex(RBX, RAX, 1, 0), xmm_reg); -#else - MOVSS(M((void*)((u32)Memory::base + (address & Memory::MEMVIEW32_MASK))), xmm_reg); -#endif -} - -void Jit64::ForceSinglePrecisionS(X64Reg xmm) { - // Most games don't need these. Zelda requires it though - some platforms get stuck without them. - if (jo.accurateSinglePrecision) - { - CVTSD2SS(xmm, R(xmm)); - CVTSS2SD(xmm, R(xmm)); - } -} - -void Jit64::ForceSinglePrecisionP(X64Reg xmm) { - // Most games don't need these. Zelda requires it though - some platforms get stuck without them. - if (jo.accurateSinglePrecision) - { - CVTPD2PS(xmm, R(xmm)); - CVTPS2PD(xmm, R(xmm)); - } -} diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp index cad1814bc6..b5a61ab676 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp @@ -34,7 +34,7 @@ #include "../../HW/GPFifo.h" #include "Jit.h" #include "JitAsm.h" -#include "JitCache.h" +#include "../JitCommon/JitCache.h" #include "JitRegCache.h" #if !defined JITTEST || ! JITTEST diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h index 8d7c48b771..7a9b51edb8 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h @@ -31,8 +31,12 @@ #define _JIT_H #include "../PPCAnalyst.h" -#include "JitCache.h" -#include "JitRegCache.h" +#include "../JitCommon/JitCache.h" +#if JITTEST +#include "../Jit64IL/JitRegCache.h" +#else +#include "../Jit64/JitRegCache.h" +#endif #include "x64Emitter.h" #include "x64Analyzer.h" #include "IR.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitAsm.cpp index 469931359a..2132b29b84 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitAsm.cpp @@ -27,7 +27,6 @@ #include "ABI.h" #include "Jit.h" -#include "JitCache.h" #include "Thunk.h" #include "../../HW/GPFifo.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitBackpatch.cpp deleted file mode 100644 index 65e5bbdea2..0000000000 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitBackpatch.cpp +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright (C) 2003-2008 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#include - -#include "Common.h" -#include "disasm.h" -#include "JitAsm.h" -#include "../../HW/Memmap.h" - -#include "x64Emitter.h" -#include "ABI.h" -#include "Thunk.h" -#include "x64Analyzer.h" - -#include "StringUtil.h" -#include "Jit.h" - -using namespace Gen; - -extern u8 *trampolineCodePtr; - -void BackPatchError(const std::string &text, u8 *codePtr, u32 emAddress) { - u64 code_addr = (u64)codePtr; - disassembler disasm; - char disbuf[256]; - memset(disbuf, 0, 256); -#ifdef _M_IX86 - disasm.disasm32(0, code_addr, codePtr, disbuf); -#else - disasm.disasm64(0, code_addr, codePtr, disbuf); -#endif - PanicAlert("%s\n\n" - "Error encountered accessing emulated address %08x.\n" - "Culprit instruction: \n%s\nat %08x%08x", - text.c_str(), emAddress, disbuf, code_addr>>32, code_addr); - return; -} - - -void TrampolineCache::Init() -{ - AllocCodeSpace(1024 * 1024); -} - -void TrampolineCache::Shutdown() -{ - AllocCodeSpace(1024 * 1024); -} - -// Extremely simplistic - just generate the requested trampoline. May reuse them in the future. -const u8 *TrampolineCache::GetReadTrampoline(const InstructionInfo &info) -{ - if (GetSpaceLeft() < 1024) - PanicAlert("Trampoline cache full"); - - X64Reg addrReg = (X64Reg)info.scaledReg; - X64Reg dataReg = (X64Reg)info.regOperandReg; - const u8 *trampoline = GetCodePtr(); -#ifdef _M_X64 - // It's a read. Easy. - ABI_PushAllCallerSavedRegsAndAdjustStack(); - if (addrReg != ABI_PARAM1) - MOV(32, R(ABI_PARAM1), R((X64Reg)addrReg)); - if (info.displacement) { - ADD(32, R(ABI_PARAM1), Imm32(info.displacement)); - } - switch (info.operandSize) { - case 4: - CALL(thunks.ProtectFunction((void *)&Memory::Read_U32, 1)); - break; - } - ABI_PopAllCallerSavedRegsAndAdjustStack(); - MOV(32, R(dataReg), R(EAX)); - RET(); -#endif - return trampoline; -} - -// Extremely simplistic - just generate the requested trampoline. May reuse them in the future. -const u8 *TrampolineCache::GetWriteTrampoline(const InstructionInfo &info) -{ - if (GetSpaceLeft() < 1024) - PanicAlert("Trampoline cache full"); - - X64Reg addrReg = (X64Reg)info.scaledReg; - X64Reg dataReg = (X64Reg)info.regOperandReg; - if (dataReg != EAX) - PanicAlert("Backpatch write - not through EAX"); - - const u8 *trampoline = GetCodePtr(); - -#ifdef _M_X64 - - // It's a write. Yay. Remember that we don't have to be super efficient since it's "just" a - // hardware access - we can take shortcuts. - //if (emAddress == 0xCC008000) - // PanicAlert("caught a fifo write"); - CMP(32, R(addrReg), Imm32(0xCC008000)); - FixupBranch skip_fast = J_CC(CC_NE, false); - MOV(32, R(ABI_PARAM1), R((X64Reg)dataReg)); - CALL((void*)asm_routines.fifoDirectWrite32); - RET(); - SetJumpTarget(skip_fast); - ABI_PushAllCallerSavedRegsAndAdjustStack(); - if (addrReg != ABI_PARAM1) { - MOV(32, R(ABI_PARAM1), R((X64Reg)dataReg)); - MOV(32, R(ABI_PARAM2), R((X64Reg)addrReg)); - } else { - MOV(32, R(ABI_PARAM2), R((X64Reg)addrReg)); - MOV(32, R(ABI_PARAM1), R((X64Reg)dataReg)); - } - if (info.displacement) { - ADD(32, R(ABI_PARAM2), Imm32(info.displacement)); - } - switch (info.operandSize) { - case 4: - CALL(thunks.ProtectFunction((void *)&Memory::Write_U32, 2)); - break; - } - ABI_PopAllCallerSavedRegsAndAdjustStack(); - RET(); -#endif - - return trampoline; -} - - -// This generates some fairly heavy trampolines, but: -// 1) It's really necessary. We don't know anything about the context. -// 2) It doesn't really hurt. Only instructions that access I/O will get these, and there won't be -// that many of them in a typical program/game. -const u8 *Jit64::BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx) -{ -#ifdef _M_X64 - if (!jit.IsInCodeSpace(codePtr)) - return 0; // this will become a regular crash real soon after this - - InstructionInfo info; - if (!DisassembleMov(codePtr, info, accessType)) { - BackPatchError("BackPatch - failed to disassemble MOV instruction", codePtr, emAddress); - } - - /* - if (info.isMemoryWrite) { - if (!Memory::IsRAMAddress(emAddress, true)) { - PanicAlert("Exception: Caught write to invalid address %08x", emAddress); - return; - } - BackPatchError("BackPatch - determined that MOV is write, not yet supported and should have been caught before", - codePtr, emAddress); - }*/ - - if (info.operandSize != 4) { - BackPatchError(StringFromFormat("BackPatch - no support for operand size %i", info.operandSize), codePtr, emAddress); - } - - if (info.otherReg != RBX) - PanicAlert("BackPatch : Base reg not RBX." - "\n\nAttempted to access %08x.", emAddress); - - if (accessType == OP_ACCESS_WRITE) - PanicAlert("BackPatch : Currently only supporting reads." - "\n\nAttempted to write to %08x.", emAddress); - - // In the first iteration, we assume that all accesses are 32-bit. We also only deal with reads. - if (accessType == 0) - { - XEmitter emitter(codePtr); - int bswapNopCount; - // Check the following BSWAP for REX byte - if ((codePtr[info.instructionSize] & 0xF0) == 0x40) - bswapNopCount = 3; - else - bswapNopCount = 2; - const u8 *trampoline = trampolines.GetReadTrampoline(info); - emitter.CALL((void *)trampoline); - emitter.NOP((int)info.instructionSize + bswapNopCount - 5); - return codePtr; - } - else if (accessType == 1) - { - // TODO: special case FIFO writes. Also, support 32-bit mode. - // Also, debug this so that it actually works correctly :P - XEmitter emitter(codePtr - 2); - // We know it's EAX so the BSWAP before will be two byte. Overwrite it. - const u8 *trampoline = trampolines.GetWriteTrampoline(info); - emitter.CALL((void *)trampoline); - emitter.NOP((int)info.instructionSize - 3); - if (info.instructionSize < 3) - PanicAlert("instruction too small"); - // We entered here with a BSWAP-ed EAX. We'll have to swap it back. - ctx->Rax = Common::swap32((u32)ctx->Rax); - return codePtr - 2; - } - return 0; -#else - return 0; -#endif -} - diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitCache.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitCache.cpp deleted file mode 100644 index 6d3871d3bd..0000000000 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitCache.cpp +++ /dev/null @@ -1,344 +0,0 @@ -// Copyright (C) 2003-2008 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -// Enable define below to enable oprofile integration. For this to work, -// it requires at least oprofile version 0.9.4, and changing the build -// system to link the Dolphin executable against libopagent. Since the -// dependency is a little inconvenient and this is possibly a slight -// performance hit, it's not enabled by default, but it's useful for -// locating performance issues. - -#include "Common.h" -#include "../../Core.h" -#include "MemoryUtil.h" - -#include "../../HW/Memmap.h" -#include "../../CoreTiming.h" - -#include "../PowerPC.h" -#include "../PPCTables.h" -#include "../PPCAnalyst.h" - -#include "x64Emitter.h" -#include "x64Analyzer.h" - -#include "Jit.h" -#include "JitCache.h" -#include "JitAsm.h" - -#include "disasm.h" - -#if defined USE_OPROFILE && USE_OPROFILE -#include -#endif - -#if defined USE_OPROFILE && USE_OPROFILE - op_agent_t agent; -#endif - -using namespace Gen; - -#define INVALID_EXIT 0xFFFFFFFF - - -bool JitBlock::ContainsAddress(u32 em_address) -{ - // WARNING - THIS DOES NOT WORK WITH INLINING ENABLED. - return (em_address >= originalAddress && em_address < originalAddress + originalSize); -} - - bool JitBlockCache::IsFull() const - { - return GetNumBlocks() >= MAX_NUM_BLOCKS - 1; - } - - void JitBlockCache::Init() - { - MAX_NUM_BLOCKS = 65536*2; - if (Core::g_CoreStartupParameter.bJITUnlimitedCache) - { - MAX_NUM_BLOCKS = 65536*8; - } - -#if defined USE_OPROFILE && USE_OPROFILE - agent = op_open_agent(); -#endif - blocks = new JitBlock[MAX_NUM_BLOCKS]; - blockCodePointers = new const u8*[MAX_NUM_BLOCKS]; - - Clear(); - } - - void JitBlockCache::Shutdown() - { - delete [] blocks; - delete [] blockCodePointers; - blocks = 0; - blockCodePointers = 0; - num_blocks = 0; -#if defined USE_OPROFILE && USE_OPROFILE - op_close_agent(agent); -#endif - } - - // This clears the JIT cache. It's called from JitCache.cpp when the JIT cache - // is full and when saving and loading states. - void JitBlockCache::Clear() - { - Core::DisplayMessage("Cleared code cache.", 3000); - // Is destroying the blocks really necessary? - for (int i = 0; i < num_blocks; i++) - { - DestroyBlock(i, false); - } - links_to.clear(); - num_blocks = 0; - memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS); - } - - void JitBlockCache::DestroyBlocksWithFlag(BlockFlag death_flag) - { - for (int i = 0; i < num_blocks; i++) - { - if (blocks[i].flags & death_flag) - { - DestroyBlock(i, false); - } - } - } - - void JitBlockCache::Reset() - { - Shutdown(); - Init(); - } - - JitBlock *JitBlockCache::GetBlock(int no) - { - return &blocks[no]; - } - - int JitBlockCache::GetNumBlocks() const - { - return num_blocks; - } - - bool JitBlockCache::RangeIntersect(int s1, int e1, int s2, int e2) const - { - // check if any endpoint is inside the other range - if ((s1 >= s2 && s1 <= e2) || - (e1 >= s2 && e1 <= e2) || - (s2 >= s1 && s2 <= e1) || - (e2 >= s1 && e2 <= e1)) - return true; - else - return false; - } - - int JitBlockCache::AllocateBlock(u32 em_address) - { - JitBlock &b = blocks[num_blocks]; - b.invalid = false; - b.originalAddress = em_address; - b.originalFirstOpcode = Memory::ReadFast32(em_address); - b.exitAddress[0] = INVALID_EXIT; - b.exitAddress[1] = INVALID_EXIT; - b.exitPtrs[0] = 0; - b.exitPtrs[1] = 0; - b.linkStatus[0] = false; - b.linkStatus[1] = false; - num_blocks++; //commit the current block - return num_blocks - 1; - } - - void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr) - { - blockCodePointers[block_num] = code_ptr; - JitBlock &b = blocks[block_num]; - Memory::WriteUnchecked_U32((JIT_OPCODE << 26) | block_num, blocks[block_num].originalAddress); - if (block_link) - { - for (int i = 0; i < 2; i++) - { - if (b.exitAddress[i] != INVALID_EXIT) - links_to.insert(std::pair(b.exitAddress[i], block_num)); - } - - LinkBlock(block_num); - LinkBlockExits(block_num); - } - -#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); -#endif - } - - const u8 **JitBlockCache::GetCodePointers() - { - return blockCodePointers; - } - - int JitBlockCache::GetBlockNumberFromStartAddress(u32 addr) - { - if (!blocks) - return -1; - u32 code = Memory::ReadFast32(addr); - if ((code >> 26) == JIT_OPCODE) - { - // Jitted code. - unsigned int block = code & 0x03FFFFFF; - if (block >= (unsigned int)num_blocks) { - return -1; - } - - if (blocks[block].originalAddress != addr) - { - //_assert_msg_(DYNA_REC, 0, "GetBlockFromAddress %08x - No match - This is BAD", addr); - return -1; - } - return block; - } - else - { - return -1; - } - } - -void JitBlockCache::GetBlockNumbersFromAddress(u32 em_address, std::vector *block_numbers) -{ - for (int i = 0; i < num_blocks; i++) - if (blocks[i].ContainsAddress(em_address)) - block_numbers->push_back(i); -} - - u32 JitBlockCache::GetOriginalCode(u32 address) - { - int num = GetBlockNumberFromStartAddress(address); - if (num == -1) - return Memory::ReadUnchecked_U32(address); - else - return blocks[num].originalFirstOpcode; - } - - CompiledCode JitBlockCache::GetCompiledCodeFromBlock(int blockNumber) - { - return (CompiledCode)blockCodePointers[blockNumber]; - } - - //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]; - if (b.invalid) - { - // This block is dead. Don't relink it. - return; - } - for (int e = 0; e < 2; e++) - { - if (b.exitAddress[e] != INVALID_EXIT && !b.linkStatus[e]) - { - int destinationBlock = GetBlockNumberFromStartAddress(b.exitAddress[e]); - if (destinationBlock != -1) - { - XEmitter emit(b.exitPtrs[e]); - emit.JMP(blocks[destinationBlock].checkedEntry, true); - b.linkStatus[e] = true; - } - } - } - } - - using namespace std; - - void JitBlockCache::LinkBlock(int i) - { - LinkBlockExits(i); - JitBlock &b = blocks[i]; - std::map::iterator iter; - pair::iterator, multimap::iterator> ppp; - // equal_range(b) returns pair representing the range - // of element with key b - ppp = links_to.equal_range(b.originalAddress); - if (ppp.first == ppp.second) - return; - for (multimap::iterator iter2 = ppp.first; iter2 != ppp.second; ++iter2) { - // PanicAlert("Linking block %i to block %i", iter2->second, i); - LinkBlockExits(iter2->second); - } - } - - void JitBlockCache::DestroyBlock(int blocknum, bool invalidate) - { - u32 codebytes = (JIT_OPCODE << 26) | blocknum; //generate from i - JitBlock &b = blocks[blocknum]; - b.invalid = 1; - if (codebytes == Memory::ReadFast32(b.originalAddress)) - { - //nobody has changed it, good - Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress); - } - else if (!invalidate) - { - //PanicAlert("Detected code overwrite"); - //else, we may be in trouble, since we apparently know of this block but it's been - //overwritten. We should have thrown it out before, on instruction cache invalidate or something. - //Not ne cessarily bad though , if a game has simply thrown away a lot of code and is now using the space - //for something else, then it's fine. - LOG(MASTER_LOG, "WARNING - ClearCache detected code overwrite @ %08x", blocks[blocknum].originalAddress); - } - - // We don't unlink blocks, we just send anyone who tries to run them back to the dispatcher. - // Not entirely ideal, but .. pretty good. - - // TODO - make sure that the below stuff really is safe. - - // Spurious entrances from previously linked blocks can only come through checkedEntry - XEmitter emit((u8 *)b.checkedEntry); - emit.MOV(32, M(&PC), Imm32(b.originalAddress)); - emit.JMP(asm_routines.dispatcher, true); - - emit.SetCodePtr((u8 *)blockCodePointers[blocknum]); - emit.MOV(32, M(&PC), Imm32(b.originalAddress)); - emit.JMP(asm_routines.dispatcher, true); - } - - - void JitBlockCache::InvalidateCodeRange(u32 address, u32 length) - { - if (!jit.jo.enableBlocklink) - return; - return; - //This is slow but should be safe (zelda needs it for block linking) - for (int i = 0; i < num_blocks; i++) - { - if (RangeIntersect(blocks[i].originalAddress, blocks[i].originalAddress + blocks[i].originalSize, - address, address + length)) - { - DestroyBlock(i, true); - } - } - } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitCache.h b/Source/Core/Core/Src/PowerPC/Jit64IL/JitCache.h deleted file mode 100644 index f75a5e1db2..0000000000 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitCache.h +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (C) 2003-2008 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef _JITCACHE_H -#define _JITCACHE_H - -#include -#include - -#include "../Gekko.h" -#include "../PPCAnalyst.h" - -#ifdef _WIN32 -#include -#endif - -enum BlockFlag -{ - BLOCK_USE_GQR0 = 0x1, BLOCK_USE_GQR1 = 0x2, BLOCK_USE_GQR2 = 0x4, BLOCK_USE_GQR3 = 0x8, - BLOCK_USE_GQR4 = 0x10, BLOCK_USE_GQR5 = 0x20, BLOCK_USE_GQR6 = 0x40, BLOCK_USE_GQR7 = 0x80, -}; - -// TODO(ector) - optimize this struct for size -struct JitBlock -{ - u32 exitAddress[2]; // 0xFFFFFFFF == unknown - u8 *exitPtrs[2]; // to be able to rewrite the exit jump - bool linkStatus[2]; - - u32 originalAddress; - u32 originalFirstOpcode; //to be able to restore - u32 codeSize; - u32 originalSize; - int runCount; // for profiling. - -#ifdef _WIN32 - // we don't really need to save start and stop - // TODO (mb2): ticStart and ticStop -> "local var" mean "in block" ... low priority ;) - LARGE_INTEGER ticStart; // for profiling - time. - LARGE_INTEGER ticStop; // for profiling - time. - LARGE_INTEGER ticCounter; // for profiling - time. -#endif - const u8 *checkedEntry; - bool invalid; - int flags; - - bool ContainsAddress(u32 em_address); -}; - -typedef void (*CompiledCode)(); - -class JitBlockCache -{ - const u8 **blockCodePointers; - JitBlock *blocks; - int num_blocks; - std::multimap links_to; - int MAX_NUM_BLOCKS; - - bool RangeIntersect(int s1, int e1, int s2, int e2) const; - void LinkBlockExits(int i); - void LinkBlock(int i); - -public: - JitBlockCache() {} - - int AllocateBlock(u32 em_address); - void FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr); - - void Clear(); - void Init(); - void Shutdown(); - void Reset(); - - bool IsFull() const; - - // Code Cache - JitBlock *GetBlock(int block_num); - int GetNumBlocks() const; - const u8 **GetCodePointers(); - - // Fast way to get a block. Only works on the first ppc instruction of a block. - int GetBlockNumberFromStartAddress(u32 em_address); - - // slower, but can get numbers from within blocks, not just the first instruction. - // WARNING! WILL NOT WORK WITH INLINING ENABLED (not yet a feature but will be soon) - // Returns a list of block numbers - only one block can start at a particular address, but they CAN overlap. - // This one is slow so should only be used for one-shots from the debugger UI, not for anything during runtime. - void GetBlockNumbersFromAddress(u32 em_address, std::vector *block_numbers); - - u32 GetOriginalCode(u32 address); - CompiledCode GetCompiledCodeFromBlock(int blockNumber); - - // DOES NOT WORK CORRECTLY WITH INLINING - void InvalidateCodeRange(u32 em_address, u32 length); - void DestroyBlock(int blocknum, bool invalidate); - - // Not currently used - void DestroyBlocksWithFlag(BlockFlag death_flag); -}; - -#endif diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitRegCache.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitRegCache.cpp index ca9680025d..e614c00957 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitRegCache.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitRegCache.cpp @@ -19,7 +19,6 @@ #include "../PPCTables.h" #include "../PPCAnalyst.h" #include "Jit.h" -#include "JitCache.h" #include "JitAsm.h" #include "JitRegCache.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp index 3fe7840354..9324750966 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp @@ -25,7 +25,6 @@ #include "Jit.h" #include "JitRegCache.h" -#include "JitCache.h" #include "JitAsm.h" // The branches are known good, or at least reasonably good. diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp index f0bbae1437..7a9da8fcb3 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp @@ -23,7 +23,6 @@ #include "x64Emitter.h" #include "Jit.h" -#include "JitCache.h" #include "JitRegCache.h" //#define INSTRUCTION_START Default(inst); return; diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp index ecd8851211..da820625e5 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp @@ -25,7 +25,6 @@ #include "x64Emitter.h" #include "Jit.h" -#include "JitCache.h" #include "JitRegCache.h" #include "JitAsm.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp index 0ee939f981..656a64253b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp @@ -32,7 +32,6 @@ #include "ABI.h" #include "Jit.h" -#include "JitCache.h" #include "JitAsm.h" #include "JitRegCache.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp index b0704ed450..22f0b93818 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp @@ -32,7 +32,6 @@ #include "ABI.h" #include "Jit.h" -#include "JitCache.h" #include "JitAsm.h" #include "JitRegCache.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStorePaired.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStorePaired.cpp index 79dc624e70..7802d929a0 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStorePaired.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStorePaired.cpp @@ -33,7 +33,6 @@ #include "ABI.h" #include "Jit.h" -#include "JitCache.h" #include "JitAsm.h" #include "JitRegCache.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Paired.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Paired.cpp index edaabad95d..e7ad4edccf 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Paired.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Paired.cpp @@ -24,7 +24,6 @@ #include "../../HW/GPFifo.h" #include "Jit.h" -#include "JitCache.h" #include "JitRegCache.h" void Jit64::ps_mr(UGeckoInstruction inst) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp index b3508925ba..99195933bf 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp @@ -27,7 +27,6 @@ #include "Thunk.h" #include "Jit.h" -#include "JitCache.h" #include "JitRegCache.h" //#define INSTRUCTION_START Default(inst); return; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp similarity index 97% rename from Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp rename to Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp index 65e5bbdea2..ec3e54522f 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp @@ -19,7 +19,13 @@ #include "Common.h" #include "disasm.h" -#include "JitAsm.h" +#ifdef JITTEST +#include "../Jit64IL/Jit.h" +#include "../Jit64IL/JitAsm.h" +#else +#include "../Jit64/Jit.h" +#include "../Jit64/JitAsm.h" +#endif #include "../../HW/Memmap.h" #include "x64Emitter.h" @@ -28,7 +34,6 @@ #include "x64Analyzer.h" #include "StringUtil.h" -#include "Jit.h" using namespace Gen; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp similarity index 98% rename from Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp rename to Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index 2edef0399c..58a04da501 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -36,9 +36,15 @@ #include "x64Emitter.h" #include "x64Analyzer.h" -#include "Jit.h" +#ifdef JITTEST +#include "../Jit64IL/Jit.h" +#include "../Jit64IL/JitAsm.h" +#else +#include "../Jit64/Jit.h" +#include "../Jit64/JitAsm.h" +#endif + #include "JitCache.h" -#include "JitAsm.h" #include "disasm.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h similarity index 100% rename from Source/Core/Core/Src/PowerPC/Jit64/JitCache.h rename to Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Util.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp similarity index 95% rename from Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Util.cpp rename to Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp index 20d5caddbf..ffe354660d 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Util.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp @@ -28,10 +28,17 @@ #include "x64Emitter.h" #include "ABI.h" -#include "Jit.h" +#ifdef JITTEST +#include "../Jit64IL/Jit.h" #include "JitCache.h" -#include "JitAsm.h" -#include "JitRegCache.h" +#include "../Jit64IL/JitAsm.h" +#include "../Jit64IL/JitRegCache.h" +#else +#include "../Jit64/Jit.h" +#include "JitCache.h" +#include "../Jit64/JitAsm.h" +#include "../Jit64/JitRegCache.h" +#endif void Jit64::JitClearCA() { diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.cpp b/Source/Core/Core/Src/PowerPC/PPCTables.cpp index c4518c6c1c..621ef61af5 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCTables.cpp @@ -25,7 +25,6 @@ #if defined(_M_IX86) || defined(_M_X64) #include "Jit64/Jit.h" -#include "Jit64/JitCache.h" #else #error Unknown architecture! #endif diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp index 3beae59f17..0d23220385 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp @@ -27,7 +27,6 @@ #include "Interpreter/Interpreter.h" #include "Jit64/Jit.h" -#include "Jit64/JitCache.h" #include "PowerPC.h" #include "PPCTables.h" diff --git a/Source/Core/Core/Src/SConscript b/Source/Core/Core/Src/SConscript index 3c53bcd8d7..39a8f11832 100644 --- a/Source/Core/Core/Src/SConscript +++ b/Source/Core/Core/Src/SConscript @@ -81,6 +81,9 @@ files = ["Console.cpp", "PowerPC/Interpreter/Interpreter_LoadStore.cpp", "PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp", "PowerPC/Interpreter/Interpreter_SystemRegisters.cpp", + "PowerPC/JitCommon/JitCache.cpp", + "PowerPC/JitCommon/JitBackpatch.cpp", + "PowerPC/JitCommon/Jit_Util.cpp", "HLE/HLE.cpp", "HLE/HLE_Misc.cpp", "HLE/HLE_OS.cpp", @@ -88,8 +91,6 @@ files = ["Console.cpp", if env['JITTEST']: files += ["PowerPC/Jit64IL/Jit.cpp", - "PowerPC/Jit64IL/JitBackpatch.cpp", - "PowerPC/Jit64IL/JitCache.cpp", "PowerPC/Jit64IL/JitRegCache.cpp", "PowerPC/Jit64IL/JitAsm.cpp", "PowerPC/Jit64IL/Jit_Branch.cpp", @@ -100,13 +101,10 @@ if env['JITTEST']: "PowerPC/Jit64IL/Jit_LoadStore.cpp", "PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp", "PowerPC/Jit64IL/Jit_SystemRegisters.cpp", - "PowerPC/Jit64IL/Jit_Util.cpp", "PowerPC/Jit64IL/IR.cpp", ] else: files += ["PowerPC/Jit64/Jit.cpp", - "PowerPC/Jit64/JitBackpatch.cpp", - "PowerPC/Jit64/JitCache.cpp", "PowerPC/Jit64/JitRegCache.cpp", "PowerPC/Jit64/JitAsm.cpp", "PowerPC/Jit64/Jit_Branch.cpp", @@ -117,7 +115,6 @@ else: "PowerPC/Jit64/Jit_LoadStore.cpp", "PowerPC/Jit64/Jit_LoadStoreFloating.cpp", "PowerPC/Jit64/Jit_SystemRegisters.cpp", - "PowerPC/Jit64/Jit_Util.cpp", ] libs = [ diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.cpp b/Source/Core/DebuggerWX/Src/CodeWindow.cpp index 4b3b1de03c..f6e37e2a41 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindow.cpp +++ b/Source/Core/DebuggerWX/Src/CodeWindow.cpp @@ -60,7 +60,7 @@ #include "PowerPC/SignatureDB.h" #include "PowerPC/PPCTables.h" #include "PowerPC/Jit64/Jit.h" -#include "PowerPC/Jit64/JitCache.h" // for ClearCache() +#include "PowerPC/JitCommon/JitCache.h" // for ClearCache() #include "PluginManager.h" #include "ConfigManager.h" diff --git a/Source/Core/DebuggerWX/Src/CodeWindowSJP.cpp b/Source/Core/DebuggerWX/Src/CodeWindowSJP.cpp index 02268f9fa5..9640ff1ac4 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindowSJP.cpp +++ b/Source/Core/DebuggerWX/Src/CodeWindowSJP.cpp @@ -61,7 +61,7 @@ #include "PowerPC/SignatureDB.h" #include "PowerPC/PPCTables.h" #include "PowerPC/Jit64/Jit.h" -#include "PowerPC/Jit64/JitCache.h" // for ClearCache() +#include "PowerPC/JitCommon/JitCache.h" // for ClearCache() #include "PluginManager.h" #include "ConfigManager.h" diff --git a/Source/Core/DebuggerWX/Src/JitWindow.cpp b/Source/Core/DebuggerWX/Src/JitWindow.cpp index 63afb0c228..a45121c528 100644 --- a/Source/Core/DebuggerWX/Src/JitWindow.cpp +++ b/Source/Core/DebuggerWX/Src/JitWindow.cpp @@ -23,11 +23,16 @@ #include #include #include + #include "JitWindow.h" #include "HW/CPU.h" #include "PowerPC/PowerPC.h" +#if JITTEST #include "PowerPC/Jit64/Jit.h" -#include "PowerPC/Jit64/JitCache.h" +#else +#include "PowerPC/Jit64IL/Jit.h" +#endif +#include "PowerPC/JitCommon/JitCache.h" #include "PowerPC/PPCAnalyst.h" #include "PowerPCDisasm.h" #include "Host.h" diff --git a/Source/Core/DolphinWX/DolphinWX.vcproj b/Source/Core/DolphinWX/DolphinWX.vcproj index f896aa36fc..50b64d9b97 100644 --- a/Source/Core/DolphinWX/DolphinWX.vcproj +++ b/Source/Core/DolphinWX/DolphinWX.vcproj @@ -103,7 +103,7 @@ SubSystem="2" BaseAddress="0x00400000" RandomizedBaseAddress="1" - DataExecutionPrevention="0" + DataExecutionPrevention="2" TargetMachine="1" />