Merge pull request #4516 from lioncash/jit
Jit: Move most x86-64-specific code out of JitCommon
This commit is contained in:
commit
49384208cf
|
@ -206,10 +206,11 @@ if(_M_X86)
|
|||
PowerPC/Jit64/Jit_Paired.cpp
|
||||
PowerPC/Jit64/JitRegCache.cpp
|
||||
PowerPC/Jit64/Jit_SystemRegisters.cpp
|
||||
PowerPC/Jit64Common/BlockCache.cpp
|
||||
PowerPC/Jit64Common/Jit64AsmCommon.cpp
|
||||
PowerPC/JitCommon/JitBackpatch.cpp
|
||||
PowerPC/JitCommon/Jit_Util.cpp
|
||||
PowerPC/JitCommon/TrampolineCache.cpp)
|
||||
PowerPC/Jit64Common/Jit64Base.cpp
|
||||
PowerPC/Jit64Common/Jit64Util.cpp
|
||||
PowerPC/Jit64Common/TrampolineCache.cpp)
|
||||
elseif(_M_ARM_64)
|
||||
set(SRCS ${SRCS}
|
||||
PowerPC/JitArm64/Jit.cpp
|
||||
|
|
|
@ -237,13 +237,14 @@
|
|||
<ClCompile Include="PowerPC\Jit64\Jit_LoadStorePaired.cpp" />
|
||||
<ClCompile Include="PowerPC\Jit64\Jit_Paired.cpp" />
|
||||
<ClCompile Include="PowerPC\Jit64\Jit_SystemRegisters.cpp" />
|
||||
<ClCompile Include="PowerPC\Jit64Common\BlockCache.cpp" />
|
||||
<ClCompile Include="PowerPC\Jit64Common\Jit64AsmCommon.cpp" />
|
||||
<ClCompile Include="PowerPC\Jit64Common\Jit64Base.cpp" />
|
||||
<ClCompile Include="PowerPC\Jit64Common\Jit64Util.cpp" />
|
||||
<ClCompile Include="PowerPC\Jit64Common\TrampolineCache.cpp" />
|
||||
<ClCompile Include="PowerPC\JitCommon\JitAsmCommon.cpp" />
|
||||
<ClCompile Include="PowerPC\JitCommon\JitBackpatch.cpp" />
|
||||
<ClCompile Include="PowerPC\JitCommon\JitBase.cpp" />
|
||||
<ClCompile Include="PowerPC\JitCommon\JitCache.cpp" />
|
||||
<ClCompile Include="PowerPC\JitCommon\Jit_Util.cpp" />
|
||||
<ClCompile Include="PowerPC\JitCommon\TrampolineCache.cpp" />
|
||||
<ClCompile Include="PowerPC\CachedInterpreter.cpp" />
|
||||
<ClCompile Include="PowerPC\JitInterface.cpp" />
|
||||
<ClCompile Include="PowerPC\MMU.cpp" />
|
||||
|
@ -429,12 +430,14 @@
|
|||
<ClInclude Include="PowerPC\Jit64\JitRegCache.h" />
|
||||
<ClInclude Include="PowerPC\JitILCommon\IR.h" />
|
||||
<ClInclude Include="PowerPC\JitILCommon\JitILBase.h" />
|
||||
<ClInclude Include="PowerPC\Jit64Common\BlockCache.h" />
|
||||
<ClInclude Include="PowerPC\Jit64Common\Jit64AsmCommon.h" />
|
||||
<ClInclude Include="PowerPC\Jit64Common\Jit64Base.h" />
|
||||
<ClInclude Include="PowerPC\Jit64Common\Jit64Util.h" />
|
||||
<ClInclude Include="PowerPC\Jit64Common\TrampolineCache.h" />
|
||||
<ClInclude Include="PowerPC\JitCommon\JitAsmCommon.h" />
|
||||
<ClInclude Include="PowerPC\JitCommon\JitBase.h" />
|
||||
<ClInclude Include="PowerPC\JitCommon\JitCache.h" />
|
||||
<ClInclude Include="PowerPC\JitCommon\Jit_Util.h" />
|
||||
<ClInclude Include="PowerPC\JitCommon\TrampolineCache.h" />
|
||||
<ClInclude Include="PowerPC\CachedInterpreter.h" />
|
||||
<ClInclude Include="PowerPC\JitInterface.h" />
|
||||
<ClInclude Include="PowerPC\PowerPC.h" />
|
||||
|
|
|
@ -651,9 +651,6 @@
|
|||
<ClCompile Include="PowerPC\SignatureDB.cpp">
|
||||
<Filter>PowerPC</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PowerPC\JitCommon\Jit_Util.cpp">
|
||||
<Filter>PowerPC\JitCommon</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PowerPC\JitCommon\JitAsmCommon.cpp">
|
||||
<Filter>PowerPC\JitCommon</Filter>
|
||||
</ClCompile>
|
||||
|
@ -663,9 +660,6 @@
|
|||
<ClCompile Include="PowerPC\JitCommon\JitCache.cpp">
|
||||
<Filter>PowerPC\JitCommon</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PowerPC\JitCommon\TrampolineCache.cpp">
|
||||
<Filter>PowerPC\JitCommon</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PowerPC\Jit64IL\IR_X86.cpp">
|
||||
<Filter>PowerPC\JitIL</Filter>
|
||||
</ClCompile>
|
||||
|
@ -741,12 +735,21 @@
|
|||
<ClCompile Include="PowerPC\MMU.cpp">
|
||||
<Filter>PowerPC</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PowerPC\JitCommon\JitBackpatch.cpp">
|
||||
<Filter>PowerPC\JitCommon</Filter>
|
||||
<ClCompile Include="PowerPC\Jit64Common\BlockCache.cpp">
|
||||
<Filter>PowerPC\Jit64Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PowerPC\Jit64Common\Jit64AsmCommon.cpp">
|
||||
<Filter>PowerPC\Jit64Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PowerPC\Jit64Common\Jit64Base.cpp">
|
||||
<Filter>PowerPC\Jit64Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PowerPC\Jit64Common\Jit64Util.cpp">
|
||||
<Filter>PowerPC\Jit64Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PowerPC\Jit64Common\TrampolineCache.cpp">
|
||||
<Filter>PowerPC\Jit64Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Analytics.cpp" />
|
||||
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb_ven.cpp">
|
||||
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
|
||||
|
@ -1238,9 +1241,6 @@
|
|||
<ClInclude Include="PowerPC\SignatureDB.h">
|
||||
<Filter>PowerPC</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PowerPC\JitCommon\Jit_Util.h">
|
||||
<Filter>PowerPC\JitCommon</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PowerPC\JitCommon\JitAsmCommon.h">
|
||||
<Filter>PowerPC\JitCommon</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1250,9 +1250,6 @@
|
|||
<ClInclude Include="PowerPC\JitCommon\JitCache.h">
|
||||
<Filter>PowerPC\JitCommon</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PowerPC\JitCommon\TrampolineCache.h">
|
||||
<Filter>PowerPC\JitCommon</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PowerPC\Jit64IL\JitIL.h">
|
||||
<Filter>PowerPC\JitIL</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1278,9 +1275,21 @@
|
|||
<ClInclude Include="HW\GCKeyboard.h">
|
||||
<Filter>HW %28Flipper/Hollywood%29\GCKeyboard</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PowerPC\Jit64Common\BlockCache.h">
|
||||
<Filter>PowerPC\Jit64Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PowerPC\Jit64Common\Jit64AsmCommon.h">
|
||||
<Filter>PowerPC\Jit64Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PowerPC\Jit64Common\Jit64Base.h">
|
||||
<Filter>PowerPC\Jit64Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PowerPC\Jit64Common\Jit64Util.h">
|
||||
<Filter>PowerPC\Jit64Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PowerPC\Jit64Common\TrampolineCache.h">
|
||||
<Filter>PowerPC\Jit64Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Analytics.h" />
|
||||
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_ven.h">
|
||||
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HW/CPU.h"
|
||||
#include "Core/PowerPC/Gekko.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "Core/PowerPC/Jit64/Jit64_Tables.h"
|
||||
#include "Core/PowerPC/Jit64/JitAsm.h"
|
||||
#include "Core/PowerPC/Jit64/JitRegCache.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Core/PowerPC/JitInterface.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/PowerPC/Profiler.h"
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/Jit64/JitAsm.h"
|
||||
#include "Core/PowerPC/Jit64/JitRegCache.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Base.h"
|
||||
#include "Core/PowerPC/JitCommon/JitCache.h"
|
||||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/Jit64/Jit.h"
|
||||
#include "Core/PowerPC/Jit64/JitRegCache.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
using namespace Gen;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/Jit64/Jit.h"
|
||||
#include "Core/PowerPC/Jit64/JitRegCache.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "Core/HW/DSP.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/PowerPC/Jit64/JitRegCache.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Core/PowerPC/JitInterface.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
|
|
|
@ -4,11 +4,10 @@
|
|||
|
||||
#include "Core/PowerPC/Jit64/Jit.h"
|
||||
#include "Common/BitSet.h"
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/Jit64/JitRegCache.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
|
||||
using namespace Gen;
|
||||
|
||||
|
|
|
@ -6,13 +6,12 @@
|
|||
// Should give a very noticeable speed boost to paired single heavy code.
|
||||
|
||||
#include "Core/PowerPC/Jit64/Jit.h"
|
||||
#include "Common/BitSet.h"
|
||||
#include "Common/CPUDetect.h"
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/Jit64/JitRegCache.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Core/PowerPC/JitCommon/JitAsmCommon.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
using namespace Gen;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "Core/CoreTiming.h"
|
||||
#include "Core/HW/ProcessorInterface.h"
|
||||
#include "Core/PowerPC/Jit64/JitRegCache.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
using namespace Gen;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2016 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/PowerPC/Jit64Common/BlockCache.h"
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
|
||||
void JitBlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest)
|
||||
{
|
||||
u8* location = source.exitPtrs;
|
||||
const u8* address = dest ? dest->checkedEntry : jit->GetAsmRoutines()->dispatcher;
|
||||
Gen::XEmitter emit(location);
|
||||
if (*location == 0xE8)
|
||||
{
|
||||
emit.CALL(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're going to link with the next block, there is no need
|
||||
// to emit JMP. So just NOP out the gap to the next block.
|
||||
// Support up to 3 additional bytes because of alignment.
|
||||
s64 offset = address - emit.GetCodePtr();
|
||||
if (offset > 0 && offset <= 5 + 3)
|
||||
emit.NOP(offset);
|
||||
else
|
||||
emit.JMP(address, true);
|
||||
}
|
||||
}
|
||||
|
||||
void JitBlockCache::WriteDestroyBlock(const JitBlock& block)
|
||||
{
|
||||
// Only clear the entry points as we might still be within this block.
|
||||
Gen::XEmitter emit(const_cast<u8*>(block.checkedEntry));
|
||||
emit.INT3();
|
||||
Gen::XEmitter emit2(const_cast<u8*>(block.normalEntry));
|
||||
emit2.INT3();
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2016 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Core/PowerPC/JitCommon/JitCache.h"
|
||||
|
||||
class JitBlockCache : public JitBaseBlockCache
|
||||
{
|
||||
private:
|
||||
void WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest) override;
|
||||
void WriteDestroyBlock(const JitBlock& block) override;
|
||||
};
|
|
@ -11,8 +11,8 @@
|
|||
#include "Common/x64Emitter.h"
|
||||
#include "Core/HW/GPFifo.h"
|
||||
#include "Core/PowerPC/Gekko.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Base.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
#define QUANTIZED_REGS_TO_SAVE \
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Core/PowerPC/JitCommon/JitAsmCommon.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
|
||||
enum EQuantizeType : u32;
|
||||
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
// Copyright 2008 Dolphin Emulator Project
|
||||
// Copyright 2016 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cinttypes>
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Base.h"
|
||||
|
||||
#include <disasm.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "disasm.h"
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/BitSet.h"
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/GekkoDisassembler.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/x64Emitter.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Common/x64Reg.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
|
||||
using namespace Gen;
|
||||
#include "Core/MachineContext.h"
|
||||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
|
||||
// This generates some fairly heavy trampolines, but it doesn't really hurt.
|
||||
// Only instructions that access I/O will get these, and there won't be that
|
||||
|
@ -24,19 +26,20 @@ using namespace Gen;
|
|||
bool Jitx86Base::HandleFault(uintptr_t access_address, SContext* ctx)
|
||||
{
|
||||
// TODO: do we properly handle off-the-end?
|
||||
if (access_address >= (uintptr_t)Memory::physical_base &&
|
||||
access_address < (uintptr_t)Memory::physical_base + 0x100010000)
|
||||
return BackPatch((u32)(access_address - (uintptr_t)Memory::physical_base), ctx);
|
||||
if (access_address >= (uintptr_t)Memory::logical_base &&
|
||||
access_address < (uintptr_t)Memory::logical_base + 0x100010000)
|
||||
return BackPatch((u32)(access_address - (uintptr_t)Memory::logical_base), ctx);
|
||||
const auto base_ptr = reinterpret_cast<uintptr_t>(Memory::physical_base);
|
||||
if (access_address >= base_ptr && access_address < base_ptr + 0x100010000)
|
||||
return BackPatch(static_cast<u32>(access_address - base_ptr), ctx);
|
||||
|
||||
const auto logical_base_ptr = reinterpret_cast<uintptr_t>(Memory::logical_base);
|
||||
if (access_address >= logical_base_ptr && access_address < logical_base_ptr + 0x100010000)
|
||||
return BackPatch(static_cast<u32>(access_address - logical_base_ptr), ctx);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Jitx86Base::BackPatch(u32 emAddress, SContext* ctx)
|
||||
{
|
||||
u8* codePtr = (u8*)ctx->CTX_PC;
|
||||
u8* codePtr = reinterpret_cast<u8*>(ctx->CTX_PC);
|
||||
|
||||
if (!IsInSpace(codePtr))
|
||||
return false; // this will become a regular crash real soon after this
|
||||
|
@ -87,7 +90,7 @@ bool Jitx86Base::BackPatch(u32 emAddress, SContext* ctx)
|
|||
// before faulting (eg: the store+swap was not an atomic op like MOVBE), let's
|
||||
// swap it back so that the swap can happen again (this double swap isn't ideal but
|
||||
// only happens the first time we fault).
|
||||
if (info.nonAtomicSwapStoreSrc != INVALID_REG)
|
||||
if (info.nonAtomicSwapStoreSrc != Gen::INVALID_REG)
|
||||
{
|
||||
u64* ptr = ContextRN(ctx, info.nonAtomicSwapStoreSrc);
|
||||
switch (info.accessSize << 3)
|
||||
|
@ -122,3 +125,41 @@ bool Jitx86Base::BackPatch(u32 emAddress, SContext* ctx)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LogGeneratedX86(int size, PPCAnalyst::CodeBuffer* code_buffer, const u8* normalEntry,
|
||||
JitBlock* b)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
const PPCAnalyst::CodeOp& op = code_buffer->codebuffer[i];
|
||||
std::string temp = StringFromFormat(
|
||||
"%08x %s", op.address, GekkoDisassembler::Disassemble(op.inst.hex, op.address).c_str());
|
||||
DEBUG_LOG(DYNA_REC, "IR_X86 PPC: %s\n", temp.c_str());
|
||||
}
|
||||
|
||||
disassembler x64disasm;
|
||||
x64disasm.set_syntax_intel();
|
||||
|
||||
u64 disasmPtr = reinterpret_cast<u64>(normalEntry);
|
||||
const u8* end = normalEntry + b->codeSize;
|
||||
|
||||
while (reinterpret_cast<u8*>(disasmPtr) < end)
|
||||
{
|
||||
char sptr[1000] = "";
|
||||
disasmPtr += x64disasm.disasm64(disasmPtr, disasmPtr, reinterpret_cast<u8*>(disasmPtr), sptr);
|
||||
DEBUG_LOG(DYNA_REC, "IR_X86 x86: %s", sptr);
|
||||
}
|
||||
|
||||
if (b->codeSize <= 250)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex;
|
||||
for (u8 i = 0; i <= b->codeSize; i++)
|
||||
{
|
||||
ss.width(2);
|
||||
ss.fill('0');
|
||||
ss << static_cast<u32>(*(normalEntry + i));
|
||||
}
|
||||
DEBUG_LOG(DYNA_REC, "IR_X86 bin: %s\n\n\n", ss.str().c_str());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2016 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/x64Reg.h"
|
||||
#include "Core/PowerPC/Jit64Common/BlockCache.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64AsmCommon.h"
|
||||
#include "Core/PowerPC/Jit64Common/TrampolineCache.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
|
||||
namespace PPCAnalyst
|
||||
{
|
||||
class CodeBuffer;
|
||||
}
|
||||
|
||||
// The following register assignments are common to Jit64 and Jit64IL:
|
||||
// RSCRATCH and RSCRATCH2 are always scratch registers and can be used without
|
||||
// limitation.
|
||||
constexpr Gen::X64Reg RSCRATCH = Gen::RAX;
|
||||
constexpr Gen::X64Reg RSCRATCH2 = Gen::RDX;
|
||||
// RSCRATCH_EXTRA may be in the allocation order, so it has to be flushed
|
||||
// before use.
|
||||
constexpr Gen::X64Reg RSCRATCH_EXTRA = Gen::RCX;
|
||||
// RMEM points to the start of emulated memory.
|
||||
constexpr Gen::X64Reg RMEM = Gen::RBX;
|
||||
// RPPCSTATE points to ppcState + 0x80. It's offset because we want to be able
|
||||
// to address as much as possible in a one-byte offset form.
|
||||
constexpr Gen::X64Reg RPPCSTATE = Gen::RBP;
|
||||
|
||||
class Jitx86Base : public JitBase, public QuantizedMemoryRoutines
|
||||
{
|
||||
protected:
|
||||
bool BackPatch(u32 emAddress, SContext* ctx);
|
||||
JitBlockCache blocks;
|
||||
TrampolineCache trampolines;
|
||||
|
||||
public:
|
||||
JitBlockCache* GetBlockCache() override { return &blocks; }
|
||||
bool HandleFault(uintptr_t access_address, SContext* ctx) override;
|
||||
};
|
||||
|
||||
void LogGeneratedX86(int size, PPCAnalyst::CodeBuffer* code_buffer, const u8* normalEntry,
|
||||
JitBlock* b);
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Common/BitSet.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Intrinsics.h"
|
||||
|
@ -11,7 +11,8 @@
|
|||
#include "Common/x64Emitter.h"
|
||||
#include "Core/HW/MMIO.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Base.h"
|
||||
#include "Core/PowerPC/Jit64Common/TrampolineCache.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
using namespace Gen;
|
||||
|
@ -79,7 +80,7 @@ bool EmuCodeBlock::UnsafeLoadToReg(X64Reg reg_value, OpArg opAddress, int access
|
|||
{
|
||||
// This method can potentially clobber the address if it shares a register
|
||||
// with the load target. In this case we can just subtract offset from the
|
||||
// register (see JitBackpatch for this implementation).
|
||||
// register (see Jit64Base for this implementation).
|
||||
offsetAddedToAddress = (reg_value == opAddress.GetSimpleReg());
|
||||
|
||||
LEA(32, reg_value, MDisp(opAddress.GetSimpleReg(), offset));
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "Common/BitSet.h"
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
|
@ -48,16 +49,16 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static const int CODE_SIZE = 1024 * 1024 * 32;
|
||||
constexpr int CODE_SIZE = 1024 * 1024 * 32;
|
||||
|
||||
// a bit of a hack; the MMU results in a vast amount more code ending up in the far cache,
|
||||
// mostly exception handling, so give it a whole bunch more space if the MMU is on.
|
||||
static const int FARCODE_SIZE = 1024 * 1024 * 8;
|
||||
static const int FARCODE_SIZE_MMU = 1024 * 1024 * 48;
|
||||
constexpr int FARCODE_SIZE = 1024 * 1024 * 8;
|
||||
constexpr int FARCODE_SIZE_MMU = 1024 * 1024 * 48;
|
||||
|
||||
// same for the trampoline code cache, because fastmem results in far more backpatches in MMU mode
|
||||
static const int TRAMPOLINE_CODE_SIZE = 1024 * 1024 * 8;
|
||||
static const int TRAMPOLINE_CODE_SIZE_MMU = 1024 * 1024 * 32;
|
||||
constexpr int TRAMPOLINE_CODE_SIZE = 1024 * 1024 * 8;
|
||||
constexpr int TRAMPOLINE_CODE_SIZE_MMU = 1024 * 1024 * 32;
|
||||
|
||||
// Stores information we need to batch-patch a MOV with a call to the slow read/write path after
|
||||
// it faults. There will be 10s of thousands of these structs live, so be wary of making this too
|
|
@ -2,17 +2,18 @@
|
|||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/PowerPC/Jit64Common/TrampolineCache.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <string>
|
||||
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/JitRegister.h"
|
||||
#include "Common/x64ABI.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Base.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/JitCommon/TrampolineCache.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
#ifdef _WIN32
|
|
@ -4,15 +4,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Common/BitSet.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
|
||||
struct InstructionInfo;
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Util.h"
|
||||
|
||||
// We need at least this many bytes for backpatching.
|
||||
const int BACKPATCH_SIZE = 5;
|
||||
constexpr int BACKPATCH_SIZE = 5;
|
||||
|
||||
class TrampolineCache : public EmuCodeBlock
|
||||
{
|
|
@ -21,7 +21,6 @@
|
|||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/Gekko.h"
|
||||
#include "Core/PowerPC/Jit64/JitAsm.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
#include "Core/PowerPC/JitCommon/JitCache.h"
|
||||
#include "Core/PowerPC/JitILCommon/JitILBase.h"
|
||||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
|
||||
constexpr int CODE_SIZE = 1024 * 1024 * 32;
|
||||
constexpr int FARCODE_SIZE_MMU = 1024 * 1024 * 48;
|
||||
|
||||
class JitArm64 : public JitBase, public Arm64Gen::ARM64CodeBlock, public CommonAsmRoutinesBase
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -2,18 +2,11 @@
|
|||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "disasm.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/GekkoDisassembler.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/HW/CPU.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
|
@ -30,44 +23,6 @@ u32 Helper_Mask(u8 mb, u8 me)
|
|||
return mb > me ? ~mask : mask;
|
||||
}
|
||||
|
||||
void LogGeneratedX86(int size, PPCAnalyst::CodeBuffer* code_buffer, const u8* normalEntry,
|
||||
JitBlock* b)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
const PPCAnalyst::CodeOp& op = code_buffer->codebuffer[i];
|
||||
std::string temp = StringFromFormat(
|
||||
"%08x %s", op.address, GekkoDisassembler::Disassemble(op.inst.hex, op.address).c_str());
|
||||
DEBUG_LOG(DYNA_REC, "IR_X86 PPC: %s\n", temp.c_str());
|
||||
}
|
||||
|
||||
disassembler x64disasm;
|
||||
x64disasm.set_syntax_intel();
|
||||
|
||||
u64 disasmPtr = (u64)normalEntry;
|
||||
const u8* end = normalEntry + b->codeSize;
|
||||
|
||||
while ((u8*)disasmPtr < end)
|
||||
{
|
||||
char sptr[1000] = "";
|
||||
disasmPtr += x64disasm.disasm64(disasmPtr, disasmPtr, (u8*)disasmPtr, sptr);
|
||||
DEBUG_LOG(DYNA_REC, "IR_X86 x86: %s", sptr);
|
||||
}
|
||||
|
||||
if (b->codeSize <= 250)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex;
|
||||
for (u8 i = 0; i <= b->codeSize; i++)
|
||||
{
|
||||
ss.width(2);
|
||||
ss.fill('0');
|
||||
ss << (u32) * (normalEntry + i);
|
||||
}
|
||||
DEBUG_LOG(DYNA_REC, "IR_X86 bin: %s\n\n\n", ss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool JitBase::MergeAllowedNextInstructions(int count)
|
||||
{
|
||||
if (CPU::GetState() == CPU::CPU_STEPPING || js.instructionsLeft < count)
|
||||
|
|
|
@ -16,27 +16,10 @@
|
|||
#include "Core/ConfigManager.h"
|
||||
#include "Core/MachineContext.h"
|
||||
#include "Core/PowerPC/CPUCoreBase.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64AsmCommon.h"
|
||||
#include "Core/PowerPC/JitCommon/JitAsmCommon.h"
|
||||
#include "Core/PowerPC/JitCommon/JitCache.h"
|
||||
#include "Core/PowerPC/JitCommon/Jit_Util.h"
|
||||
#include "Core/PowerPC/JitCommon/TrampolineCache.h"
|
||||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
|
||||
// TODO: find a better place for x86-specific stuff
|
||||
// The following register assignments are common to Jit64 and Jit64IL:
|
||||
// RSCRATCH and RSCRATCH2 are always scratch registers and can be used without
|
||||
// limitation.
|
||||
#define RSCRATCH RAX
|
||||
#define RSCRATCH2 RDX
|
||||
// RSCRATCH_EXTRA may be in the allocation order, so it has to be flushed
|
||||
// before use.
|
||||
#define RSCRATCH_EXTRA RCX
|
||||
// RMEM points to the start of emulated memory.
|
||||
#define RMEM RBX
|
||||
// RPPCSTATE points to ppcState + 0x80. It's offset because we want to be able
|
||||
// to address as much as possible in a one-byte offset form.
|
||||
#define RPPCSTATE RBP
|
||||
|
||||
// Use these to control the instruction selection
|
||||
// #define INSTRUCTION_START FallBackToInterpreter(inst); return;
|
||||
// #define INSTRUCTION_START PPCTables::CountInstruction(inst);
|
||||
|
@ -142,21 +125,7 @@ public:
|
|||
virtual bool HandleStackFault() { return false; }
|
||||
};
|
||||
|
||||
class Jitx86Base : public JitBase, public QuantizedMemoryRoutines
|
||||
{
|
||||
protected:
|
||||
bool BackPatch(u32 emAddress, SContext* ctx);
|
||||
JitBlockCache blocks;
|
||||
TrampolineCache trampolines;
|
||||
|
||||
public:
|
||||
JitBlockCache* GetBlockCache() override { return &blocks; }
|
||||
bool HandleFault(uintptr_t access_address, SContext* ctx) override;
|
||||
};
|
||||
|
||||
void Jit(u32 em_address);
|
||||
|
||||
// Merged routines that should be moved somewhere better
|
||||
u32 Helper_Mask(u8 mb, u8 me);
|
||||
void LogGeneratedX86(int size, PPCAnalyst::CodeBuffer* code_buffer, const u8* normalEntry,
|
||||
JitBlock* b);
|
||||
|
|
|
@ -352,34 +352,3 @@ void JitBaseBlockCache::InvalidateICache(u32 address, const u32 length, bool for
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JitBlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest)
|
||||
{
|
||||
u8* location = source.exitPtrs;
|
||||
const u8* address = dest ? dest->checkedEntry : jit->GetAsmRoutines()->dispatcher;
|
||||
XEmitter emit(location);
|
||||
if (*location == 0xE8)
|
||||
{
|
||||
emit.CALL(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're going to link with the next block, there is no need
|
||||
// to emit JMP. So just NOP out the gap to the next block.
|
||||
// Support up to 3 additional bytes because of alignment.
|
||||
s64 offset = address - emit.GetCodePtr();
|
||||
if (offset > 0 && offset <= 5 + 3)
|
||||
emit.NOP(offset);
|
||||
else
|
||||
emit.JMP(address, true);
|
||||
}
|
||||
}
|
||||
|
||||
void JitBlockCache::WriteDestroyBlock(const JitBlock& block)
|
||||
{
|
||||
// Only clear the entry points as we might still be within this block.
|
||||
XEmitter emit((u8*)block.checkedEntry);
|
||||
emit.INT3();
|
||||
XEmitter emit2((u8*)block.normalEntry);
|
||||
emit2.INT3();
|
||||
}
|
||||
|
|
|
@ -186,11 +186,3 @@ public:
|
|||
|
||||
u32* GetBlockBitSet() const { return valid_block.m_valid_block.get(); }
|
||||
};
|
||||
|
||||
// x86 BlockCache
|
||||
class JitBlockCache : public JitBaseBlockCache
|
||||
{
|
||||
private:
|
||||
void WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest) override;
|
||||
void WriteDestroyBlock(const JitBlock& block) override;
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/PowerPC/Gekko.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64Base.h"
|
||||
#include "Core/PowerPC/JitILCommon/IR.h"
|
||||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue