summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorMat M <mathew1800@gmail.com>2018-12-28 06:16:18 -0500
committerGitHub <noreply@github.com>2018-12-28 06:16:18 -0500
commitf006af441e87f0331ea39d38082a0a52a9b86277 (patch)
tree30369aee19a99fde0318da684fff5ec3c8778afc /Source
parentbfb9b1aca54481af905877edc0fe950e9273d3b1 (diff)
parent77e9aa48bc217f9143d7ee2dca4b213a1505a02f (diff)
Merge pull request #7655 from MerryMage/rm-Jitx86Base
Jit64: Remove Jitx86Base class
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/CMakeLists.txt1
-rw-r--r--Source/Core/Core/Core.vcxproj3
-rw-r--r--Source/Core/Core/Core.vcxproj.filters5
-rw-r--r--Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.cpp153
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.h16
-rw-r--r--Source/Core/Core/PowerPC/Jit64/JitAsm.cpp2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/JitAsm.h2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp1
-rw-r--r--Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.cpp2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.cpp2
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp5
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.h6
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp3
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.h4
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/Jit64Base.cpp165
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/Jit64Base.h47
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/Jit64Constants.h24
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/Jit64PowerPCState.h1
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.cpp3
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.h9
21 files changed, 214 insertions, 242 deletions
diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index b7c7caacd6..ccf1f69e64 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -255,7 +255,6 @@ if(_M_X86)
PowerPC/Jit64Common/EmuCodeBlock.cpp
PowerPC/Jit64Common/FarCodeCache.cpp
PowerPC/Jit64Common/Jit64AsmCommon.cpp
- PowerPC/Jit64Common/Jit64Base.cpp
PowerPC/Jit64Common/TrampolineCache.cpp
)
elseif(_M_ARM_64)
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 9a58d93f25..52d8aa400f 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -279,7 +279,6 @@
<ClCompile Include="PowerPC\Jit64Common\EmuCodeBlock.cpp" />
<ClCompile Include="PowerPC\Jit64Common\FarCodeCache.cpp" />
<ClCompile Include="PowerPC\Jit64Common\Jit64AsmCommon.cpp" />
- <ClCompile Include="PowerPC\Jit64Common\Jit64Base.cpp" />
<ClCompile Include="PowerPC\Jit64Common\TrampolineCache.cpp" />
<ClCompile Include="PowerPC\JitCommon\JitAsmCommon.cpp" />
<ClCompile Include="PowerPC\JitCommon\JitBase.cpp" />
@@ -523,7 +522,7 @@
<ClInclude Include="PowerPC\Jit64Common\EmuCodeBlock.h" />
<ClInclude Include="PowerPC\Jit64Common\FarCodeCache.h" />
<ClInclude Include="PowerPC\Jit64Common\Jit64AsmCommon.h" />
- <ClInclude Include="PowerPC\Jit64Common\Jit64Base.h" />
+ <ClInclude Include="PowerPC\Jit64Common\Jit64Constants.h" />
<ClInclude Include="PowerPC\Jit64Common\Jit64PowerPCState.h" />
<ClInclude Include="PowerPC\Jit64Common\TrampolineCache.h" />
<ClInclude Include="PowerPC\Jit64Common\TrampolineInfo.h" />
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 00add0e697..be4aca8f97 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -699,9 +699,6 @@
<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\TrampolineCache.cpp">
<Filter>PowerPC\Jit64Common</Filter>
</ClCompile>
@@ -1393,7 +1390,7 @@
<ClInclude Include="PowerPC\Jit64Common\Jit64AsmCommon.h">
<Filter>PowerPC\Jit64Common</Filter>
</ClInclude>
- <ClInclude Include="PowerPC\Jit64Common\Jit64Base.h">
+ <ClInclude Include="PowerPC\Jit64Common\Jit64Constants.h">
<Filter>PowerPC\Jit64Common</Filter>
</ClInclude>
<ClInclude Include="PowerPC\Jit64Common\Jit64PowerPCState.h">
diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
index 1c945b42b1..81bd4b9a00 100644
--- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
+++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
@@ -11,7 +11,7 @@
#include "Core/HLE/HLE.h"
#include "Core/HW/CPU.h"
#include "Core/PowerPC/Gekko.h"
-#include "Core/PowerPC/Jit64Common/Jit64Base.h"
+#include "Core/PowerPC/Jit64Common/Jit64Constants.h"
#include "Core/PowerPC/PPCAnalyst.h"
#include "Core/PowerPC/PowerPC.h"
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp
index 05574b303d..545047c40c 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp
@@ -4,7 +4,9 @@
#include "Core/PowerPC/Jit64/Jit.h"
+#include <disasm.h>
#include <map>
+#include <sstream>
#include <string>
// for the PROFILER stuff
@@ -14,21 +16,26 @@
#include "Common/CommonTypes.h"
#include "Common/File.h"
+#include "Common/GekkoDisassembler.h"
#include "Common/Logging/Log.h"
#include "Common/MemoryUtil.h"
#include "Common/PerformanceCounter.h"
#include "Common/StringUtil.h"
+#include "Common/Swap.h"
#include "Common/x64ABI.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/HLE/HLE.h"
#include "Core/HW/CPU.h"
#include "Core/HW/GPFifo.h"
+#include "Core/HW/Memmap.h"
#include "Core/HW/ProcessorInterface.h"
+#include "Core/MachineContext.h"
#include "Core/PatchEngine.h"
#include "Core/PowerPC/Jit64/JitAsm.h"
#include "Core/PowerPC/Jit64/RegCache/JitRegCache.h"
#include "Core/PowerPC/Jit64Common/FarCodeCache.h"
+#include "Core/PowerPC/Jit64Common/Jit64Constants.h"
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
#include "Core/PowerPC/Jit64Common/TrampolineCache.h"
#include "Core/PowerPC/JitInterface.h"
@@ -146,7 +153,9 @@ enum
GUARD_OFFSET = STACK_SIZE - SAFE_STACK_SIZE - GUARD_SIZE,
};
-Jit64::Jit64() = default;
+Jit64::Jit64() : QuantizedMemoryRoutines(*this)
+{
+}
Jit64::~Jit64() = default;
@@ -211,7 +220,110 @@ bool Jit64::HandleFault(uintptr_t access_address, SContext* ctx)
if (m_enable_blr_optimization && diff >= GUARD_OFFSET && diff < GUARD_OFFSET + GUARD_SIZE)
return HandleStackFault();
- return Jitx86Base::HandleFault(access_address, ctx);
+ // 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
+ // many of them in a typical program/game.
+
+ // TODO: do we properly handle off-the-end?
+ 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 Jit64::BackPatch(u32 emAddress, SContext* ctx)
+{
+ u8* codePtr = reinterpret_cast<u8*>(ctx->CTX_PC);
+
+ if (!IsInSpace(codePtr))
+ return false; // this will become a regular crash real soon after this
+
+ auto it = m_back_patch_info.find(codePtr);
+ if (it == m_back_patch_info.end())
+ {
+ PanicAlert("BackPatch: no register use entry for address %p", codePtr);
+ return false;
+ }
+
+ TrampolineInfo& info = it->second;
+
+ u8* exceptionHandler = nullptr;
+ if (jo.memcheck)
+ {
+ auto it2 = m_exception_handler_at_loc.find(codePtr);
+ if (it2 != m_exception_handler_at_loc.end())
+ exceptionHandler = it2->second;
+ }
+
+ // In the trampoline code, we jump back into the block at the beginning
+ // of the next instruction. The next instruction comes immediately
+ // after the backpatched operation, or BACKPATCH_SIZE bytes after the start
+ // of the backpatched operation, whichever comes last. (The JIT inserts NOPs
+ // into the original code if necessary to ensure there is enough space
+ // to insert the backpatch jump.)
+
+ js.generatingTrampoline = true;
+ js.trampolineExceptionHandler = exceptionHandler;
+ js.compilerPC = info.pc;
+
+ // Generate the trampoline.
+ const u8* trampoline = trampolines.GenerateTrampoline(info);
+ js.generatingTrampoline = false;
+ js.trampolineExceptionHandler = nullptr;
+
+ u8* start = info.start;
+
+ // Patch the original memory operation.
+ XEmitter emitter(start);
+ emitter.JMP(trampoline, true);
+ // NOPs become dead code
+ const u8* end = info.start + info.len;
+ for (const u8* i = emitter.GetCodePtr(); i < end; ++i)
+ emitter.INT3();
+
+ // Rewind time to just before the start of the write block. If we swapped memory
+ // 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 != Gen::INVALID_REG)
+ {
+ u64* ptr = ContextRN(ctx, info.nonAtomicSwapStoreSrc);
+ switch (info.accessSize << 3)
+ {
+ case 8:
+ // No need to swap a byte
+ break;
+ case 16:
+ *ptr = Common::swap16(static_cast<u16>(*ptr));
+ break;
+ case 32:
+ *ptr = Common::swap32(static_cast<u32>(*ptr));
+ break;
+ case 64:
+ *ptr = Common::swap64(static_cast<u64>(*ptr));
+ break;
+ default:
+ DEBUG_ASSERT(0);
+ break;
+ }
+ }
+
+ // This is special code to undo the LEA in SafeLoadToReg if it clobbered the address
+ // register in the case where reg_value shared the same location as opAddress.
+ if (info.offsetAddedToAddress)
+ {
+ u64* ptr = ContextRN(ctx, info.op_arg.GetSimpleReg());
+ *ptr -= static_cast<u32>(info.offset);
+ }
+
+ ctx->CTX_PC = reinterpret_cast<u64>(trampoline);
+
+ return true;
}
void Jit64::Init()
@@ -1044,3 +1156,40 @@ bool Jit64::HandleFunctionHooking(u32 address)
return true;
});
}
+
+void LogGeneratedX86(size_t size, const PPCAnalyst::CodeBuffer& code_buffer, const u8* normalEntry,
+ const JitBlock* b)
+{
+ for (size_t i = 0; i < size; i++)
+ {
+ const PPCAnalyst::CodeOp& op = code_buffer[i];
+ const std::string disasm = Common::GekkoDisassembler::Disassemble(op.inst.hex, op.address);
+ DEBUG_LOG(DYNA_REC, "IR_X86 PPC: %08x %s\n", op.address, disasm.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());
+ }
+}
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h
index 35b356f32d..452cdbdfc6 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.h
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.h
@@ -25,16 +25,19 @@
#include "Core/PowerPC/Jit64/RegCache/FPURegCache.h"
#include "Core/PowerPC/Jit64/RegCache/GPRRegCache.h"
#include "Core/PowerPC/Jit64/RegCache/JitRegCache.h"
-#include "Core/PowerPC/Jit64Common/Jit64Base.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"
#include "Core/PowerPC/JitCommon/JitCache.h"
namespace PPCAnalyst
{
struct CodeBlock;
struct CodeOp;
-}
+} // namespace PPCAnalyst
-class Jit64 : public Jitx86Base
+class Jit64 : public JitBase, public QuantizedMemoryRoutines
{
public:
Jit64();
@@ -45,6 +48,7 @@ public:
bool HandleFault(uintptr_t access_address, SContext* ctx) override;
bool HandleStackFault() override;
+ bool BackPatch(u32 emAddress, SContext* ctx);
void EnableOptimization();
void EnableBlockLink();
@@ -239,6 +243,9 @@ private:
void AllocStack();
void FreeStack();
+ JitBlockCache blocks{*this};
+ TrampolineCache trampolines{*this};
+
GPRRegCache gpr{*this};
FPURegCache fpr{*this};
@@ -248,3 +255,6 @@ private:
bool m_cleanup_after_stackfault;
u8* m_stack;
};
+
+void LogGeneratedX86(size_t size, const PPCAnalyst::CodeBuffer& code_buffer, const u8* normalEntry,
+ const JitBlock* b);
diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp
index 716f13f7e5..1389fb05cc 100644
--- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp
@@ -18,7 +18,7 @@
using namespace Gen;
-Jit64AsmRoutineManager::Jit64AsmRoutineManager(Jitx86Base& jit) : m_jit{jit}, CommonAsmRoutines(jit)
+Jit64AsmRoutineManager::Jit64AsmRoutineManager(Jit64& jit) : CommonAsmRoutines(jit), m_jit{jit}
{
}
diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.h b/Source/Core/Core/PowerPC/Jit64/JitAsm.h
index c15b02b5aa..b678f8ed1d 100644
--- a/Source/Core/Core/PowerPC/Jit64/JitAsm.h
+++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.h
@@ -35,7 +35,7 @@ public:
// want to ensure this number is big enough.
static constexpr size_t CODE_SIZE = 16384;
- explicit Jit64AsmRoutineManager(Jitx86Base& jit);
+ explicit Jit64AsmRoutineManager(Jit64& jit);
void Init(u8* stack_top);
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp
index f75489be86..f2695d22fd 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp
@@ -8,6 +8,7 @@
#include "Common/x64Emitter.h"
#include "Core/PowerPC/Jit64/Jit.h"
#include "Core/PowerPC/Jit64/RegCache/JitRegCache.h"
+#include "Core/PowerPC/Jit64Common/Jit64Constants.h"
using namespace Gen;
diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.cpp b/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.cpp
index f671afb74c..899eb5cb0a 100644
--- a/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.cpp
@@ -4,8 +4,8 @@
#include "Core/PowerPC/Jit64/RegCache/FPURegCache.h"
+#include "Common/x64Reg.h"
#include "Core/PowerPC/Jit64/Jit.h"
-#include "Core/PowerPC/Jit64Common/Jit64Base.h"
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
using namespace Gen;
diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.cpp b/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.cpp
index 1671d37a51..1ee5a7f47e 100644
--- a/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.cpp
@@ -4,8 +4,8 @@
#include "Core/PowerPC/Jit64/RegCache/GPRRegCache.h"
+#include "Common/x64Reg.h"
#include "Core/PowerPC/Jit64/Jit.h"
-#include "Core/PowerPC/Jit64Common/Jit64Base.h"
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
using namespace Gen;
diff --git a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp
index 839a6937cd..8c7d48b9dd 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp
+++ b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp
@@ -15,7 +15,8 @@
#include "Core/HW/MMIO.h"
#include "Core/HW/Memmap.h"
#include "Core/PowerPC/Gekko.h"
-#include "Core/PowerPC/Jit64Common/Jit64Base.h"
+#include "Core/PowerPC/Jit64/Jit.h"
+#include "Core/PowerPC/Jit64Common/Jit64Constants.h"
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
#include "Core/PowerPC/MMU.h"
#include "Core/PowerPC/PowerPC.h"
@@ -182,7 +183,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 Jit64Base for this implementation).
+ // register (see Jit64 for this implementation).
offsetAddedToAddress = (reg_value == opAddress.GetSimpleReg());
LEA(32, reg_value, MDisp(opAddress.GetSimpleReg(), offset));
diff --git a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.h b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.h
index b929db4b0d..4e6ad4edab 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.h
+++ b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.h
@@ -19,13 +19,13 @@ namespace MMIO
class Mapping;
}
-class Jitx86Base;
+class Jit64;
// Like XCodeBlock but has some utilities for memory access.
class EmuCodeBlock : public Gen::X64CodeBlock
{
public:
- explicit EmuCodeBlock(Jitx86Base& jit) : m_jit{jit} {}
+ explicit EmuCodeBlock(Jit64& jit) : m_jit{jit} {}
void MemoryExceptionCheck();
// Simple functions to switch between near and far code emitting
@@ -128,7 +128,7 @@ public:
void Clear();
protected:
- Jitx86Base& m_jit;
+ Jit64& m_jit;
ConstantPool m_const_pool;
FarCodeCache m_far_code;
u8* m_near_code; // Backed up when we switch to far code.
diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp
index ca9be3141b..ff3a99a797 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp
+++ b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp
@@ -13,7 +13,8 @@
#include "Common/x64ABI.h"
#include "Common/x64Emitter.h"
#include "Core/PowerPC/Gekko.h"
-#include "Core/PowerPC/Jit64Common/Jit64Base.h"
+#include "Core/PowerPC/Jit64/Jit.h"
+#include "Core/PowerPC/Jit64Common/Jit64Constants.h"
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
#include "Core/PowerPC/PowerPC.h"
diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.h b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.h
index 0bfe0cc6cb..306b5e311e 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.h
+++ b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.h
@@ -13,7 +13,7 @@ enum EQuantizeType : u32;
class QuantizedMemoryRoutines : public EmuCodeBlock
{
public:
- explicit QuantizedMemoryRoutines(Jitx86Base& jit) : EmuCodeBlock(jit) {}
+ explicit QuantizedMemoryRoutines(Jit64& jit) : EmuCodeBlock(jit) {}
void GenQuantizedLoad(bool single, EQuantizeType type, int quantize);
void GenQuantizedStore(bool single, EQuantizeType type, int quantize);
@@ -25,7 +25,7 @@ private:
class CommonAsmRoutines : public CommonAsmRoutinesBase, public QuantizedMemoryRoutines
{
public:
- explicit CommonAsmRoutines(Jitx86Base& jit) : QuantizedMemoryRoutines(jit) {}
+ explicit CommonAsmRoutines(Jit64& jit) : QuantizedMemoryRoutines(jit) {}
void GenFrsqrte();
void GenFres();
void GenMfcr();
diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64Base.cpp b/Source/Core/Core/PowerPC/Jit64Common/Jit64Base.cpp
deleted file mode 100644
index 4525d8c23c..0000000000
--- a/Source/Core/Core/PowerPC/Jit64Common/Jit64Base.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2016 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-#include "Core/PowerPC/Jit64Common/Jit64Base.h"
-
-#include <disasm.h>
-#include <sstream>
-#include <string>
-
-#include "Common/Assert.h"
-#include "Common/CommonTypes.h"
-#include "Common/GekkoDisassembler.h"
-#include "Common/Logging/Log.h"
-#include "Common/MsgHandler.h"
-#include "Common/StringUtil.h"
-#include "Common/Swap.h"
-#include "Common/x64Reg.h"
-#include "Core/HW/Memmap.h"
-#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
-// many of them in a typical program/game.
-bool Jitx86Base::HandleFault(uintptr_t access_address, SContext* ctx)
-{
- // TODO: do we properly handle off-the-end?
- 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 = reinterpret_cast<u8*>(ctx->CTX_PC);
-
- if (!IsInSpace(codePtr))
- return false; // this will become a regular crash real soon after this
-
- auto it = m_back_patch_info.find(codePtr);
- if (it == m_back_patch_info.end())
- {
- PanicAlert("BackPatch: no register use entry for address %p", codePtr);
- return false;
- }
-
- TrampolineInfo& info = it->second;
-
- u8* exceptionHandler = nullptr;
- if (jo.memcheck)
- {
- auto it2 = m_exception_handler_at_loc.find(codePtr);
- if (it2 != m_exception_handler_at_loc.end())
- exceptionHandler = it2->second;
- }
-
- // In the trampoline code, we jump back into the block at the beginning
- // of the next instruction. The next instruction comes immediately
- // after the backpatched operation, or BACKPATCH_SIZE bytes after the start
- // of the backpatched operation, whichever comes last. (The JIT inserts NOPs
- // into the original code if necessary to ensure there is enough space
- // to insert the backpatch jump.)
-
- js.generatingTrampoline = true;
- js.trampolineExceptionHandler = exceptionHandler;
- js.compilerPC = info.pc;
-
- // Generate the trampoline.
- const u8* trampoline = trampolines.GenerateTrampoline(info);
- js.generatingTrampoline = false;
- js.trampolineExceptionHandler = nullptr;
-
- u8* start = info.start;
-
- // Patch the original memory operation.
- XEmitter emitter(start);
- emitter.JMP(trampoline, true);
- // NOPs become dead code
- const u8* end = info.start + info.len;
- for (const u8* i = emitter.GetCodePtr(); i < end; ++i)
- emitter.INT3();
-
- // Rewind time to just before the start of the write block. If we swapped memory
- // 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 != Gen::INVALID_REG)
- {
- u64* ptr = ContextRN(ctx, info.nonAtomicSwapStoreSrc);
- switch (info.accessSize << 3)
- {
- case 8:
- // No need to swap a byte
- break;
- case 16:
- *ptr = Common::swap16(static_cast<u16>(*ptr));
- break;
- case 32:
- *ptr = Common::swap32(static_cast<u32>(*ptr));
- break;
- case 64:
- *ptr = Common::swap64(static_cast<u64>(*ptr));
- break;
- default:
- DEBUG_ASSERT(0);
- break;
- }
- }
-
- // This is special code to undo the LEA in SafeLoadToReg if it clobbered the address
- // register in the case where reg_value shared the same location as opAddress.
- if (info.offsetAddedToAddress)
- {
- u64* ptr = ContextRN(ctx, info.op_arg.GetSimpleReg());
- *ptr -= static_cast<u32>(info.offset);
- }
-
- ctx->CTX_PC = reinterpret_cast<u64>(trampoline);
-
- return true;
-}
-
-void LogGeneratedX86(size_t size, const PPCAnalyst::CodeBuffer& code_buffer, const u8* normalEntry,
- const JitBlock* b)
-{
- for (size_t i = 0; i < size; i++)
- {
- const PPCAnalyst::CodeOp& op = code_buffer[i];
- const std::string disasm = Common::GekkoDisassembler::Disassemble(op.inst.hex, op.address);
- DEBUG_LOG(DYNA_REC, "IR_X86 PPC: %08x %s\n", op.address, disasm.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());
- }
-}
diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64Base.h b/Source/Core/Core/PowerPC/Jit64Common/Jit64Base.h
deleted file mode 100644
index 0beacd873d..0000000000
--- a/Source/Core/Core/PowerPC/Jit64Common/Jit64Base.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2016 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <cstddef>
-#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"
-#include "Core/PowerPC/PPCAnalyst.h"
-
-// 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;
-
-constexpr size_t CODE_SIZE = 1024 * 1024 * 32;
-
-class Jitx86Base : public JitBase, public QuantizedMemoryRoutines
-{
-public:
- Jitx86Base() : QuantizedMemoryRoutines(*this) {}
- JitBlockCache* GetBlockCache() override { return &blocks; }
- bool HandleFault(uintptr_t access_address, SContext* ctx) override;
-
-protected:
- bool BackPatch(u32 emAddress, SContext* ctx);
- JitBlockCache blocks{*this};
- TrampolineCache trampolines{*this};
-};
-
-void LogGeneratedX86(size_t size, const PPCAnalyst::CodeBuffer& code_buffer, const u8* normalEntry,
- const JitBlock* b);
diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64Constants.h b/Source/Core/Core/PowerPC/Jit64Common/Jit64Constants.h
new file mode 100644
index 0000000000..6a3d2c780b
--- /dev/null
+++ b/Source/Core/Core/PowerPC/Jit64Common/Jit64Constants.h
@@ -0,0 +1,24 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <cstddef>
+
+#include "Common/x64Reg.h"
+
+// 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;
+
+constexpr size_t CODE_SIZE = 1024 * 1024 * 32;
diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64PowerPCState.h b/Source/Core/Core/PowerPC/Jit64Common/Jit64PowerPCState.h
index 48f2c039f5..fc79096235 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/Jit64PowerPCState.h
+++ b/Source/Core/Core/PowerPC/Jit64Common/Jit64PowerPCState.h
@@ -5,6 +5,7 @@
#pragma once
#include "Common/CommonTypes.h"
+#include "Core/PowerPC/Jit64Common/Jit64Constants.h"
#include "Core/PowerPC/PowerPC.h"
// We offset by 0x80 because the range of one byte memory offsets is
diff --git a/Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.cpp b/Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.cpp
index 06cb42d881..5e75a79d00 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.cpp
+++ b/Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.cpp
@@ -11,7 +11,8 @@
#include "Common/JitRegister.h"
#include "Common/MsgHandler.h"
#include "Common/x64Emitter.h"
-#include "Core/PowerPC/Jit64Common/Jit64Base.h"
+#include "Core/PowerPC/Jit64/Jit.h"
+#include "Core/PowerPC/Jit64Common/Jit64Constants.h"
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
#include "Core/PowerPC/Jit64Common/TrampolineInfo.h"
#include "Core/PowerPC/PowerPC.h"
diff --git a/Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.h b/Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.h
index 83f7baf977..1eecf18b8a 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.h
+++ b/Source/Core/Core/PowerPC/Jit64Common/TrampolineCache.h
@@ -20,11 +20,12 @@ constexpr int BACKPATCH_SIZE = 5;
class TrampolineCache : public EmuCodeBlock
{
- const u8* GenerateReadTrampoline(const TrampolineInfo& info);
- const u8* GenerateWriteTrampoline(const TrampolineInfo& info);
-
public:
- explicit TrampolineCache(Jitx86Base& jit) : EmuCodeBlock(jit) {}
+ explicit TrampolineCache(Jit64& jit) : EmuCodeBlock(jit) {}
const u8* GenerateTrampoline(const TrampolineInfo& info);
void ClearCodeSpace();
+
+private:
+ const u8* GenerateReadTrampoline(const TrampolineInfo& info);
+ const u8* GenerateWriteTrampoline(const TrampolineInfo& info);
};