From a5be0976bd0a8afc44bee2355f80c46df4c5bb92 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 1 May 2016 01:20:21 +0200 Subject: [PATCH 1/5] Remove preprocessor hacks to choose JIT implementation. Opens up for having multiple JIT implementations available at runtime, which could be use for experimenting with new JIT compiler types or for unit testing one JIT on another architecture. Very few of the newly virtual calls are on any sort of critical path so hopefully there will not be a performance loss. --- CMakeLists.txt | 1 + Common/CodeBlock.h | 2 +- Core/Core.vcxproj | 3 +- Core/Core.vcxproj.filters | 3 + Core/Debugger/Breakpoints.cpp | 4 +- Core/HLE/ReplaceTables.cpp | 12 +- Core/MIPS/ARM/ArmJit.h | 158 +++++++++++++------------- Core/MIPS/ARM64/Arm64Jit.h | 145 +++++++++++------------ Core/MIPS/JitCommon/JitBlockCache.cpp | 6 +- Core/MIPS/JitCommon/JitCommon.cpp | 18 +-- Core/MIPS/JitCommon/JitState.h | 4 + Core/MIPS/JitCommon/NativeJit.cpp | 53 +++++++++ Core/MIPS/JitCommon/NativeJit.h | 116 +++++++++++++++---- Core/MIPS/MIPS.cpp | 24 +--- Core/MIPS/MIPS/MipsJit.h | 136 +++++++++++----------- Core/MIPS/MIPSAnalyst.cpp | 1 + Core/MIPS/MIPSTables.cpp | 12 +- Core/MIPS/MIPSTables.h | 2 +- Core/MIPS/fake/FakeJit.h | 3 - Core/MIPS/x86/CompReplace.cpp | 1 + Core/MIPS/x86/Jit.h | 147 ++++++++++++------------ Core/MemMap.cpp | 1 + Core/SaveState.cpp | 1 + UI/DevScreens.cpp | 1 + android/jni/Android.mk | 1 + unittest/JitHarness.cpp | 1 + 26 files changed, 480 insertions(+), 376 deletions(-) create mode 100644 Core/MIPS/JitCommon/NativeJit.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d78af8512..d18eab9c1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1389,6 +1389,7 @@ add_library(${CoreLibName} ${CoreLinkType} Core/FileLoaders/RetryingFileLoader.h Core/MIPS/JitCommon/JitCommon.cpp Core/MIPS/JitCommon/JitCommon.h + Core/MIPS/JitCommon/NativeJit.cpp Core/MIPS/JitCommon/NativeJit.h Core/MIPS/JitCommon/JitBlockCache.cpp Core/MIPS/JitCommon/JitBlockCache.h diff --git a/Common/CodeBlock.h b/Common/CodeBlock.h index ea8937b046..3a96d75177 100644 --- a/Common/CodeBlock.h +++ b/Common/CodeBlock.h @@ -11,7 +11,7 @@ // You get memory management for free, plus, you can use all emitter functions without // having to prefix them with gen-> or something similar. // Example implementation: -// class JIT : public CodeBlock {} +// class JIT : public CodeBlock, public JitInterface {} template class CodeBlock : public T, NonCopyable { private: diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 514cf98e74..7230ef2683 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -426,6 +426,7 @@ + @@ -737,4 +738,4 @@ - + \ No newline at end of file diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 76cce1b921..1f5ca4951c 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -631,6 +631,9 @@ FileLoaders + + MIPS\JitCommon + diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp index dc77e088ab..0d1318d128 100644 --- a/Core/Debugger/Breakpoints.cpp +++ b/Core/Debugger/Breakpoints.cpp @@ -15,6 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include + +#include "Common/Log.h" #include "Core/Core.h" #include "Core/Debugger/Breakpoints.h" #include "Core/Debugger/SymbolMap.h" @@ -22,7 +25,6 @@ #include "Core/MIPS/MIPSAnalyst.h" #include "Core/MIPS/JitCommon/NativeJit.h" #include "Core/CoreTiming.h" -#include std::vector CBreakPoints::breakPoints_; u32 CBreakPoints::breakSkipFirstAt_ = 0; diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 5fc1da5d7d..06b5392d9d 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -1109,17 +1109,7 @@ static int Hook_omertachinmokunookitethelegacy_download_frame() { return 0; } -#ifdef ARM -#define JITFUNC(f) (&MIPSComp::ArmJit::f) -#elif defined(ARM64) -#define JITFUNC(f) (&MIPSComp::Arm64Jit::f) -#elif defined(_M_X64) || defined(_M_IX86) -#define JITFUNC(f) (&MIPSComp::Jit::f) -#elif defined(MIPS) -#define JITFUNC(f) (&MIPSComp::MipsJit::f) -#else -#define JITFUNC(f) (&MIPSComp::FakeJit::f) -#endif +#define JITFUNC(f) (&MIPSComp::JitInterface::f) // Can either replace with C functions or functions emitted in Asm/ArmAsm. static const ReplacementTableEntry entries[] = { diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index 3df0936f69..50a23631d4 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -22,6 +22,7 @@ #include "Common/ArmEmitter.h" #include "Core/MIPS/JitCommon/JitState.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" +#include "Core/MIPS/JitCommon/NativeJit.h" #include "Core/MIPS/ARM/ArmRegCache.h" #include "Core/MIPS/ARM/ArmRegCacheFPU.h" #include "Core/MIPS/MIPSVFPUUtils.h" @@ -32,98 +33,97 @@ namespace MIPSComp { -class ArmJit : public ArmGen::ARMXCodeBlock { +class ArmJit : public ArmGen::ARMXCodeBlock, public JitInterface { public: ArmJit(MIPSState *mips); virtual ~ArmJit(); - void DoState(PointerWrap &p); - static void DoDummyState(PointerWrap &p); + void DoState(PointerWrap &p) override; + void DoDummyState(PointerWrap &p) override; const JitOptions &GetJitOptions() { return jo; } // Compiled ops should ignore delay slots // the compiler will take care of them by itself // OR NOT - void Comp_Generic(MIPSOpcode op); + void Comp_Generic(MIPSOpcode op) override; - void RunLoopUntil(u64 globalticks); + void RunLoopUntil(u64 globalticks) override; - void Compile(u32 em_address); // Compiles a block at current MIPS PC - const u8 *DoJit(u32 em_address, JitBlock *b); + void Compile(u32 em_address) override; // Compiles a block at current MIPS PC - bool DescribeCodePtr(const u8 *ptr, std::string &name); + bool DescribeCodePtr(const u8 *ptr, std::string &name) override; - void Comp_RunBlock(MIPSOpcode op); - void Comp_ReplacementFunc(MIPSOpcode op); + void Comp_RunBlock(MIPSOpcode op) override; + void Comp_ReplacementFunc(MIPSOpcode op) override; // Ops - void Comp_ITypeMem(MIPSOpcode op); - void Comp_Cache(MIPSOpcode op); + void Comp_ITypeMem(MIPSOpcode op) override; + void Comp_Cache(MIPSOpcode op) override; - void Comp_RelBranch(MIPSOpcode op); - void Comp_RelBranchRI(MIPSOpcode op); - void Comp_FPUBranch(MIPSOpcode op); - void Comp_FPULS(MIPSOpcode op); - void Comp_FPUComp(MIPSOpcode op); - void Comp_Jump(MIPSOpcode op); - void Comp_JumpReg(MIPSOpcode op); - void Comp_Syscall(MIPSOpcode op); - void Comp_Break(MIPSOpcode op); + void Comp_RelBranch(MIPSOpcode op) override; + void Comp_RelBranchRI(MIPSOpcode op) override; + void Comp_FPUBranch(MIPSOpcode op) override; + void Comp_FPULS(MIPSOpcode op) override; + void Comp_FPUComp(MIPSOpcode op) override; + void Comp_Jump(MIPSOpcode op) override; + void Comp_JumpReg(MIPSOpcode op) override; + void Comp_Syscall(MIPSOpcode op) override; + void Comp_Break(MIPSOpcode op) override; - void Comp_IType(MIPSOpcode op); - void Comp_RType2(MIPSOpcode op); - void Comp_RType3(MIPSOpcode op); - void Comp_ShiftType(MIPSOpcode op); - void Comp_Allegrex(MIPSOpcode op); - void Comp_Allegrex2(MIPSOpcode op); - void Comp_VBranch(MIPSOpcode op); - void Comp_MulDivType(MIPSOpcode op); - void Comp_Special3(MIPSOpcode op); + void Comp_IType(MIPSOpcode op) override; + void Comp_RType2(MIPSOpcode op) override; + void Comp_RType3(MIPSOpcode op) override; + void Comp_ShiftType(MIPSOpcode op) override; + void Comp_Allegrex(MIPSOpcode op) override; + void Comp_Allegrex2(MIPSOpcode op) override; + void Comp_VBranch(MIPSOpcode op) override; + void Comp_MulDivType(MIPSOpcode op) override; + void Comp_Special3(MIPSOpcode op) override; - void Comp_FPU3op(MIPSOpcode op); - void Comp_FPU2op(MIPSOpcode op); - void Comp_mxc1(MIPSOpcode op); + void Comp_FPU3op(MIPSOpcode op) override; + void Comp_FPU2op(MIPSOpcode op) override; + void Comp_mxc1(MIPSOpcode op) override; - void Comp_DoNothing(MIPSOpcode op); + void Comp_DoNothing(MIPSOpcode op) override; - void Comp_SV(MIPSOpcode op); - void Comp_SVQ(MIPSOpcode op); - void Comp_VPFX(MIPSOpcode op); - void Comp_VVectorInit(MIPSOpcode op); - void Comp_VMatrixInit(MIPSOpcode op); - void Comp_VDot(MIPSOpcode op); - void Comp_VecDo3(MIPSOpcode op); - void Comp_VV2Op(MIPSOpcode op); - void Comp_Mftv(MIPSOpcode op); - void Comp_Vmfvc(MIPSOpcode op); - void Comp_Vmtvc(MIPSOpcode op); - void Comp_Vmmov(MIPSOpcode op); - void Comp_VScl(MIPSOpcode op); - void Comp_Vmmul(MIPSOpcode op); - void Comp_Vmscl(MIPSOpcode op); - void Comp_Vtfm(MIPSOpcode op); - void Comp_VHdp(MIPSOpcode op); - void Comp_VCrs(MIPSOpcode op); - void Comp_VDet(MIPSOpcode op); - void Comp_Vi2x(MIPSOpcode op); - void Comp_Vx2i(MIPSOpcode op); - void Comp_Vf2i(MIPSOpcode op); - void Comp_Vi2f(MIPSOpcode op); - void Comp_Vh2f(MIPSOpcode op); - void Comp_Vcst(MIPSOpcode op); - void Comp_Vhoriz(MIPSOpcode op); - void Comp_VRot(MIPSOpcode op); - void Comp_VIdt(MIPSOpcode op); - void Comp_Vcmp(MIPSOpcode op); - void Comp_Vcmov(MIPSOpcode op); - void Comp_Viim(MIPSOpcode op); - void Comp_Vfim(MIPSOpcode op); - void Comp_VCrossQuat(MIPSOpcode op); - void Comp_Vsgn(MIPSOpcode op); - void Comp_Vocp(MIPSOpcode op); - void Comp_ColorConv(MIPSOpcode op); - void Comp_Vbfy(MIPSOpcode op); + void Comp_SV(MIPSOpcode op) override; + void Comp_SVQ(MIPSOpcode op) override; + void Comp_VPFX(MIPSOpcode op) override; + void Comp_VVectorInit(MIPSOpcode op) override; + void Comp_VMatrixInit(MIPSOpcode op) override; + void Comp_VDot(MIPSOpcode op) override; + void Comp_VecDo3(MIPSOpcode op) override; + void Comp_VV2Op(MIPSOpcode op) override; + void Comp_Mftv(MIPSOpcode op) override; + void Comp_Vmfvc(MIPSOpcode op) override; + void Comp_Vmtvc(MIPSOpcode op) override; + void Comp_Vmmov(MIPSOpcode op) override; + void Comp_VScl(MIPSOpcode op) override; + void Comp_Vmmul(MIPSOpcode op) override; + void Comp_Vmscl(MIPSOpcode op) override; + void Comp_Vtfm(MIPSOpcode op) override; + void Comp_VHdp(MIPSOpcode op) override; + void Comp_VCrs(MIPSOpcode op) override; + void Comp_VDet(MIPSOpcode op) override; + void Comp_Vi2x(MIPSOpcode op) override; + void Comp_Vx2i(MIPSOpcode op) override; + void Comp_Vf2i(MIPSOpcode op) override; + void Comp_Vi2f(MIPSOpcode op) override; + void Comp_Vh2f(MIPSOpcode op) override; + void Comp_Vcst(MIPSOpcode op) override; + void Comp_Vhoriz(MIPSOpcode op) override; + void Comp_VRot(MIPSOpcode op) override; + void Comp_VIdt(MIPSOpcode op) override; + void Comp_Vcmp(MIPSOpcode op) override; + void Comp_Vcmov(MIPSOpcode op) override; + void Comp_Viim(MIPSOpcode op) override; + void Comp_Vfim(MIPSOpcode op) override; + void Comp_VCrossQuat(MIPSOpcode op) override; + void Comp_Vsgn(MIPSOpcode op) override; + void Comp_Vocp(MIPSOpcode op) override; + void Comp_ColorConv(MIPSOpcode op) override; + void Comp_Vbfy(MIPSOpcode op) override; // Non-NEON: VPFX @@ -167,15 +167,21 @@ public: int Replace_fabsf(); - JitBlockCache *GetBlockCache() { return &blocks; } + JitBlockCache *GetBlockCache() override { return &blocks; } - void ClearCache(); - void InvalidateCache(); - void InvalidateCacheAt(u32 em_address, int length = 4); + void ClearCache() override; + void InvalidateCache() override; + void InvalidateCacheAt(u32 em_address, int length = 4) override; - void EatPrefix() { js.EatPrefix(); } + void EatPrefix() override { js.EatPrefix(); } + + const u8 *GetDispatcher() const override { + return dispatcher; + } private: + const u8 *DoJit(u32 em_address, JitBlock *b); + void GenerateFixedCode(); void FlushAll(); void FlushPrefixV(); diff --git a/Core/MIPS/ARM64/Arm64Jit.h b/Core/MIPS/ARM64/Arm64Jit.h index 36caaabe25..f8f4d7461d 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -22,6 +22,7 @@ #include "Common/Arm64Emitter.h" #include "Core/MIPS/JitCommon/JitState.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" +#include "Core/MIPS/JitCommon/NativeJit.h" #include "Core/MIPS/ARM64/Arm64RegCache.h" #include "Core/MIPS/ARM64/Arm64RegCacheFPU.h" #include "Core/MIPS/MIPSVFPUUtils.h" @@ -32,98 +33,98 @@ namespace MIPSComp { -class Arm64Jit : public Arm64Gen::ARM64CodeBlock { +class Arm64Jit : public Arm64Gen::ARM64CodeBlock, public JitInterface { public: Arm64Jit(MIPSState *mips); virtual ~Arm64Jit(); - void DoState(PointerWrap &p); - static void DoDummyState(PointerWrap &p); + void DoState(PointerWrap &p) override; + void DoDummyState(PointerWrap &p) override; const JitOptions &GetJitOptions() { return jo; } // Compiled ops should ignore delay slots // the compiler will take care of them by itself // OR NOT - void Comp_Generic(MIPSOpcode op); + void Comp_Generic(MIPSOpcode op) override; - void RunLoopUntil(u64 globalticks); + void RunLoopUntil(u64 globalticks) override; - void Compile(u32 em_address); // Compiles a block at current MIPS PC + void Compile(u32 em_address) override; // Compiles a block at current MIPS PC const u8 *DoJit(u32 em_address, JitBlock *b); - bool DescribeCodePtr(const u8 *ptr, std::string &name); + bool DescribeCodePtr(const u8 *ptr, std::string &name) override; - void Comp_RunBlock(MIPSOpcode op); - void Comp_ReplacementFunc(MIPSOpcode op); + void Comp_RunBlock(MIPSOpcode op) override; + void Comp_ReplacementFunc(MIPSOpcode op) override; // Ops - void Comp_ITypeMem(MIPSOpcode op); - void Comp_Cache(MIPSOpcode op); + void Comp_ITypeMem(MIPSOpcode op) override; + void Comp_Cache(MIPSOpcode op) override; - void Comp_RelBranch(MIPSOpcode op); - void Comp_RelBranchRI(MIPSOpcode op); - void Comp_FPUBranch(MIPSOpcode op); - void Comp_FPULS(MIPSOpcode op); - void Comp_FPUComp(MIPSOpcode op); - void Comp_Jump(MIPSOpcode op); - void Comp_JumpReg(MIPSOpcode op); - void Comp_Syscall(MIPSOpcode op); - void Comp_Break(MIPSOpcode op); + void Comp_RelBranch(MIPSOpcode op) override; + void Comp_RelBranchRI(MIPSOpcode op) override; + void Comp_FPUBranch(MIPSOpcode op) override; + void Comp_FPULS(MIPSOpcode op) override; + void Comp_FPUComp(MIPSOpcode op) override; + void Comp_Jump(MIPSOpcode op) override; + void Comp_JumpReg(MIPSOpcode op) override; + void Comp_Syscall(MIPSOpcode op) override; + void Comp_Break(MIPSOpcode op) override; - void Comp_IType(MIPSOpcode op); - void Comp_RType2(MIPSOpcode op); - void Comp_RType3(MIPSOpcode op); - void Comp_ShiftType(MIPSOpcode op); - void Comp_Allegrex(MIPSOpcode op); - void Comp_Allegrex2(MIPSOpcode op); - void Comp_VBranch(MIPSOpcode op); - void Comp_MulDivType(MIPSOpcode op); - void Comp_Special3(MIPSOpcode op); + void Comp_IType(MIPSOpcode op) override; + void Comp_RType2(MIPSOpcode op) override; + void Comp_RType3(MIPSOpcode op) override; + void Comp_ShiftType(MIPSOpcode op) override; + void Comp_Allegrex(MIPSOpcode op) override; + void Comp_Allegrex2(MIPSOpcode op) override; + void Comp_VBranch(MIPSOpcode op) override; + void Comp_MulDivType(MIPSOpcode op) override; + void Comp_Special3(MIPSOpcode op) override; - void Comp_FPU3op(MIPSOpcode op); - void Comp_FPU2op(MIPSOpcode op); - void Comp_mxc1(MIPSOpcode op); + void Comp_FPU3op(MIPSOpcode op) override; + void Comp_FPU2op(MIPSOpcode op) override; + void Comp_mxc1(MIPSOpcode op) override; - void Comp_DoNothing(MIPSOpcode op); + void Comp_DoNothing(MIPSOpcode op) override; - void Comp_SV(MIPSOpcode op); - void Comp_SVQ(MIPSOpcode op); - void Comp_VPFX(MIPSOpcode op); - void Comp_VVectorInit(MIPSOpcode op); - void Comp_VMatrixInit(MIPSOpcode op); - void Comp_VDot(MIPSOpcode op); - void Comp_VecDo3(MIPSOpcode op); - void Comp_VV2Op(MIPSOpcode op); - void Comp_Mftv(MIPSOpcode op); - void Comp_Vmfvc(MIPSOpcode op); - void Comp_Vmtvc(MIPSOpcode op); - void Comp_Vmmov(MIPSOpcode op); - void Comp_VScl(MIPSOpcode op); - void Comp_Vmmul(MIPSOpcode op); - void Comp_Vmscl(MIPSOpcode op); - void Comp_Vtfm(MIPSOpcode op); - void Comp_VHdp(MIPSOpcode op); - void Comp_VCrs(MIPSOpcode op); - void Comp_VDet(MIPSOpcode op); - void Comp_Vi2x(MIPSOpcode op); - void Comp_Vx2i(MIPSOpcode op); - void Comp_Vf2i(MIPSOpcode op); - void Comp_Vi2f(MIPSOpcode op); - void Comp_Vh2f(MIPSOpcode op); - void Comp_Vcst(MIPSOpcode op); - void Comp_Vhoriz(MIPSOpcode op); - void Comp_VRot(MIPSOpcode op); - void Comp_VIdt(MIPSOpcode op); - void Comp_Vcmp(MIPSOpcode op); - void Comp_Vcmov(MIPSOpcode op); - void Comp_Viim(MIPSOpcode op); - void Comp_Vfim(MIPSOpcode op); - void Comp_VCrossQuat(MIPSOpcode op); - void Comp_Vsgn(MIPSOpcode op); - void Comp_Vocp(MIPSOpcode op); - void Comp_ColorConv(MIPSOpcode op); - void Comp_Vbfy(MIPSOpcode op); + void Comp_SV(MIPSOpcode op) override; + void Comp_SVQ(MIPSOpcode op) override; + void Comp_VPFX(MIPSOpcode op) override; + void Comp_VVectorInit(MIPSOpcode op) override; + void Comp_VMatrixInit(MIPSOpcode op) override; + void Comp_VDot(MIPSOpcode op) override; + void Comp_VecDo3(MIPSOpcode op) override; + void Comp_VV2Op(MIPSOpcode op) override; + void Comp_Mftv(MIPSOpcode op) override; + void Comp_Vmfvc(MIPSOpcode op) override; + void Comp_Vmtvc(MIPSOpcode op) override; + void Comp_Vmmov(MIPSOpcode op) override; + void Comp_VScl(MIPSOpcode op) override; + void Comp_Vmmul(MIPSOpcode op) override; + void Comp_Vmscl(MIPSOpcode op) override; + void Comp_Vtfm(MIPSOpcode op) override; + void Comp_VHdp(MIPSOpcode op) override; + void Comp_VCrs(MIPSOpcode op) override; + void Comp_VDet(MIPSOpcode op) override; + void Comp_Vi2x(MIPSOpcode op) override; + void Comp_Vx2i(MIPSOpcode op) override; + void Comp_Vf2i(MIPSOpcode op) override; + void Comp_Vi2f(MIPSOpcode op) override; + void Comp_Vh2f(MIPSOpcode op) override; + void Comp_Vcst(MIPSOpcode op) override; + void Comp_Vhoriz(MIPSOpcode op) override; + void Comp_VRot(MIPSOpcode op) override; + void Comp_VIdt(MIPSOpcode op) override; + void Comp_Vcmp(MIPSOpcode op) override; + void Comp_Vcmov(MIPSOpcode op) override; + void Comp_Viim(MIPSOpcode op) override; + void Comp_Vfim(MIPSOpcode op) override; + void Comp_VCrossQuat(MIPSOpcode op) override; + void Comp_Vsgn(MIPSOpcode op) override; + void Comp_Vocp(MIPSOpcode op) override; + void Comp_ColorConv(MIPSOpcode op) override; + void Comp_Vbfy(MIPSOpcode op) override; // Non-NEON: VPFX @@ -175,6 +176,10 @@ public: void EatPrefix() { js.EatPrefix(); } + const u8 *GetDispatcher() const override { + return dispatcher; + } + private: void GenerateFixedCode(const JitOptions &jo); void FlushAll(); diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index af49b8ccb4..0eeed6b6a1 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -62,11 +62,13 @@ op_agent_t agent; #endif #ifdef ARM +#include "Core/MIPS/ARM/ArmRegCache.h" using namespace ArmGen; using namespace ArmJitConstants; #elif defined(_M_X64) || defined(_M_IX86) using namespace Gen; #elif defined(ARM64) +#include "Core/MIPS/ARM64/Arm64RegCache.h" using namespace Arm64Gen; using namespace Arm64JitConstants; #endif @@ -595,7 +597,7 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate) { ARMXEmitter emit((u8 *)b->checkedEntry); emit.MOVI2R(R0, b->originalAddress); emit.STR(R0, CTXREG, offsetof(MIPSState, pc)); - emit.B(MIPSComp::jit->dispatcher); + emit.B(MIPSComp::jit->GetDispatcher()); emit.FlushIcache(); #elif defined(_M_IX86) || defined(_M_X64) @@ -615,7 +617,7 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate) { ARM64XEmitter emit((u8 *)b->checkedEntry); emit.MOVI2R(SCRATCH1, b->originalAddress); emit.STR(INDEX_UNSIGNED, SCRATCH1, CTXREG, offsetof(MIPSState, pc)); - emit.B(MIPSComp::jit->dispatcher); + emit.B(MIPSComp::jit->GetDispatcher()); emit.FlushIcache(); #endif diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp index 83903e9ab3..5c356354e7 100644 --- a/Core/MIPS/JitCommon/JitCommon.cpp +++ b/Core/MIPS/JitCommon/JitCommon.cpp @@ -18,6 +18,7 @@ #include #include "Core/MIPS/JitCommon/JitCommon.h" +#include "Core/MIPS/JitCommon/JitState.h" #include "Core/MIPS/JitCommon/NativeJit.h" #include "Common/StringUtils.h" @@ -29,23 +30,6 @@ #define DISASM_ALL 1 #endif -namespace MIPSComp { -#if defined(ARM) - ArmJit *jit; -#elif defined(ARM64) - Arm64Jit *jit; -#elif defined(_M_IX86) || defined(_M_X64) - Jit *jit; -#elif defined(MIPS) - MipsJit *jit; -#else - FakeJit *jit; -#endif - void JitAt() { - jit->Compile(currentMIPS->pc); - } -} - #if defined(ARM) || defined(DISASM_ALL) // We compile this for x86 as well because it may be useful when developing the ARM JIT on a PC. std::vector DisassembleArm2(const u8 *data, int size) { diff --git a/Core/MIPS/JitCommon/JitState.h b/Core/MIPS/JitCommon/JitState.h index b4e81b18fe..1bc75b083c 100644 --- a/Core/MIPS/JitCommon/JitState.h +++ b/Core/MIPS/JitCommon/JitState.h @@ -19,8 +19,10 @@ #pragma once #include "Common/Common.h" +#include "Core/MIPS/MIPS.h" struct JitBlock; +class JitBlockCache; namespace MIPSComp { @@ -203,4 +205,6 @@ namespace MIPSComp { bool continueJumps; int continueMaxInstructions; }; + } + diff --git a/Core/MIPS/JitCommon/NativeJit.cpp b/Core/MIPS/JitCommon/NativeJit.cpp new file mode 100644 index 0000000000..7c6b81295e --- /dev/null +++ b/Core/MIPS/JitCommon/NativeJit.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2012- PPSSPP 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 or later versions. + +// 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 git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitState.h" + +#if defined(ARM) +#include "../ARM/ArmJit.h" +#elif defined(ARM64) +#include "../ARM64/Arm64Jit.h" +#elif defined(_M_IX86) || defined(_M_X64) +#include "../x86/Jit.h" +#elif defined(MIPS) +#include "../MIPS/MipsJit.h" +#else +#include "../fake/FakeJit.h" +#endif + +namespace MIPSComp { + JitInterface *jit; + void JitAt() { + jit->Compile(currentMIPS->pc); + } + +JitInterface *CreateNativeJit(MIPSState *mips) { +#if defined(ARM) + return new MIPSComp::ArmJit(mips); +#elif defined(ARM64) + return new MIPSComp::Arm64Jit(mips); +#elif defined(_M_IX86) || defined(_M_X64) + return new MIPSComp::Jit(mips); +#elif defined(MIPS) + return new MIPSComp::MipsJit(mips); +#else + return new MIPSComp::FakeJit(mips); +#endif +} + +} \ No newline at end of file diff --git a/Core/MIPS/JitCommon/NativeJit.h b/Core/MIPS/JitCommon/NativeJit.h index 96be0d0bfb..c17c2902ce 100644 --- a/Core/MIPS/JitCommon/NativeJit.h +++ b/Core/MIPS/JitCommon/NativeJit.h @@ -17,32 +17,110 @@ #pragma once +#include +#include "Common/CommonTypes.h" +#include "Core/MIPS/MIPS.h" + struct JitBlock; +class JitBlockCache; +class PointerWrap; #ifdef USING_QT_UI #undef emit #endif -#if defined(ARM) -#include "../ARM/ArmJit.h" -typedef MIPSComp::ArmJit NativeJit; -#elif defined(ARM64) -#include "../ARM64/Arm64Jit.h" -typedef MIPSComp::Arm64Jit NativeJit; -#elif defined(_M_IX86) || defined(_M_X64) -#include "../x86/Jit.h" -typedef MIPSComp::Jit NativeJit; -#elif defined(MIPS) -#include "../MIPS/MipsJit.h" -typedef MIPSComp::MipsJit NativeJit; -#else -#include "../fake/FakeJit.h" -typedef MIPSComp::FakeJit NativeJit; -#endif +class MIPSState; namespace MIPSComp { - extern NativeJit *jit; - typedef void (NativeJit::*MIPSCompileFunc)(MIPSOpcode opcode); - typedef int (NativeJit::*MIPSReplaceFunc)(); + class JitInterface { + public: + virtual ~JitInterface() {} + + virtual bool DescribeCodePtr(const u8 *ptr, std::string &name) = 0; + virtual const u8 *GetDispatcher() const = 0; + virtual JitBlockCache *GetBlockCache() = 0; + virtual void InvalidateCache() = 0; + virtual void InvalidateCacheAt(u32 em_address, int length = 4) = 0; + virtual void DoState(PointerWrap &p) = 0; + virtual void DoDummyState(PointerWrap &p) = 0; + virtual void RunLoopUntil(u64 globalticks) = 0; + virtual void Compile(u32 em_address) = 0; + virtual void ClearCache() = 0; + virtual void EatPrefix() = 0; + + virtual void Comp_Generic(MIPSOpcode op) = 0; + virtual void Comp_RunBlock(MIPSOpcode op) = 0; + virtual void Comp_ReplacementFunc(MIPSOpcode op) = 0; + virtual void Comp_ITypeMem(MIPSOpcode op) = 0; + virtual void Comp_Cache(MIPSOpcode op) = 0; + virtual void Comp_RelBranch(MIPSOpcode op) = 0; + virtual void Comp_RelBranchRI(MIPSOpcode op) = 0; + virtual void Comp_FPUBranch(MIPSOpcode op) = 0; + virtual void Comp_FPULS(MIPSOpcode op) = 0; + virtual void Comp_FPUComp(MIPSOpcode op) = 0; + virtual void Comp_Jump(MIPSOpcode op) = 0; + virtual void Comp_JumpReg(MIPSOpcode op) = 0; + virtual void Comp_Syscall(MIPSOpcode op) = 0; + virtual void Comp_Break(MIPSOpcode op) = 0; + virtual void Comp_IType(MIPSOpcode op) = 0; + virtual void Comp_RType2(MIPSOpcode op) = 0; + virtual void Comp_RType3(MIPSOpcode op) = 0; + virtual void Comp_ShiftType(MIPSOpcode op) = 0; + virtual void Comp_Allegrex(MIPSOpcode op) = 0; + virtual void Comp_Allegrex2(MIPSOpcode op) = 0; + virtual void Comp_VBranch(MIPSOpcode op) = 0; + virtual void Comp_MulDivType(MIPSOpcode op) = 0; + virtual void Comp_Special3(MIPSOpcode op) = 0; + virtual void Comp_FPU3op(MIPSOpcode op) = 0; + virtual void Comp_FPU2op(MIPSOpcode op) = 0; + virtual void Comp_mxc1(MIPSOpcode op) = 0; + virtual void Comp_SV(MIPSOpcode op) = 0; + virtual void Comp_SVQ(MIPSOpcode op) = 0; + virtual void Comp_VPFX(MIPSOpcode op) = 0; + virtual void Comp_VVectorInit(MIPSOpcode op) = 0; + virtual void Comp_VMatrixInit(MIPSOpcode op) = 0; + virtual void Comp_VDot(MIPSOpcode op) = 0; + virtual void Comp_VecDo3(MIPSOpcode op) = 0; + virtual void Comp_VV2Op(MIPSOpcode op) = 0; + virtual void Comp_Mftv(MIPSOpcode op) = 0; + virtual void Comp_Vmfvc(MIPSOpcode op) = 0; + virtual void Comp_Vmtvc(MIPSOpcode op) = 0; + virtual void Comp_Vmmov(MIPSOpcode op) = 0; + virtual void Comp_VScl(MIPSOpcode op) = 0; + virtual void Comp_Vmmul(MIPSOpcode op) = 0; + virtual void Comp_Vmscl(MIPSOpcode op) = 0; + virtual void Comp_Vtfm(MIPSOpcode op) = 0; + virtual void Comp_VHdp(MIPSOpcode op) = 0; + virtual void Comp_VCrs(MIPSOpcode op) = 0; + virtual void Comp_VDet(MIPSOpcode op) = 0; + virtual void Comp_Vi2x(MIPSOpcode op) = 0; + virtual void Comp_Vx2i(MIPSOpcode op) = 0; + virtual void Comp_Vf2i(MIPSOpcode op) = 0; + virtual void Comp_Vi2f(MIPSOpcode op) = 0; + virtual void Comp_Vh2f(MIPSOpcode op) = 0; + virtual void Comp_Vcst(MIPSOpcode op) = 0; + virtual void Comp_Vhoriz(MIPSOpcode op) = 0; + virtual void Comp_VRot(MIPSOpcode op) = 0; + virtual void Comp_VIdt(MIPSOpcode op) = 0; + virtual void Comp_Vcmp(MIPSOpcode op) = 0; + virtual void Comp_Vcmov(MIPSOpcode op) = 0; + virtual void Comp_Viim(MIPSOpcode op) = 0; + virtual void Comp_Vfim(MIPSOpcode op) = 0; + virtual void Comp_VCrossQuat(MIPSOpcode op) = 0; + virtual void Comp_Vsgn(MIPSOpcode op) = 0; + virtual void Comp_Vocp(MIPSOpcode op) = 0; + virtual void Comp_ColorConv(MIPSOpcode op) = 0; + virtual void Comp_Vbfy(MIPSOpcode op) = 0; + virtual void Comp_DoNothing(MIPSOpcode op) = 0; + + virtual int Replace_fabsf() = 0; + }; + + typedef void (JitInterface::*MIPSCompileFunc)(MIPSOpcode opcode); + typedef int (JitInterface::*MIPSReplaceFunc)(); + + extern JitInterface *jit; + + JitInterface *CreateNativeJit(MIPSState *mips); } diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index e69ec9cbbf..6cb88b8594 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -209,17 +209,7 @@ void MIPSState::Init() { rng.Init(0x1337); if (PSP_CoreParameter().cpuCore == CPU_JIT) { -#ifdef ARM - MIPSComp::jit = new MIPSComp::ArmJit(this); -#elif defined(ARM64) - MIPSComp::jit = new MIPSComp::Arm64Jit(this); -#elif defined(_M_IX86) || defined(_M_X64) - MIPSComp::jit = new MIPSComp::Jit(this); -#elif defined(MIPS) - MIPSComp::jit = new MIPSComp::MipsJit(this); -#else - MIPSComp::jit = new MIPSComp::FakeJit(this); -#endif + MIPSComp::jit = MIPSComp::CreateNativeJit(this); } else { MIPSComp::jit = nullptr; } @@ -239,17 +229,7 @@ void MIPSState::UpdateCore(CPUCore desired) { case CPU_JIT: INFO_LOG(CPU, "Switching to JIT"); if (!MIPSComp::jit) { -#ifdef ARM - MIPSComp::jit = new MIPSComp::ArmJit(this); -#elif defined(ARM64) - MIPSComp::jit = new MIPSComp::Arm64Jit(this); -#elif defined(_M_IX86) || defined(_M_X64) - MIPSComp::jit = new MIPSComp::Jit(this); -#elif defined(MIPS) - MIPSComp::jit = new MIPSComp::MipsJit(this); -#else - MIPSComp::jit = new MIPSComp::FakeJit(this); -#endif + MIPSComp::jit = MIPSComp::CreateNativeJit(this); } break; diff --git a/Core/MIPS/MIPS/MipsJit.h b/Core/MIPS/MIPS/MipsJit.h index dfbaa89e5c..1fcb6faea6 100644 --- a/Core/MIPS/MIPS/MipsJit.h +++ b/Core/MIPS/MIPS/MipsJit.h @@ -31,22 +31,22 @@ using namespace MIPSGen; namespace MIPSComp { -class MipsJit : public MIPSGen::MIPSCodeBlock +class MipsJit : public MIPSGen::MIPSCodeBlock, public JitInterface { public: MipsJit(MIPSState *mips); - void DoState(PointerWrap &p); - static void DoDummyState(PointerWrap &p); + void DoState(PointerWrap &p) override; + void DoDummyState(PointerWrap &p) override; // Compiled ops should ignore delay slots // the compiler will take care of them by itself // OR NOT - void Comp_Generic(MIPSOpcode op); + void Comp_Generic(MIPSOpcode op) override; - void RunLoopUntil(u64 globalticks); + void RunLoopUntil(u64 globalticks) override; - void Compile(u32 em_address); // Compiles a block at current MIPS PC + void Compile(u32 em_address) override; // Compiles a block at current MIPS PC const u8 *DoJit(u32 em_address, JitBlock *b); bool DescribeCodePtr(const u8 *ptr, std::string &name); @@ -55,75 +55,75 @@ public: void EatInstruction(MIPSOpcode op); void AddContinuedBlock(u32 dest); - void Comp_RunBlock(MIPSOpcode op); - void Comp_ReplacementFunc(MIPSOpcode op); + void Comp_RunBlock(MIPSOpcode op) override; + void Comp_ReplacementFunc(MIPSOpcode op) override; // Ops - void Comp_ITypeMem(MIPSOpcode op) {} - void Comp_Cache(MIPSOpcode op) {} + void Comp_ITypeMem(MIPSOpcode op) override {} + void Comp_Cache(MIPSOpcode op) override {} - void Comp_RelBranch(MIPSOpcode op) {} - void Comp_RelBranchRI(MIPSOpcode op) {} - void Comp_FPUBranch(MIPSOpcode op) {} - void Comp_FPULS(MIPSOpcode op) {} - void Comp_FPUComp(MIPSOpcode op) {} - void Comp_Jump(MIPSOpcode op) {} - void Comp_JumpReg(MIPSOpcode op) {} - void Comp_Syscall(MIPSOpcode op) {} - void Comp_Break(MIPSOpcode op) {} + void Comp_RelBranch(MIPSOpcode op) override {} + void Comp_RelBranchRI(MIPSOpcode op) override {} + void Comp_FPUBranch(MIPSOpcode op) override {} + void Comp_FPULS(MIPSOpcode op) override {} + void Comp_FPUComp(MIPSOpcode op) override {} + void Comp_Jump(MIPSOpcode op) override {} + void Comp_JumpReg(MIPSOpcode op) override {} + void Comp_Syscall(MIPSOpcode op) override {} + void Comp_Break(MIPSOpcode op) override {} - void Comp_IType(MIPSOpcode op) {} - void Comp_RType2(MIPSOpcode op) {} - void Comp_RType3(MIPSOpcode op) {} - void Comp_ShiftType(MIPSOpcode op) {} - void Comp_Allegrex(MIPSOpcode op) {} - void Comp_Allegrex2(MIPSOpcode op) {} - void Comp_VBranch(MIPSOpcode op) {} - void Comp_MulDivType(MIPSOpcode op) {} - void Comp_Special3(MIPSOpcode op) {} + void Comp_IType(MIPSOpcode op) override {} + void Comp_RType2(MIPSOpcode op) override {} + void Comp_RType3(MIPSOpcode op) override {} + void Comp_ShiftType(MIPSOpcode op) override {} + void Comp_Allegrex(MIPSOpcode op) override {} + void Comp_Allegrex2(MIPSOpcode op) override {} + void Comp_VBranch(MIPSOpcode op) override {} + void Comp_MulDivType(MIPSOpcode op) override {} + void Comp_Special3(MIPSOpcode op) override {} - void Comp_FPU3op(MIPSOpcode op) {} - void Comp_FPU2op(MIPSOpcode op) {} - void Comp_mxc1(MIPSOpcode op) {} + void Comp_FPU3op(MIPSOpcode op) override {} + void Comp_FPU2op(MIPSOpcode op) override {} + void Comp_mxc1(MIPSOpcode op) override {} - void Comp_DoNothing(MIPSOpcode op) {} + void Comp_DoNothing(MIPSOpcode op) override {} - void Comp_SV(MIPSOpcode op) {} - void Comp_SVQ(MIPSOpcode op) {} - void Comp_VPFX(MIPSOpcode op) {} - void Comp_VVectorInit(MIPSOpcode op) {} - void Comp_VMatrixInit(MIPSOpcode op) {} - void Comp_VDot(MIPSOpcode op) {} - void Comp_VecDo3(MIPSOpcode op) {} - void Comp_VV2Op(MIPSOpcode op) {} - void Comp_Mftv(MIPSOpcode op) {} - void Comp_Vmfvc(MIPSOpcode op) {} - void Comp_Vmtvc(MIPSOpcode op) {} - void Comp_Vmmov(MIPSOpcode op) {} - void Comp_VScl(MIPSOpcode op) {} - void Comp_Vmmul(MIPSOpcode op) {} - void Comp_Vmscl(MIPSOpcode op) {} - void Comp_Vtfm(MIPSOpcode op) {} - void Comp_VHdp(MIPSOpcode op) {} - void Comp_VCrs(MIPSOpcode op) {} - void Comp_VDet(MIPSOpcode op) {} - void Comp_Vi2x(MIPSOpcode op) {} - void Comp_Vx2i(MIPSOpcode op) {} - void Comp_Vf2i(MIPSOpcode op) {} - void Comp_Vi2f(MIPSOpcode op) {} - void Comp_Vh2f(MIPSOpcode op) {} - void Comp_Vcst(MIPSOpcode op) {} - void Comp_Vhoriz(MIPSOpcode op) {} - void Comp_VRot(MIPSOpcode op) {} - void Comp_VIdt(MIPSOpcode op) {} - void Comp_Vcmp(MIPSOpcode op) {} - void Comp_Vcmov(MIPSOpcode op) {} - void Comp_Viim(MIPSOpcode op) {} - void Comp_Vfim(MIPSOpcode op) {} - void Comp_VCrossQuat(MIPSOpcode op) {} - void Comp_Vsgn(MIPSOpcode op) {} - void Comp_Vocp(MIPSOpcode op) {} - void Comp_ColorConv(MIPSOpcode op) {} + void Comp_SV(MIPSOpcode op) override {} + void Comp_SVQ(MIPSOpcode op) override {} + void Comp_VPFX(MIPSOpcode op) override {} + void Comp_VVectorInit(MIPSOpcode op) override {} + void Comp_VMatrixInit(MIPSOpcode op) override {} + void Comp_VDot(MIPSOpcode op) override {} + void Comp_VecDo3(MIPSOpcode op) override {} + void Comp_VV2Op(MIPSOpcode op) override {} + void Comp_Mftv(MIPSOpcode op) override {} + void Comp_Vmfvc(MIPSOpcode op) override {} + void Comp_Vmtvc(MIPSOpcode op) override {} + void Comp_Vmmov(MIPSOpcode op) override {} + void Comp_VScl(MIPSOpcode op) override {} + void Comp_Vmmul(MIPSOpcode op) override {} + void Comp_Vmscl(MIPSOpcode op) override {} + void Comp_Vtfm(MIPSOpcode op) override {} + void Comp_VHdp(MIPSOpcode op) override {} + void Comp_VCrs(MIPSOpcode op) override {} + void Comp_VDet(MIPSOpcode op) override {} + void Comp_Vi2x(MIPSOpcode op) override {} + void Comp_Vx2i(MIPSOpcode op) override {} + void Comp_Vf2i(MIPSOpcode op) override {} + void Comp_Vi2f(MIPSOpcode op) override {} + void Comp_Vh2f(MIPSOpcode op) override {} + void Comp_Vcst(MIPSOpcode op) override {} + void Comp_Vhoriz(MIPSOpcode op) override {} + void Comp_VRot(MIPSOpcode op) override {} + void Comp_VIdt(MIPSOpcode op) override {} + void Comp_Vcmp(MIPSOpcode op) override {} + void Comp_Vcmov(MIPSOpcode op) override {} + void Comp_Viim(MIPSOpcode op) override {} + void Comp_Vfim(MIPSOpcode op) override {} + void Comp_VCrossQuat(MIPSOpcode op) override {} + void Comp_Vsgn(MIPSOpcode op) override {} + void Comp_Vocp(MIPSOpcode op) override {} + void Comp_ColorConv(MIPSOpcode op) override {} int Replace_fabsf() { return 0; } void Comp_Vbfy(MIPSOpcode op) {} diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index fbe4863962..cf248816f0 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -25,6 +25,7 @@ #include "Core/MemMap.h" #include "Core/System.h" #include "Core/MIPS/MIPS.h" +#include "Core/MIPS/MIPSVFPUUtils.h" #include "Core/MIPS/MIPSTables.h" #include "Core/MIPS/MIPSAnalyst.h" #include "Core/MIPS/MIPSCodeUtils.h" diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 2b7169a00e..4112123779 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -81,17 +81,7 @@ struct MIPSInstruction { #define ENCODING(a) {a} #define INSTR(name, comp, dis, inter, flags) {Instruc, name, comp, dis, inter, MIPSInfo(flags)} -#ifdef ARM -#define JITFUNC(f) (&ArmJit::f) -#elif defined(ARM64) -#define JITFUNC(f) (&Arm64Jit::f) -#elif defined(_M_X64) || defined(_M_IX86) -#define JITFUNC(f) (&Jit::f) -#elif defined(MIPS) -#define JITFUNC(f) (&MipsJit::f) -#else -#define JITFUNC(f) (&FakeJit::f) -#endif +#define JITFUNC(f) (&JitInterface::f) using namespace MIPSDis; using namespace MIPSInt; diff --git a/Core/MIPS/MIPSTables.h b/Core/MIPS/MIPSTables.h index ac77e34f2b..75ac6c5003 100644 --- a/Core/MIPS/MIPSTables.h +++ b/Core/MIPS/MIPSTables.h @@ -111,7 +111,6 @@ struct MIPSInfo { typedef void (CDECL *MIPSDisFunc)(MIPSOpcode opcode, char *out); typedef void (CDECL *MIPSInterpretFunc)(MIPSOpcode opcode); - void MIPSCompileOp(MIPSOpcode op); void MIPSDisAsm(MIPSOpcode op, u32 pc, char *out, bool tabsToSpaces = false); MIPSInfo MIPSGetInfo(MIPSOpcode op); @@ -124,3 +123,4 @@ const char *MIPSGetName(MIPSOpcode op); const char *MIPSDisasmAt(u32 compilerPC); void FillMIPSTables(); + diff --git a/Core/MIPS/fake/FakeJit.h b/Core/MIPS/fake/FakeJit.h index 0546d0e038..cfb09a8a56 100644 --- a/Core/MIPS/fake/FakeJit.h +++ b/Core/MIPS/fake/FakeJit.h @@ -178,8 +178,5 @@ public: const u8 *breakpointBailout; }; -typedef void (FakeJit::*MIPSCompileFunc)(MIPSOpcode opcode); -typedef int (FakeJit::*MIPSReplaceFunc)(); - } // namespace MIPSComp diff --git a/Core/MIPS/x86/CompReplace.cpp b/Core/MIPS/x86/CompReplace.cpp index f0e907d03f..549e552526 100644 --- a/Core/MIPS/x86/CompReplace.cpp +++ b/Core/MIPS/x86/CompReplace.cpp @@ -18,6 +18,7 @@ #include "Core/MemMap.h" #include "Core/MIPS/JitCommon/NativeJit.h" #include "Core/MIPS/x86/RegCache.h" +#include "Core/MIPS/x86/Jit.h" static const u64 MEMORY_ALIGNED16(ssNoSignMask[2]) = {0x7FFFFFFF7FFFFFFFULL, 0x7FFFFFFF7FFFFFFFULL}; diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index cc927bb389..fb67c3a4ef 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -28,6 +28,7 @@ #include "Common/x64Emitter.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/MIPS/JitCommon/JitState.h" +#include "Core/MIPS/JitCommon/NativeJit.h" #include "Core/MIPS/x86/JitSafeMem.h" #include "Core/MIPS/x86/RegCache.h" #include "Core/MIPS/x86/RegCacheFPU.h" @@ -45,7 +46,7 @@ struct RegCacheState { FPURegCacheState fpr; }; -class Jit : public Gen::XCodeBlock { +class Jit : public Gen::XCodeBlock, public JitInterface { public: Jit(MIPSState *mips); virtual ~Jit(); @@ -53,92 +54,92 @@ public: const JitOptions &GetJitOptions() { return jo; } void DoState(PointerWrap &p); - static void DoDummyState(PointerWrap &p); + void DoDummyState(PointerWrap &p); // Compiled ops should ignore delay slots // the compiler will take care of them by itself // OR NOT - void Comp_Generic(MIPSOpcode op); + void Comp_Generic(MIPSOpcode op) override; - void RunLoopUntil(u64 globalticks); + void RunLoopUntil(u64 globalticks) override; - void Compile(u32 em_address); // Compiles a block at current MIPS PC + void Compile(u32 em_address) override; // Compiles a block at current MIPS PC const u8 *DoJit(u32 em_address, JitBlock *b); - bool DescribeCodePtr(const u8 *ptr, std::string &name); + bool DescribeCodePtr(const u8 *ptr, std::string &name) override; - void Comp_RunBlock(MIPSOpcode op); - void Comp_ReplacementFunc(MIPSOpcode op); + void Comp_RunBlock(MIPSOpcode op) override; + void Comp_ReplacementFunc(MIPSOpcode op) override; // Ops - void Comp_ITypeMem(MIPSOpcode op); - void Comp_Cache(MIPSOpcode op); + void Comp_ITypeMem(MIPSOpcode op) override; + void Comp_Cache(MIPSOpcode op) override; - void Comp_RelBranch(MIPSOpcode op); - void Comp_RelBranchRI(MIPSOpcode op); - void Comp_FPUBranch(MIPSOpcode op); - void Comp_FPULS(MIPSOpcode op); - void Comp_FPUComp(MIPSOpcode op); - void Comp_Jump(MIPSOpcode op); - void Comp_JumpReg(MIPSOpcode op); - void Comp_Syscall(MIPSOpcode op); - void Comp_Break(MIPSOpcode op); + void Comp_RelBranch(MIPSOpcode op) override; + void Comp_RelBranchRI(MIPSOpcode op) override; + void Comp_FPUBranch(MIPSOpcode op) override; + void Comp_FPULS(MIPSOpcode op) override; + void Comp_FPUComp(MIPSOpcode op) override; + void Comp_Jump(MIPSOpcode op) override; + void Comp_JumpReg(MIPSOpcode op) override; + void Comp_Syscall(MIPSOpcode op) override; + void Comp_Break(MIPSOpcode op) override; - void Comp_IType(MIPSOpcode op); - void Comp_RType2(MIPSOpcode op); - void Comp_RType3(MIPSOpcode op); - void Comp_ShiftType(MIPSOpcode op); - void Comp_Allegrex(MIPSOpcode op); - void Comp_Allegrex2(MIPSOpcode op); - void Comp_VBranch(MIPSOpcode op); - void Comp_MulDivType(MIPSOpcode op); - void Comp_Special3(MIPSOpcode op); + void Comp_IType(MIPSOpcode op) override; + void Comp_RType2(MIPSOpcode op) override; + void Comp_RType3(MIPSOpcode op) override; + void Comp_ShiftType(MIPSOpcode op) override; + void Comp_Allegrex(MIPSOpcode op) override; + void Comp_Allegrex2(MIPSOpcode op) override; + void Comp_VBranch(MIPSOpcode op) override; + void Comp_MulDivType(MIPSOpcode op) override; + void Comp_Special3(MIPSOpcode op) override; - void Comp_FPU3op(MIPSOpcode op); - void Comp_FPU2op(MIPSOpcode op); - void Comp_mxc1(MIPSOpcode op); + void Comp_FPU3op(MIPSOpcode op) override; + void Comp_FPU2op(MIPSOpcode op) override; + void Comp_mxc1(MIPSOpcode op) override; - void Comp_SV(MIPSOpcode op); - void Comp_SVQ(MIPSOpcode op); - void Comp_VPFX(MIPSOpcode op); - void Comp_VVectorInit(MIPSOpcode op); - void Comp_VMatrixInit(MIPSOpcode op); - void Comp_VDot(MIPSOpcode op); - void Comp_VecDo3(MIPSOpcode op); - void Comp_VV2Op(MIPSOpcode op); - void Comp_Mftv(MIPSOpcode op); - void Comp_Vmfvc(MIPSOpcode op); - void Comp_Vmtvc(MIPSOpcode op); - void Comp_Vmmov(MIPSOpcode op); - void Comp_VScl(MIPSOpcode op); - void Comp_Vmmul(MIPSOpcode op); - void Comp_Vmscl(MIPSOpcode op); - void Comp_Vtfm(MIPSOpcode op); - void Comp_VHdp(MIPSOpcode op); - void Comp_VCrs(MIPSOpcode op); - void Comp_VDet(MIPSOpcode op); - void Comp_Vi2x(MIPSOpcode op); - void Comp_Vx2i(MIPSOpcode op); - void Comp_Vf2i(MIPSOpcode op); - void Comp_Vi2f(MIPSOpcode op); - void Comp_Vh2f(MIPSOpcode op); - void Comp_Vcst(MIPSOpcode op); - void Comp_Vhoriz(MIPSOpcode op); - void Comp_VRot(MIPSOpcode op); - void Comp_VIdt(MIPSOpcode op); - void Comp_Vcmp(MIPSOpcode op); - void Comp_Vcmov(MIPSOpcode op); - void Comp_Viim(MIPSOpcode op); - void Comp_Vfim(MIPSOpcode op); - void Comp_VCrossQuat(MIPSOpcode op); - void Comp_Vsgn(MIPSOpcode op); - void Comp_Vocp(MIPSOpcode op); - void Comp_ColorConv(MIPSOpcode op); - void Comp_Vbfy(MIPSOpcode op); + void Comp_SV(MIPSOpcode op) override; + void Comp_SVQ(MIPSOpcode op) override; + void Comp_VPFX(MIPSOpcode op) override; + void Comp_VVectorInit(MIPSOpcode op) override; + void Comp_VMatrixInit(MIPSOpcode op) override; + void Comp_VDot(MIPSOpcode op) override; + void Comp_VecDo3(MIPSOpcode op) override; + void Comp_VV2Op(MIPSOpcode op) override; + void Comp_Mftv(MIPSOpcode op) override; + void Comp_Vmfvc(MIPSOpcode op) override; + void Comp_Vmtvc(MIPSOpcode op) override; + void Comp_Vmmov(MIPSOpcode op) override; + void Comp_VScl(MIPSOpcode op) override; + void Comp_Vmmul(MIPSOpcode op) override; + void Comp_Vmscl(MIPSOpcode op) override; + void Comp_Vtfm(MIPSOpcode op) override; + void Comp_VHdp(MIPSOpcode op) override; + void Comp_VCrs(MIPSOpcode op) override; + void Comp_VDet(MIPSOpcode op) override; + void Comp_Vi2x(MIPSOpcode op) override; + void Comp_Vx2i(MIPSOpcode op) override; + void Comp_Vf2i(MIPSOpcode op) override; + void Comp_Vi2f(MIPSOpcode op) override; + void Comp_Vh2f(MIPSOpcode op) override; + void Comp_Vcst(MIPSOpcode op) override; + void Comp_Vhoriz(MIPSOpcode op) override; + void Comp_VRot(MIPSOpcode op) override; + void Comp_VIdt(MIPSOpcode op) override; + void Comp_Vcmp(MIPSOpcode op) override; + void Comp_Vcmov(MIPSOpcode op) override; + void Comp_Viim(MIPSOpcode op) override; + void Comp_Vfim(MIPSOpcode op) override; + void Comp_VCrossQuat(MIPSOpcode op) override; + void Comp_Vsgn(MIPSOpcode op) override; + void Comp_Vocp(MIPSOpcode op) override; + void Comp_ColorConv(MIPSOpcode op) override; + void Comp_Vbfy(MIPSOpcode op) override; - void Comp_DoNothing(MIPSOpcode op); + void Comp_DoNothing(MIPSOpcode op) override; - int Replace_fabsf(); + int Replace_fabsf() override; void ApplyPrefixST(u8 *vregs, u32 prefix, VectorSize sz); void ApplyPrefixD(const u8 *vregs, VectorSize sz); @@ -162,14 +163,14 @@ public: JitBlockCache *GetBlockCache() { return &blocks; } void ClearCache(); - void InvalidateCache(); - inline void InvalidateCacheAt(u32 em_address, int length = 4) { + void InvalidateCache() override; + void InvalidateCacheAt(u32 em_address, int length = 4) { if (blocks.RangeMayHaveEmuHacks(em_address, em_address + length)) { blocks.InvalidateICache(em_address, length); } } - const u8 *GetDispatcher() const { + const u8 *GetDispatcher() const override { return dispatcher; } diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index e07fc65bb8..557bc461c4 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -35,6 +35,7 @@ #include "Core/Debugger/Breakpoints.h" #include "Core/Config.h" #include "Core/HLE/ReplaceTables.h" +#include "Core/MIPS/JitCommon/JitBlockCache.h" namespace Memory { diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 1155de1c61..bf6f30eeed 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -41,6 +41,7 @@ #include "Core/HLE/sceKernel.h" #include "Core/MemMap.h" #include "Core/MIPS/MIPS.h" +#include "Core/MIPS/JitCommon/JitBlockCache.h" #include "HW/MemoryStick.h" #include "GPU/GPUState.h" #include "UI/OnScreenDisplay.h" diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index e25c8ad982..52cf744a0a 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -35,6 +35,7 @@ #include "Core/CoreParameter.h" #include "Core/MIPS/MIPSTables.h" #include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 6eb9e787c8..4f0e3e78ef 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -357,6 +357,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/MIPS/JitCommon/JitCommon.cpp \ $(SRC)/Core/MIPS/JitCommon/JitBlockCache.cpp \ $(SRC)/Core/MIPS/JitCommon/JitState.cpp \ + $(SRC)/Core/MIPS/JitCommon/NativeJit.cpp \ $(SRC)/Core/Util/AudioFormat.cpp \ $(SRC)/Core/Util/GameManager.cpp \ $(SRC)/Core/Util/BlockAllocator.cpp \ diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index dc533ad362..bfd745b38f 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -21,6 +21,7 @@ #include "base/NativeApp.h" #include "input/input_state.h" #include "Core/MIPS/JitCommon/JitCommon.h" +#include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/MIPS/JitCommon/NativeJit.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/MIPSDebugInterface.h" From 5aadce59a2ede8836bb5a0690af56d466d23321d Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 1 May 2016 10:25:01 +0200 Subject: [PATCH 2/5] Move architecture-specific code out of JitBlockCache --- Core/MIPS/ARM/ArmJit.cpp | 37 ++++++++++- Core/MIPS/ARM/ArmJit.h | 3 + Core/MIPS/ARM64/Arm64Jit.cpp | 24 ++++++- Core/MIPS/ARM64/Arm64Jit.h | 3 + Core/MIPS/JitCommon/JitBlockCache.cpp | 91 +-------------------------- Core/MIPS/JitCommon/JitBlockCache.h | 2 +- Core/MIPS/JitCommon/NativeJit.h | 5 ++ Core/MIPS/x86/Jit.cpp | 26 +++++++- Core/MIPS/x86/Jit.h | 3 + 9 files changed, 98 insertions(+), 96 deletions(-) diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index ac78d8aab4..621678afe2 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -271,17 +271,17 @@ const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b) JumpTarget backJump = GetCodePtr(); gpr.SetRegImm(R0, js.blockStart); B((const void *)outerLoopPCInR0); - b->checkedEntry = GetCodePtr(); + b->checkedEntry = (u8 *)GetCodePtr(); SetCC(CC_LT); B(backJump); SetCC(CC_AL); } else if (jo.useForwardJump) { - b->checkedEntry = GetCodePtr(); + b->checkedEntry = (u8 *)GetCodePtr(); SetCC(CC_LT); bail = B(); SetCC(CC_AL); } else { - b->checkedEntry = GetCodePtr(); + b->checkedEntry = (u8 *)GetCodePtr(); SetCC(CC_LT); gpr.SetRegImm(R0, js.blockStart); B((const void *)outerLoopPCInR0); @@ -397,6 +397,37 @@ void ArmJit::Comp_RunBlock(MIPSOpcode op) ERROR_LOG(JIT, "Comp_RunBlock should never be reached!"); } +void ArmJit::LinkBlock(u8 *exitPoint, const u8 *checkedEntry) { + ARMXEmitter emit(exitPoint); + u32 op = *((const u32 *)emit.GetCodePtr()); + bool prelinked = (op & 0xFF000000) == 0xEA000000; + // Jump directly to the block, yay. + emit.B(checkedEntry); + + if (!prelinked) { + do { + op = *((const u32 *)emit.GetCodePtr()); + // Overwrite whatever is here with a breakpoint. + emit.BKPT(1); + // Stop after overwriting the next unconditional branch or BKPT. + // It can be a BKPT if we unlinked, and are now linking a different one. + } while ((op & 0xFF000000) != 0xEA000000 && (op & 0xFFF000F0) != 0xE1200070); + } + emit.FlushIcache(); +} + +void ArmJit::UnlinkBlock(u8 *checkedEntry, u32 originalAddress) { + // Send anyone who tries to run this block back to the dispatcher. + // Not entirely ideal, but .. pretty good. + // I hope there's enough space... + // checkedEntry is the only "linked" entrance so it's enough to overwrite that. + ARMXEmitter emit(checkedEntry); + emit.MOVI2R(R0, originalAddress); + emit.STR(R0, CTXREG, offsetof(MIPSState, pc)); + emit.B(MIPSComp::jit->GetDispatcher()); + emit.FlushIcache(); +} + bool ArmJit::ReplaceJalTo(u32 dest) { #ifdef ARM const ReplacementTableEntry *entry = nullptr; diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index 50a23631d4..3129cf3771 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -179,6 +179,9 @@ public: return dispatcher; } + void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override; + void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override; + private: const u8 *DoJit(u32 em_address, JitBlock *b); diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index 898b0f5b3f..7eadb8d9ed 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -262,13 +262,13 @@ const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) { const u8 *backJump = GetCodePtr(); MOVI2R(SCRATCH1, js.blockStart); B((const void *)outerLoopPCInSCRATCH1); - b->checkedEntry = GetCodePtr(); + b->checkedEntry = (u8 *)GetCodePtr(); B(CC_LT, backJump); } else if (jo.useForwardJump) { - b->checkedEntry = GetCodePtr(); + b->checkedEntry = (u8 *)GetCodePtr(); bail = B(CC_LT); } else if (jo.enableBlocklink) { - b->checkedEntry = GetCodePtr(); + b->checkedEntry = (u8 *)GetCodePtr(); MOVI2R(SCRATCH1, js.blockStart); FixupBranch skip = B(CC_GE); B((const void *)outerLoopPCInSCRATCH1); @@ -395,6 +395,24 @@ void Arm64Jit::Comp_RunBlock(MIPSOpcode op) { ERROR_LOG(JIT, "Comp_RunBlock should never be reached!"); } +void Arm64Jit::LinkBlock(u8 *exitPoint, const u8 *checkedEntry) { + ARM64XEmitter emit(exitPoint); + emit.B(checkedEntry); + // TODO: Write stuff after. + emit.FlushIcache(); +} + +void Arm64Jit::UnlinkBlock(u8 *checkedEntry, u32 originalAddress) { + // Send anyone who tries to run this block back to the dispatcher. + // Not entirely ideal, but .. works. + // Spurious entrances from previously linked blocks can only come through checkedEntry + ARM64XEmitter emit(checkedEntry); + emit.MOVI2R(SCRATCH1, originalAddress); + emit.STR(INDEX_UNSIGNED, SCRATCH1, CTXREG, offsetof(MIPSState, pc)); + emit.B(MIPSComp::jit->GetDispatcher()); + emit.FlushIcache(); +} + bool Arm64Jit::ReplaceJalTo(u32 dest) { #ifdef ARM64 const ReplacementTableEntry *entry = nullptr; diff --git a/Core/MIPS/ARM64/Arm64Jit.h b/Core/MIPS/ARM64/Arm64Jit.h index f8f4d7461d..01d53504f3 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -180,6 +180,9 @@ public: return dispatcher; } + void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override; + void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override; + private: void GenerateFixedCode(const JitOptions &jo); void FlushAll(); diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index 0eeed6b6a1..dce301c26d 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -44,9 +44,6 @@ #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/NativeJit.h" -#if defined(_M_IX86) || defined(_M_X64) -#include "Common/x64Analyzer.h" -#endif // #include "JitBase.h" #if defined USE_OPROFILE && USE_OPROFILE @@ -61,18 +58,6 @@ op_agent_t agent; #pragma comment(lib, "jitprofiling.lib") #endif -#ifdef ARM -#include "Core/MIPS/ARM/ArmRegCache.h" -using namespace ArmGen; -using namespace ArmJitConstants; -#elif defined(_M_X64) || defined(_M_IX86) -using namespace Gen; -#elif defined(ARM64) -#include "Core/MIPS/ARM64/Arm64RegCache.h" -using namespace Arm64Gen; -using namespace Arm64JitConstants; -#endif - const u32 INVALID_EXIT = 0xFFFFFFFF; JitBlockCache::JitBlockCache(MIPSState *mips, NativeCodeBlock *codeBlock) : @@ -198,7 +183,7 @@ void JitBlockCache::ProxyBlock(u32 rootAddress, u32 startAddress, u32 size, cons // Make binary searches and stuff work ok b.normalEntry = codePtr; - b.checkedEntry = codePtr; + b.checkedEntry = (u8 *)codePtr; // Ugh, casting away const.. proxyBlockMap_.insert(std::make_pair(startAddress, num_blocks_)); AddBlockMap(num_blocks_); @@ -416,46 +401,8 @@ void JitBlockCache::LinkBlockExits(int i) { JitBlock &eb = blocks_[destinationBlock]; // Make sure the destination is not invalid. if (!eb.invalid) { -#if defined(ARM) - ARMXEmitter emit(b.exitPtrs[e]); - u32 op = *((const u32 *)emit.GetCodePtr()); - bool prelinked = (op & 0xFF000000) == 0xEA000000; - // Jump directly to the block, yay. - emit.B(eb.checkedEntry); - - if (!prelinked) { - do { - op = *((const u32 *)emit.GetCodePtr()); - // Overwrite whatever is here with a breakpoint. - emit.BKPT(1); - // Stop after overwriting the next unconditional branch or BKPT. - // It can be a BKPT if we unlinked, and are now linking a different one. - } while ((op & 0xFF000000) != 0xEA000000 && (op & 0xFFF000F0) != 0xE1200070); - } - emit.FlushIcache(); + MIPSComp::jit->LinkBlock(b.exitPtrs[e], eb.checkedEntry); b.linkStatus[e] = true; -#elif defined(_M_IX86) || defined(_M_X64) - XEmitter emit(b.exitPtrs[e]); - // Okay, this is a bit ugly, but we check here if it already has a JMP. - // That means it doesn't have a full exit to pad with INT 3. - bool prelinked = *emit.GetCodePtr() == 0xE9; - emit.JMP(eb.checkedEntry, true); - - if (!prelinked) { - ptrdiff_t actualSize = emit.GetWritableCodePtr() - b.exitPtrs[e]; - int pad = JitBlockCache::GetBlockExitSize() - (int)actualSize; - for (int i = 0; i < pad; ++i) { - emit.INT3(); - } - } - b.linkStatus[e] = true; -#elif defined(ARM64) - ARM64XEmitter emit(b.exitPtrs[e]); - emit.B(eb.checkedEntry); - // TODO: Write stuff after. - emit.FlushIcache(); - b.linkStatus[e] = true; -#endif } } } @@ -588,39 +535,7 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate) { return; } -#if defined(ARM) - - // Send anyone who tries to run this block back to the dispatcher. - // Not entirely ideal, but .. pretty good. - // I hope there's enough space... - // checkedEntry is the only "linked" entrance so it's enough to overwrite that. - ARMXEmitter emit((u8 *)b->checkedEntry); - emit.MOVI2R(R0, b->originalAddress); - emit.STR(R0, CTXREG, offsetof(MIPSState, pc)); - emit.B(MIPSComp::jit->GetDispatcher()); - emit.FlushIcache(); - -#elif defined(_M_IX86) || defined(_M_X64) - - // Send anyone who tries to run this block back to the dispatcher. - // Not entirely ideal, but .. pretty good. - // Spurious entrances from previously linked blocks can only come through checkedEntry - XEmitter emit((u8 *)b->checkedEntry); - emit.MOV(32, M(&mips_->pc), Imm32(b->originalAddress)); - emit.JMP(MIPSComp::jit->GetDispatcher(), true); - -#elif defined(ARM64) - - // Send anyone who tries to run this block back to the dispatcher. - // Not entirely ideal, but .. works. - // Spurious entrances from previously linked blocks can only come through checkedEntry - ARM64XEmitter emit((u8 *)b->checkedEntry); - emit.MOVI2R(SCRATCH1, b->originalAddress); - emit.STR(INDEX_UNSIGNED, SCRATCH1, CTXREG, offsetof(MIPSState, pc)); - emit.B(MIPSComp::jit->GetDispatcher()); - emit.FlushIcache(); - -#endif + MIPSComp::jit->UnlinkBlock(b->checkedEntry, b->originalAddress); } void JitBlockCache::InvalidateICache(u32 address, const u32 length) { diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index ccd448337b..69ac1f451a 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -73,7 +73,7 @@ struct BlockCacheStats { struct JitBlock { bool ContainsAddress(u32 em_address); - const u8 *checkedEntry; + u8 *checkedEntry; // not const, may need to write through this to unlink const u8 *normalEntry; u8 *exitPtrs[MAX_JIT_BLOCK_EXITS]; // to be able to rewrite the exit jump diff --git a/Core/MIPS/JitCommon/NativeJit.h b/Core/MIPS/JitCommon/NativeJit.h index c17c2902ce..6314ad4fc9 100644 --- a/Core/MIPS/JitCommon/NativeJit.h +++ b/Core/MIPS/JitCommon/NativeJit.h @@ -49,6 +49,11 @@ namespace MIPSComp { virtual void ClearCache() = 0; virtual void EatPrefix() = 0; + // Block linking. This may need to work differently for whole-function JITs and stuff + // like that. + virtual void LinkBlock(u8 *exitPoint, const u8 *entryPoint) = 0; + virtual void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) = 0; + virtual void Comp_Generic(MIPSOpcode op) = 0; virtual void Comp_RunBlock(MIPSOpcode op) = 0; virtual void Comp_ReplacementFunc(MIPSOpcode op) = 0; diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index badd772e22..527c6a2c7d 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -359,7 +359,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b) js.PrefixStart(); // We add a check before the block, used when entering from a linked block. - b->checkedEntry = GetCodePtr(); + b->checkedEntry = (u8 *)GetCodePtr(); // Downcount flag check. The last block decremented downcounter, and the flag should still be available. FixupBranch skip = J_CC(CC_NS); MOV(32, M(&mips_->pc), Imm32(js.blockStart)); @@ -501,6 +501,30 @@ void Jit::Comp_RunBlock(MIPSOpcode op) ERROR_LOG(JIT, "Comp_RunBlock"); } +void Jit::LinkBlock(u8 *exitPoint, const u8 *checkedEntry) { + XEmitter emit(exitPoint); + // Okay, this is a bit ugly, but we check here if it already has a JMP. + // That means it doesn't have a full exit to pad with INT 3. + bool prelinked = *emit.GetCodePtr() == 0xE9; + emit.JMP(checkedEntry, true); + if (!prelinked) { + ptrdiff_t actualSize = emit.GetWritableCodePtr() - exitPoint; + int pad = JitBlockCache::GetBlockExitSize() - (int)actualSize; + for (int i = 0; i < pad; ++i) { + emit.INT3(); + } + } +} + +void Jit::UnlinkBlock(u8 *checkedEntry, u32 originalAddress) { + // Send anyone who tries to run this block back to the dispatcher. + // Not entirely ideal, but .. pretty good. + // Spurious entrances from previously linked blocks can only come through checkedEntry + XEmitter emit(checkedEntry); + emit.MOV(32, M(&mips_->pc), Imm32(originalAddress)); + emit.JMP(MIPSComp::jit->GetDispatcher(), true); +} + bool Jit::ReplaceJalTo(u32 dest) { const ReplacementTableEntry *entry = nullptr; u32 funcSize = 0; diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index fb67c3a4ef..7aada0997a 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -174,6 +174,9 @@ public: return dispatcher; } + void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override; + void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override; + private: void GenerateFixedCode(JitOptions &jo); void GetStateAndFlushAll(RegCacheState &state); From 8b450c80340906685be07bd1c212cf97b0200b48 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 1 May 2016 10:35:37 +0200 Subject: [PATCH 3/5] Merge NativeJit.cpp/h with JitCommon.cpp/h --- CMakeLists.txt | 2 - Core/Core.vcxproj | 2 - Core/Core.vcxproj.filters | 6 -- Core/CwCheat.cpp | 2 +- Core/Debugger/Breakpoints.cpp | 2 +- Core/HLE/ReplaceTables.h | 2 +- Core/MIPS/ARM/ArmJit.h | 2 +- Core/MIPS/ARM64/Arm64Jit.h | 2 +- Core/MIPS/JitCommon/JitBlockCache.cpp | 1 - Core/MIPS/JitCommon/JitBlockCache.h | 3 +- Core/MIPS/JitCommon/JitCommon.cpp | 45 +++++++-- Core/MIPS/JitCommon/JitCommon.h | 110 ++++++++++++++++++++- Core/MIPS/JitCommon/NativeJit.cpp | 53 ----------- Core/MIPS/JitCommon/NativeJit.h | 131 -------------------------- Core/MIPS/MIPS.cpp | 2 - Core/MIPS/MIPSAsm.cpp | 2 +- Core/MIPS/MIPSTables.cpp | 2 +- Core/MIPS/x86/CompReplace.cpp | 2 +- Core/MIPS/x86/Jit.h | 2 +- UI/CwCheatScreen.cpp | 2 +- UI/DevScreens.cpp | 1 - UI/MiscScreens.cpp | 2 +- Windows/MainWindow.cpp | 2 +- android/jni/Android.mk | 1 - unittest/JitHarness.cpp | 1 - 25 files changed, 161 insertions(+), 221 deletions(-) delete mode 100644 Core/MIPS/JitCommon/NativeJit.cpp delete mode 100644 Core/MIPS/JitCommon/NativeJit.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d18eab9c1d..f208b4e9e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1389,8 +1389,6 @@ add_library(${CoreLibName} ${CoreLinkType} Core/FileLoaders/RetryingFileLoader.h Core/MIPS/JitCommon/JitCommon.cpp Core/MIPS/JitCommon/JitCommon.h - Core/MIPS/JitCommon/NativeJit.cpp - Core/MIPS/JitCommon/NativeJit.h Core/MIPS/JitCommon/JitBlockCache.cpp Core/MIPS/JitCommon/JitBlockCache.h Core/MIPS/JitCommon/JitState.cpp diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 7230ef2683..caa73aaa5e 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -426,7 +426,6 @@ - @@ -667,7 +666,6 @@ - diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 1f5ca4951c..74b4939acc 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -631,9 +631,6 @@ FileLoaders - - MIPS\JitCommon - @@ -681,9 +678,6 @@ MIPS\JitCommon - - MIPS\JitCommon - FileSystems diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 9fef3c0915..ca0bc3b90a 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -11,7 +11,7 @@ #include "Core/ELF/ParamSFO.h" #include "Core/System.h" #include "Core/HLE/sceCtrl.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #ifdef _WIN32 #include "util/text/utf8.h" diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp index 0d1318d128..8eef12f831 100644 --- a/Core/Debugger/Breakpoints.cpp +++ b/Core/Debugger/Breakpoints.cpp @@ -23,7 +23,7 @@ #include "Core/Debugger/SymbolMap.h" #include "Core/Host.h" #include "Core/MIPS/MIPSAnalyst.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/CoreTiming.h" std::vector CBreakPoints::breakPoints_; diff --git a/Core/HLE/ReplaceTables.h b/Core/HLE/ReplaceTables.h index ba512bde4f..84f85b7eea 100644 --- a/Core/HLE/ReplaceTables.h +++ b/Core/HLE/ReplaceTables.h @@ -34,7 +34,7 @@ #pragma once #include "Common/CommonTypes.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" typedef int (* ReplaceFunc)(); diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index 3129cf3771..07b70af968 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -22,7 +22,7 @@ #include "Common/ArmEmitter.h" #include "Core/MIPS/JitCommon/JitState.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/ARM/ArmRegCache.h" #include "Core/MIPS/ARM/ArmRegCacheFPU.h" #include "Core/MIPS/MIPSVFPUUtils.h" diff --git a/Core/MIPS/ARM64/Arm64Jit.h b/Core/MIPS/ARM64/Arm64Jit.h index 01d53504f3..e1c9cf5dec 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -22,7 +22,7 @@ #include "Common/Arm64Emitter.h" #include "Core/MIPS/JitCommon/JitState.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/ARM64/Arm64RegCache.h" #include "Core/MIPS/ARM64/Arm64RegCacheFPU.h" #include "Core/MIPS/MIPSVFPUUtils.h" diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index dce301c26d..29ca61296c 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -42,7 +42,6 @@ #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/MIPS/JitCommon/JitCommon.h" -#include "Core/MIPS/JitCommon/NativeJit.h" // #include "JitBase.h" diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index 69ac1f451a..3dc23e6f63 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -114,8 +114,7 @@ public: int AllocateBlock(u32 em_address); // When a proxy block is invalidated, the block located at the rootAddress - // is invalidated too. - void ProxyBlock(u32 rootAddress, u32 startAddress, u32 size, const u8 *codePtr); + void ProxyBlock(u32 rootAddress, u32 startAddress, u32 size, u8 *codePtr); void FinalizeBlock(int block_num, bool block_link); void Clear(); diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp index 5c356354e7..91ed4c10d6 100644 --- a/Core/MIPS/JitCommon/JitCommon.cpp +++ b/Core/MIPS/JitCommon/JitCommon.cpp @@ -15,17 +15,50 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include - -#include "Core/MIPS/JitCommon/JitCommon.h" -#include "Core/MIPS/JitCommon/JitState.h" -#include "Core/MIPS/JitCommon/NativeJit.h" -#include "Common/StringUtils.h" +#include #include "ext/disarm.h" #include "ext/udis86/udis86.h" + +#include "Common/StringUtils.h" #include "Core/Util/DisArm64.h" +#include "Core/MIPS/JitCommon/JitCommon.h" +#include "Core/MIPS/JitCommon/JitState.h" + +#if defined(ARM) +#include "../ARM/ArmJit.h" +#elif defined(ARM64) +#include "../ARM64/Arm64Jit.h" +#elif defined(_M_IX86) || defined(_M_X64) +#include "../x86/Jit.h" +#elif defined(MIPS) +#include "../MIPS/MipsJit.h" +#else +#include "../fake/FakeJit.h" +#endif + +namespace MIPSComp { + JitInterface *jit; + void JitAt() { + jit->Compile(currentMIPS->pc); + } + + JitInterface *CreateNativeJit(MIPSState *mips) { +#if defined(ARM) + return new MIPSComp::ArmJit(mips); +#elif defined(ARM64) + return new MIPSComp::Arm64Jit(mips); +#elif defined(_M_IX86) || defined(_M_X64) + return new MIPSComp::Jit(mips); +#elif defined(MIPS) + return new MIPSComp::MipsJit(mips); +#else + return new MIPSComp::FakeJit(mips); +#endif + } + +} #if (defined(_M_IX86) || defined(_M_X64)) && defined(_WIN32) #define DISASM_ALL 1 #endif diff --git a/Core/MIPS/JitCommon/JitCommon.h b/Core/MIPS/JitCommon/JitCommon.h index a3a1c35828..9c440a6cdb 100644 --- a/Core/MIPS/JitCommon/JitCommon.h +++ b/Core/MIPS/JitCommon/JitCommon.h @@ -21,12 +21,120 @@ #include #include "Common/Common.h" +#include "Common/CommonTypes.h" +#include "Core/MIPS/MIPS.h" // TODO: Find a better place for these. std::vector DisassembleArm2(const u8 *data, int size); std::vector DisassembleArm64(const u8 *data, int size); std::vector DisassembleX86(const u8 *data, int size); +struct JitBlock; +class JitBlockCache; +class PointerWrap; + +#ifdef USING_QT_UI +#undef emit +#endif + +class MIPSState; + namespace MIPSComp { void JitAt(); -} \ No newline at end of file + + class JitInterface { + public: + virtual ~JitInterface() {} + + virtual bool DescribeCodePtr(const u8 *ptr, std::string &name) = 0; + virtual const u8 *GetDispatcher() const = 0; + virtual JitBlockCache *GetBlockCache() = 0; + virtual void InvalidateCache() = 0; + virtual void InvalidateCacheAt(u32 em_address, int length = 4) = 0; + virtual void DoState(PointerWrap &p) = 0; + virtual void DoDummyState(PointerWrap &p) = 0; + virtual void RunLoopUntil(u64 globalticks) = 0; + virtual void Compile(u32 em_address) = 0; + virtual void ClearCache() = 0; + virtual void EatPrefix() = 0; + + // Block linking. This may need to work differently for whole-function JITs and stuff + // like that. + virtual void LinkBlock(u8 *exitPoint, const u8 *entryPoint) = 0; + virtual void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) = 0; + + virtual void Comp_Generic(MIPSOpcode op) = 0; + virtual void Comp_RunBlock(MIPSOpcode op) = 0; + virtual void Comp_ReplacementFunc(MIPSOpcode op) = 0; + virtual void Comp_ITypeMem(MIPSOpcode op) = 0; + virtual void Comp_Cache(MIPSOpcode op) = 0; + virtual void Comp_RelBranch(MIPSOpcode op) = 0; + virtual void Comp_RelBranchRI(MIPSOpcode op) = 0; + virtual void Comp_FPUBranch(MIPSOpcode op) = 0; + virtual void Comp_FPULS(MIPSOpcode op) = 0; + virtual void Comp_FPUComp(MIPSOpcode op) = 0; + virtual void Comp_Jump(MIPSOpcode op) = 0; + virtual void Comp_JumpReg(MIPSOpcode op) = 0; + virtual void Comp_Syscall(MIPSOpcode op) = 0; + virtual void Comp_Break(MIPSOpcode op) = 0; + virtual void Comp_IType(MIPSOpcode op) = 0; + virtual void Comp_RType2(MIPSOpcode op) = 0; + virtual void Comp_RType3(MIPSOpcode op) = 0; + virtual void Comp_ShiftType(MIPSOpcode op) = 0; + virtual void Comp_Allegrex(MIPSOpcode op) = 0; + virtual void Comp_Allegrex2(MIPSOpcode op) = 0; + virtual void Comp_VBranch(MIPSOpcode op) = 0; + virtual void Comp_MulDivType(MIPSOpcode op) = 0; + virtual void Comp_Special3(MIPSOpcode op) = 0; + virtual void Comp_FPU3op(MIPSOpcode op) = 0; + virtual void Comp_FPU2op(MIPSOpcode op) = 0; + virtual void Comp_mxc1(MIPSOpcode op) = 0; + virtual void Comp_SV(MIPSOpcode op) = 0; + virtual void Comp_SVQ(MIPSOpcode op) = 0; + virtual void Comp_VPFX(MIPSOpcode op) = 0; + virtual void Comp_VVectorInit(MIPSOpcode op) = 0; + virtual void Comp_VMatrixInit(MIPSOpcode op) = 0; + virtual void Comp_VDot(MIPSOpcode op) = 0; + virtual void Comp_VecDo3(MIPSOpcode op) = 0; + virtual void Comp_VV2Op(MIPSOpcode op) = 0; + virtual void Comp_Mftv(MIPSOpcode op) = 0; + virtual void Comp_Vmfvc(MIPSOpcode op) = 0; + virtual void Comp_Vmtvc(MIPSOpcode op) = 0; + virtual void Comp_Vmmov(MIPSOpcode op) = 0; + virtual void Comp_VScl(MIPSOpcode op) = 0; + virtual void Comp_Vmmul(MIPSOpcode op) = 0; + virtual void Comp_Vmscl(MIPSOpcode op) = 0; + virtual void Comp_Vtfm(MIPSOpcode op) = 0; + virtual void Comp_VHdp(MIPSOpcode op) = 0; + virtual void Comp_VCrs(MIPSOpcode op) = 0; + virtual void Comp_VDet(MIPSOpcode op) = 0; + virtual void Comp_Vi2x(MIPSOpcode op) = 0; + virtual void Comp_Vx2i(MIPSOpcode op) = 0; + virtual void Comp_Vf2i(MIPSOpcode op) = 0; + virtual void Comp_Vi2f(MIPSOpcode op) = 0; + virtual void Comp_Vh2f(MIPSOpcode op) = 0; + virtual void Comp_Vcst(MIPSOpcode op) = 0; + virtual void Comp_Vhoriz(MIPSOpcode op) = 0; + virtual void Comp_VRot(MIPSOpcode op) = 0; + virtual void Comp_VIdt(MIPSOpcode op) = 0; + virtual void Comp_Vcmp(MIPSOpcode op) = 0; + virtual void Comp_Vcmov(MIPSOpcode op) = 0; + virtual void Comp_Viim(MIPSOpcode op) = 0; + virtual void Comp_Vfim(MIPSOpcode op) = 0; + virtual void Comp_VCrossQuat(MIPSOpcode op) = 0; + virtual void Comp_Vsgn(MIPSOpcode op) = 0; + virtual void Comp_Vocp(MIPSOpcode op) = 0; + virtual void Comp_ColorConv(MIPSOpcode op) = 0; + virtual void Comp_Vbfy(MIPSOpcode op) = 0; + virtual void Comp_DoNothing(MIPSOpcode op) = 0; + + virtual int Replace_fabsf() = 0; + }; + + typedef void (JitInterface::*MIPSCompileFunc)(MIPSOpcode opcode); + typedef int (JitInterface::*MIPSReplaceFunc)(); + + extern JitInterface *jit; + + JitInterface *CreateNativeJit(MIPSState *mips); +} diff --git a/Core/MIPS/JitCommon/NativeJit.cpp b/Core/MIPS/JitCommon/NativeJit.cpp deleted file mode 100644 index 7c6b81295e..0000000000 --- a/Core/MIPS/JitCommon/NativeJit.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2012- PPSSPP 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 or later versions. - -// 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 git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#include "Core/MIPS/JitCommon/NativeJit.h" -#include "Core/MIPS/JitCommon/JitState.h" - -#if defined(ARM) -#include "../ARM/ArmJit.h" -#elif defined(ARM64) -#include "../ARM64/Arm64Jit.h" -#elif defined(_M_IX86) || defined(_M_X64) -#include "../x86/Jit.h" -#elif defined(MIPS) -#include "../MIPS/MipsJit.h" -#else -#include "../fake/FakeJit.h" -#endif - -namespace MIPSComp { - JitInterface *jit; - void JitAt() { - jit->Compile(currentMIPS->pc); - } - -JitInterface *CreateNativeJit(MIPSState *mips) { -#if defined(ARM) - return new MIPSComp::ArmJit(mips); -#elif defined(ARM64) - return new MIPSComp::Arm64Jit(mips); -#elif defined(_M_IX86) || defined(_M_X64) - return new MIPSComp::Jit(mips); -#elif defined(MIPS) - return new MIPSComp::MipsJit(mips); -#else - return new MIPSComp::FakeJit(mips); -#endif -} - -} \ No newline at end of file diff --git a/Core/MIPS/JitCommon/NativeJit.h b/Core/MIPS/JitCommon/NativeJit.h deleted file mode 100644 index 6314ad4fc9..0000000000 --- a/Core/MIPS/JitCommon/NativeJit.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) 2012- PPSSPP 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 or later versions. - -// 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 git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#pragma once - -#include -#include "Common/CommonTypes.h" -#include "Core/MIPS/MIPS.h" - -struct JitBlock; -class JitBlockCache; -class PointerWrap; - -#ifdef USING_QT_UI -#undef emit -#endif - -class MIPSState; - -namespace MIPSComp { - - class JitInterface { - public: - virtual ~JitInterface() {} - - virtual bool DescribeCodePtr(const u8 *ptr, std::string &name) = 0; - virtual const u8 *GetDispatcher() const = 0; - virtual JitBlockCache *GetBlockCache() = 0; - virtual void InvalidateCache() = 0; - virtual void InvalidateCacheAt(u32 em_address, int length = 4) = 0; - virtual void DoState(PointerWrap &p) = 0; - virtual void DoDummyState(PointerWrap &p) = 0; - virtual void RunLoopUntil(u64 globalticks) = 0; - virtual void Compile(u32 em_address) = 0; - virtual void ClearCache() = 0; - virtual void EatPrefix() = 0; - - // Block linking. This may need to work differently for whole-function JITs and stuff - // like that. - virtual void LinkBlock(u8 *exitPoint, const u8 *entryPoint) = 0; - virtual void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) = 0; - - virtual void Comp_Generic(MIPSOpcode op) = 0; - virtual void Comp_RunBlock(MIPSOpcode op) = 0; - virtual void Comp_ReplacementFunc(MIPSOpcode op) = 0; - virtual void Comp_ITypeMem(MIPSOpcode op) = 0; - virtual void Comp_Cache(MIPSOpcode op) = 0; - virtual void Comp_RelBranch(MIPSOpcode op) = 0; - virtual void Comp_RelBranchRI(MIPSOpcode op) = 0; - virtual void Comp_FPUBranch(MIPSOpcode op) = 0; - virtual void Comp_FPULS(MIPSOpcode op) = 0; - virtual void Comp_FPUComp(MIPSOpcode op) = 0; - virtual void Comp_Jump(MIPSOpcode op) = 0; - virtual void Comp_JumpReg(MIPSOpcode op) = 0; - virtual void Comp_Syscall(MIPSOpcode op) = 0; - virtual void Comp_Break(MIPSOpcode op) = 0; - virtual void Comp_IType(MIPSOpcode op) = 0; - virtual void Comp_RType2(MIPSOpcode op) = 0; - virtual void Comp_RType3(MIPSOpcode op) = 0; - virtual void Comp_ShiftType(MIPSOpcode op) = 0; - virtual void Comp_Allegrex(MIPSOpcode op) = 0; - virtual void Comp_Allegrex2(MIPSOpcode op) = 0; - virtual void Comp_VBranch(MIPSOpcode op) = 0; - virtual void Comp_MulDivType(MIPSOpcode op) = 0; - virtual void Comp_Special3(MIPSOpcode op) = 0; - virtual void Comp_FPU3op(MIPSOpcode op) = 0; - virtual void Comp_FPU2op(MIPSOpcode op) = 0; - virtual void Comp_mxc1(MIPSOpcode op) = 0; - virtual void Comp_SV(MIPSOpcode op) = 0; - virtual void Comp_SVQ(MIPSOpcode op) = 0; - virtual void Comp_VPFX(MIPSOpcode op) = 0; - virtual void Comp_VVectorInit(MIPSOpcode op) = 0; - virtual void Comp_VMatrixInit(MIPSOpcode op) = 0; - virtual void Comp_VDot(MIPSOpcode op) = 0; - virtual void Comp_VecDo3(MIPSOpcode op) = 0; - virtual void Comp_VV2Op(MIPSOpcode op) = 0; - virtual void Comp_Mftv(MIPSOpcode op) = 0; - virtual void Comp_Vmfvc(MIPSOpcode op) = 0; - virtual void Comp_Vmtvc(MIPSOpcode op) = 0; - virtual void Comp_Vmmov(MIPSOpcode op) = 0; - virtual void Comp_VScl(MIPSOpcode op) = 0; - virtual void Comp_Vmmul(MIPSOpcode op) = 0; - virtual void Comp_Vmscl(MIPSOpcode op) = 0; - virtual void Comp_Vtfm(MIPSOpcode op) = 0; - virtual void Comp_VHdp(MIPSOpcode op) = 0; - virtual void Comp_VCrs(MIPSOpcode op) = 0; - virtual void Comp_VDet(MIPSOpcode op) = 0; - virtual void Comp_Vi2x(MIPSOpcode op) = 0; - virtual void Comp_Vx2i(MIPSOpcode op) = 0; - virtual void Comp_Vf2i(MIPSOpcode op) = 0; - virtual void Comp_Vi2f(MIPSOpcode op) = 0; - virtual void Comp_Vh2f(MIPSOpcode op) = 0; - virtual void Comp_Vcst(MIPSOpcode op) = 0; - virtual void Comp_Vhoriz(MIPSOpcode op) = 0; - virtual void Comp_VRot(MIPSOpcode op) = 0; - virtual void Comp_VIdt(MIPSOpcode op) = 0; - virtual void Comp_Vcmp(MIPSOpcode op) = 0; - virtual void Comp_Vcmov(MIPSOpcode op) = 0; - virtual void Comp_Viim(MIPSOpcode op) = 0; - virtual void Comp_Vfim(MIPSOpcode op) = 0; - virtual void Comp_VCrossQuat(MIPSOpcode op) = 0; - virtual void Comp_Vsgn(MIPSOpcode op) = 0; - virtual void Comp_Vocp(MIPSOpcode op) = 0; - virtual void Comp_ColorConv(MIPSOpcode op) = 0; - virtual void Comp_Vbfy(MIPSOpcode op) = 0; - virtual void Comp_DoNothing(MIPSOpcode op) = 0; - - virtual int Replace_fabsf() = 0; - }; - - typedef void (JitInterface::*MIPSCompileFunc)(MIPSOpcode opcode); - typedef int (JitInterface::*MIPSReplaceFunc)(); - - extern JitInterface *jit; - - JitInterface *CreateNativeJit(MIPSState *mips); -} diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 6cb88b8594..1140b67914 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -27,12 +27,10 @@ #include "Core/MIPS/MIPSTables.h" #include "Core/MIPS/MIPSDebugInterface.h" #include "Core/MIPS/MIPSVFPUUtils.h" -#include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/Reporting.h" #include "Core/System.h" #include "Core/HLE/sceDisplay.h" #include "Core/MIPS/JitCommon/JitCommon.h" -#include "Core/MIPS/JitCommon/NativeJit.h" #include "Core/CoreTiming.h" MIPSState mipsr4k; diff --git a/Core/MIPS/MIPSAsm.cpp b/Core/MIPS/MIPSAsm.cpp index ae7982ef8a..ecb9ea1859 100644 --- a/Core/MIPS/MIPSAsm.cpp +++ b/Core/MIPS/MIPSAsm.cpp @@ -15,7 +15,7 @@ #include "util/text/utf8.h" #include "Core/Debugger/SymbolMap.h" #include "Core/MemMapHelpers.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/MIPSAsm.h" namespace MIPSAsm diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 4112123779..dec15e41b6 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -29,7 +29,7 @@ #include "Core/Reporting.h" #include "Core/Debugger/Breakpoints.h" -#include "JitCommon/NativeJit.h" +#include "JitCommon/JitCommon.h" enum MipsEncoding { Imme, diff --git a/Core/MIPS/x86/CompReplace.cpp b/Core/MIPS/x86/CompReplace.cpp index 549e552526..336a38264e 100644 --- a/Core/MIPS/x86/CompReplace.cpp +++ b/Core/MIPS/x86/CompReplace.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Core/MemMap.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/x86/RegCache.h" #include "Core/MIPS/x86/Jit.h" diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index 7aada0997a..68d160a958 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -28,7 +28,7 @@ #include "Common/x64Emitter.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/MIPS/JitCommon/JitState.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/x86/JitSafeMem.h" #include "Core/MIPS/x86/RegCache.h" #include "Core/MIPS/x86/RegCacheFPU.h" diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index e16262f159..7f6481709c 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -25,7 +25,7 @@ #include "Core/Core.h" #include "Core/Config.h" #include "Core/CwCheat.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "UI/OnScreenDisplay.h" #include "UI/ui_atlas.h" diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 52cf744a0a..1b41243b61 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -34,7 +34,6 @@ #include "Core/System.h" #include "Core/CoreParameter.h" #include "Core/MIPS/MIPSTables.h" -#include "Core/MIPS/JitCommon/NativeJit.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "GPU/GPUInterface.h" diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 7925287eda..e6f0cc28e6 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -37,7 +37,7 @@ #include "Core/Config.h" #include "Core/Host.h" #include "Core/System.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/HLE/sceUtility.h" #include "Common/FileUtil.h" #include "GPU/GPUState.h" diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 2dd40ce64e..317bf72fbc 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -47,7 +47,7 @@ #include "Windows/Debugger/Debugger_Disasm.h" #include "Windows/Debugger/Debugger_MemoryDlg.h" #include "Windows/GEDebugger/GEDebugger.h" -#include "Core/MIPS/JitCommon/NativeJit.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "main.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 4f0e3e78ef..6eb9e787c8 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -357,7 +357,6 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/MIPS/JitCommon/JitCommon.cpp \ $(SRC)/Core/MIPS/JitCommon/JitBlockCache.cpp \ $(SRC)/Core/MIPS/JitCommon/JitState.cpp \ - $(SRC)/Core/MIPS/JitCommon/NativeJit.cpp \ $(SRC)/Core/Util/AudioFormat.cpp \ $(SRC)/Core/Util/GameManager.cpp \ $(SRC)/Core/Util/BlockAllocator.cpp \ diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index bfd745b38f..b80fb04e6d 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -22,7 +22,6 @@ #include "input/input_state.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" -#include "Core/MIPS/JitCommon/NativeJit.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/MIPSDebugInterface.h" #include "Core/MIPS/MIPSAsm.h" From ffe4c266eff69a912d398d10fd72963f178b6bec Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 1 May 2016 11:13:51 +0200 Subject: [PATCH 4/5] Add CodeBlockCommon base class to remove further arch-specificity in JitBlockCache Remove unused ArmThunk. --- CMakeLists.txt | 3 +- Common/Arm64Emitter.cpp | 10 ++-- Common/Arm64Emitter.h | 5 +- Common/ArmEmitter.cpp | 4 +- Common/ArmEmitter.h | 5 +- Common/ArmThunk.cpp | 74 --------------------------- Common/CodeBlock.h | 64 ++++++++++++++--------- Common/Common.vcxproj | 8 +-- Common/Common.vcxproj.filters | 3 +- Common/Thunk.h | 10 +--- Common/x64Emitter.cpp | 6 +-- Common/x64Emitter.h | 5 +- Core/MIPS/ARM/ArmJit.cpp | 4 +- Core/MIPS/JitCommon/JitBlockCache.cpp | 2 +- Core/MIPS/JitCommon/JitBlockCache.h | 29 ++--------- Core/MIPS/x86/Jit.cpp | 2 +- Qt/Common.pro | 3 +- android/jni/Android.mk | 2 - unittest/TestArm64Emitter.cpp | 2 +- unittest/TestArmEmitter.cpp | 6 +-- unittest/TestX64Emitter.cpp | 8 +-- 21 files changed, 80 insertions(+), 175 deletions(-) delete mode 100644 Common/ArmThunk.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f208b4e9e7..8e4bb97ccb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -306,8 +306,7 @@ endmacro() set(CommonExtra) if(ARM) set(CommonExtra ${CommonExtra} - Common/ArmCPUDetect.cpp - Common/ArmThunk.cpp) + Common/ArmCPUDetect.cpp) if(ARMV7) set(CommonExtra ${CommonExtra} Common/ColorConvNEON.cpp) diff --git a/Common/Arm64Emitter.cpp b/Common/Arm64Emitter.cpp index 805da7a85d..9029117e45 100644 --- a/Common/Arm64Emitter.cpp +++ b/Common/Arm64Emitter.cpp @@ -265,14 +265,14 @@ static int EncodeSize(int size) { } } -void ARM64XEmitter::SetCodePtr(u8* ptr) +void ARM64XEmitter::SetCodePointer(u8* ptr) { m_code = ptr; m_startcode = m_code; m_lastCacheFlushEnd = ptr; } -const u8* ARM64XEmitter::GetCodePtr() const +const u8* ARM64XEmitter::GetCodePointer() const { return m_code; } @@ -1914,7 +1914,7 @@ void ARM64XEmitter::MOVI2R(ARM64Reg Rd, u64 imm, bool optimize) } } - u64 aligned_pc = (u64)GetCodePtr() & ~0xFFF; + u64 aligned_pc = (u64)GetCodePointer() & ~0xFFF; s64 aligned_offset = (s64)imm - (s64)aligned_pc; if (upload_part.Count() > 1 && abs64(aligned_offset) < 0xFFFFFFFFLL) { @@ -1929,7 +1929,7 @@ void ARM64XEmitter::MOVI2R(ARM64Reg Rd, u64 imm, bool optimize) else { // If the address is within 1MB of PC we can load it in a single instruction still - s64 offset = (s64)imm - (s64)GetCodePtr(); + s64 offset = (s64)imm - (s64)GetCodePointer(); if (offset >= -0xFFFFF && offset <= 0xFFFFF) { ADR(Rd, (s32)offset); @@ -2100,7 +2100,7 @@ void ARM64FloatEmitter::EmitLoadStoreImmediate(u8 size, u32 opc, IndexType type, if (type == INDEX_UNSIGNED) { - _assert_msg_(DYNA_REC, !(imm & ((size - 1) >> 3)), "%s(INDEX_UNSIGNED) immediate offset must be aligned to size! (%d) (%p)", __FUNCTION__, imm, m_emit->GetCodePtr()); + _assert_msg_(DYNA_REC, !(imm & ((size - 1) >> 3)), "%s(INDEX_UNSIGNED) immediate offset must be aligned to size! (%d) (%p)", __FUNCTION__, imm, m_emit->GetCodePointer()); _assert_msg_(DYNA_REC, imm >= 0, "%s(INDEX_UNSIGNED) immediate offset must be positive!", __FUNCTION__); if (size == 16) imm >>= 1; diff --git a/Common/Arm64Emitter.h b/Common/Arm64Emitter.h index bf7e30987f..fc1814bae0 100644 --- a/Common/Arm64Emitter.h +++ b/Common/Arm64Emitter.h @@ -394,11 +394,12 @@ public: { } - void SetCodePtr(u8* ptr); + void SetCodePointer(u8* ptr); + const u8* GetCodePointer() const; + void ReserveCodeSpace(u32 bytes); const u8* AlignCode16(); const u8* AlignCodePage(); - const u8* GetCodePtr() const; void FlushIcache(); void FlushIcacheSection(u8* start, u8* end); u8* GetWritableCodePtr(); diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index c547fd4329..1ce785f10b 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -589,14 +589,14 @@ void ARMXEmitter::QuickCallFunction(ARMReg reg, const void *func) { } } -void ARMXEmitter::SetCodePtr(u8 *ptr) +void ARMXEmitter::SetCodePointer(u8 *ptr) { code = ptr; startcode = code; lastCacheFlushEnd = ptr; } -const u8 *ARMXEmitter::GetCodePtr() const +const u8 *ARMXEmitter::GetCodePointer() const { return code; } diff --git a/Common/ArmEmitter.h b/Common/ArmEmitter.h index 6000b94bde..d0cc1de2ed 100644 --- a/Common/ArmEmitter.h +++ b/Common/ArmEmitter.h @@ -445,11 +445,12 @@ public: } virtual ~ARMXEmitter() {} - void SetCodePtr(u8 *ptr); + void SetCodePointer(u8 *ptr); + const u8 *GetCodePointer() const; + void ReserveCodeSpace(u32 bytes); const u8 *AlignCode16(); const u8 *AlignCodePage(); - const u8 *GetCodePtr() const; void FlushIcache(); void FlushIcacheSection(u8 *start, u8 *end); u8 *GetWritableCodePtr(); diff --git a/Common/ArmThunk.cpp b/Common/ArmThunk.cpp deleted file mode 100644 index 8be655b4d9..0000000000 --- a/Common/ArmThunk.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2003 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 "MemoryUtil.h" -#include "Thunk.h" - -#define THUNK_ARENA_SIZE 1024*1024*1 - -namespace -{ - -static u8 GC_ALIGNED32(saved_fp_state[16 * 4 * 4]); -static u8 GC_ALIGNED32(saved_gpr_state[16 * 8]); -static u16 saved_mxcsr; - -} // namespace - -using namespace ArmGen; - -void ThunkManager::Init() -{ -} - -void ThunkManager::Reset() -{ - thunks.clear(); - ResetCodePtr(); -} - -void ThunkManager::Shutdown() -{ - Reset(); - FreeCodeSpace(); -} - -int ThunkManager::ThunkStackOffset() -{ - return 0; -} - -int ThunkManager::ThunkBytesNeeded() -{ - return 0; -} - -const void *ThunkManager::ProtectFunction(const void *function, int num_params) -{ - _dbg_assert_msg_(JIT, false, "Arm ThunkManager not implemented? Will crash."); - return NULL; -} - -void Enter(ThunkEmitter *emit) -{ - _dbg_assert_msg_(JIT, false, "Arm ThunkManager not implemented? Will crash."); -} - -void Leave(ThunkEmitter *emit) -{ - _dbg_assert_msg_(JIT, false, "Arm ThunkManager not implemented? Will crash."); -} diff --git a/Common/CodeBlock.h b/Common/CodeBlock.h index 3a96d75177..337f08a9c9 100644 --- a/Common/CodeBlock.h +++ b/Common/CodeBlock.h @@ -12,19 +12,41 @@ // having to prefix them with gen-> or something similar. // Example implementation: // class JIT : public CodeBlock, public JitInterface {} -template class CodeBlock : public T, NonCopyable + +class CodeBlockCommon { +public: + CodeBlockCommon() : region(nullptr), region_size(0) {} + virtual ~CodeBlockCommon() {} + + bool IsInSpace(const u8 *ptr) { + return (ptr >= region) && (ptr < (region + region_size)); + } + + virtual void SetCodePtr(u8 *ptr) = 0; + virtual const u8 *GetCodePtr() const = 0; + + u8 *GetBasePtr() { + return region; + } + + size_t GetOffset(const u8 *ptr) const { + return ptr - region; + } + +protected: + u8 *region; + size_t region_size; +}; + +template class CodeBlock : public CodeBlockCommon, public T, NonCopyable { private: // A privately used function to set the executable RAM space to something invalid. // For debugging usefulness it should be used to set the RAM to a host specific breakpoint instruction virtual void PoisonMemory() = 0; -protected: - u8 *region; - size_t region_size; - public: - CodeBlock() : region(nullptr), region_size(0) {} + CodeBlock() {} virtual ~CodeBlock() { if (region) FreeCodeSpace(); } // Call this before you generate any code. @@ -32,7 +54,7 @@ public: { region_size = size; region = (u8*)AllocateExecutableMemory(region_size); - T::SetCodePtr(region); + T::SetCodePointer(region); } // Always clear code space with breakpoints, so that if someone accidentally executes @@ -55,11 +77,6 @@ public: region_size = 0; } - bool IsInSpace(const u8 *ptr) - { - return (ptr >= region) && (ptr < (region + region_size)); - } - // Cannot currently be undone. Will write protect the entire code region. // Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()). void WriteProtect() @@ -67,22 +84,21 @@ public: WriteProtectMemory(region, region_size, true); } + void SetCodePtr(u8 *ptr) override { + T::SetCodePointer(ptr); + } + + const u8 *GetCodePtr() const override { + return T::GetCodePointer(); + } + void ResetCodePtr() { - T::SetCodePtr(region); + T::SetCodePointer(region); } - size_t GetSpaceLeft() const - { - return region_size - (T::GetCodePtr() - region); - } - - u8 *GetBasePtr() { - return region; - } - - size_t GetOffset(const u8 *ptr) const { - return ptr - region; + size_t GetSpaceLeft() const { + return region_size - (T::GetCodePointer() - region); } }; diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 2fb7c33a0b..cfd26a5698 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -258,12 +258,6 @@ true - - true - true - true - true - true true @@ -332,4 +326,4 @@ - \ No newline at end of file + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 1dcbacabe5..1a8a744b2f 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -104,7 +104,6 @@ Crypto - @@ -151,4 +150,4 @@ {c14d66ef-5f7c-4565-975a-72774e7ccfb9} - \ No newline at end of file + diff --git a/Common/Thunk.h b/Common/Thunk.h index 101ea84a8d..4e5feffd87 100644 --- a/Common/Thunk.h +++ b/Common/Thunk.h @@ -20,11 +20,7 @@ #include #include "Common.h" -#if defined(ARM) -#include "ArmEmitter.h" -#else #include "x64Emitter.h" -#endif // This simple class creates a wrapper around a C/C++ function that saves all fp state // before entering it, and restores it upon exit. This is required to be able to selectively @@ -32,18 +28,14 @@ // of complexity that it means to protect the generated code from this problem. // This process is called thunking. +// Only used for X86 right now. // There will only ever be one level of thunking on the stack, plus, // we don't want to pollute the stack, so we store away regs somewhere global. // NOT THREAD SAFE. This may only be used from the CPU thread. // Any other thread using this stuff will be FATAL. -#if defined(ARM) -typedef ArmGen::ARMXEmitter ThunkEmitter; -typedef ArmGen::ARMXCodeBlock ThunkCodeBlock; -#else typedef Gen::XEmitter ThunkEmitter; typedef Gen::XCodeBlock ThunkCodeBlock; -#endif class ThunkManager : public ThunkCodeBlock { diff --git a/Common/x64Emitter.cpp b/Common/x64Emitter.cpp index 3839df53b0..489223895f 100644 --- a/Common/x64Emitter.cpp +++ b/Common/x64Emitter.cpp @@ -96,12 +96,12 @@ enum NormalSSEOps }; -void XEmitter::SetCodePtr(u8 *ptr) +void XEmitter::SetCodePointer(u8 *ptr) { code = ptr; } -const u8 *XEmitter::GetCodePtr() const +const u8 *XEmitter::GetCodePointer() const { return code; } @@ -235,7 +235,7 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg, emit->WriteModRM(0, _operandReg, _offsetOrBaseReg); //TODO : add some checks #ifdef _M_X64 - u64 ripAddr = (u64)emit->GetCodePtr() + 4 + extraBytes; + u64 ripAddr = (u64)emit->GetCodePointer() + 4 + extraBytes; s64 distance = (s64)offset - (s64)ripAddr; _assert_msg_(DYNA_REC, (distance < 0x80000000LL && diff --git a/Common/x64Emitter.h b/Common/x64Emitter.h index e78166f9b3..cd7647813d 100644 --- a/Common/x64Emitter.h +++ b/Common/x64Emitter.h @@ -374,12 +374,13 @@ public: void WriteModRM(int mod, int rm, int reg); void WriteSIB(int scale, int index, int base); - void SetCodePtr(u8 *ptr); + void SetCodePointer(u8 *ptr); + const u8 *GetCodePointer() const; + void ReserveCodeSpace(int bytes); const u8 *AlignCode4(); const u8 *AlignCode16(); const u8 *AlignCodePage(); - const u8 *GetCodePtr() const; u8 *GetWritableCodePtr(); void LockFlags() { flags_locked = true; } diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 621678afe2..c7512181cd 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -399,14 +399,14 @@ void ArmJit::Comp_RunBlock(MIPSOpcode op) void ArmJit::LinkBlock(u8 *exitPoint, const u8 *checkedEntry) { ARMXEmitter emit(exitPoint); - u32 op = *((const u32 *)emit.GetCodePtr()); + u32 op = *((const u32 *)emit.GetCodePointer()); bool prelinked = (op & 0xFF000000) == 0xEA000000; // Jump directly to the block, yay. emit.B(checkedEntry); if (!prelinked) { do { - op = *((const u32 *)emit.GetCodePtr()); + op = *((const u32 *)emit.GetCodePointer()); // Overwrite whatever is here with a breakpoint. emit.BKPT(1); // Stop after overwriting the next unconditional branch or BKPT. diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index 29ca61296c..5b59e0bad7 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -59,7 +59,7 @@ op_agent_t agent; const u32 INVALID_EXIT = 0xFFFFFFFF; -JitBlockCache::JitBlockCache(MIPSState *mips, NativeCodeBlock *codeBlock) : +JitBlockCache::JitBlockCache(MIPSState *mips, CodeBlockCommon *codeBlock) : mips_(mips), codeBlock_(codeBlock), blocks_(0), num_blocks_(0) { } diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index 3dc23e6f63..03661b2855 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -23,31 +23,10 @@ #include #include "Common/CommonTypes.h" +#include "Common/CodeBlock.h" #include "Core/MIPS/MIPSAnalyst.h" #include "Core/MIPS/MIPS.h" -#if defined(ARM) -#include "Common/ArmEmitter.h" -namespace ArmGen { class ARMXEmitter; } -typedef ArmGen::ARMXCodeBlock NativeCodeBlock; -#elif defined(ARM64) -#include "Common/Arm64Emitter.h" -namespace Arm64Gen { class ARM64XEmitter; } -typedef Arm64Gen::ARM64CodeBlock NativeCodeBlock; -#elif defined(_M_IX86) || defined(_M_X64) -#include "Common/x64Emitter.h" -namespace Gen { class XEmitter; } -typedef Gen::XCodeBlock NativeCodeBlock; -#elif defined(MIPS) -#include "Common/MipsEmitter.h" -namespace MIPSGen { class MIPSEmitter; } -typedef MIPSGen::MIPSCodeBlock NativeCodeBlock; -#else -#include "Common/FakeEmitter.h" -namespace FakeGen { class FakeXEmitter; } -typedef FakeGen::FakeXCodeBlock NativeCodeBlock; -#endif - #if defined(ARM) || defined(ARM64) const int MAX_JIT_BLOCK_EXITS = 2; #else @@ -109,12 +88,12 @@ typedef void (*CompiledCode)(); class JitBlockCache { public: - JitBlockCache(MIPSState *mips_, NativeCodeBlock *codeBlock); + JitBlockCache(MIPSState *mips_, CodeBlockCommon *codeBlock); ~JitBlockCache(); int AllocateBlock(u32 em_address); // When a proxy block is invalidated, the block located at the rootAddress - void ProxyBlock(u32 rootAddress, u32 startAddress, u32 size, u8 *codePtr); + void ProxyBlock(u32 rootAddress, u32 startAddress, u32 size, const u8 *codePtr); void FinalizeBlock(int block_num, bool block_link); void Clear(); @@ -173,7 +152,7 @@ private: MIPSOpcode GetEmuHackOpForBlock(int block_num) const; MIPSState *mips_; - NativeCodeBlock *codeBlock_; + CodeBlockCommon *codeBlock_; JitBlock *blocks_; std::unordered_multimap proxyBlockMap_; diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index 527c6a2c7d..f3f83b58d3 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -505,7 +505,7 @@ void Jit::LinkBlock(u8 *exitPoint, const u8 *checkedEntry) { XEmitter emit(exitPoint); // Okay, this is a bit ugly, but we check here if it already has a JMP. // That means it doesn't have a full exit to pad with INT 3. - bool prelinked = *emit.GetCodePtr() == 0xE9; + bool prelinked = *emit.GetCodePointer() == 0xE9; emit.JMP(checkedEntry, true); if (!prelinked) { ptrdiff_t actualSize = emit.GetWritableCodePtr() - exitPoint; diff --git a/Qt/Common.pro b/Qt/Common.pro index 6aa505554d..7d2b705f06 100644 --- a/Qt/Common.pro +++ b/Qt/Common.pro @@ -7,8 +7,7 @@ include(Settings.pri) # CPU arm { - SOURCES += $$P/Common/ArmCPUDetect.cpp \ - $$P/Common/ArmThunk.cpp + SOURCES += $$P/Common/ArmCPUDetect.cpp } else:i86 { SOURCES += $$P/Common/ABI.cpp \ diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 6eb9e787c8..8a3c46c084 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -57,7 +57,6 @@ ARCH_FILES := \ $(SRC)/Core/Util/AudioFormatNEON.cpp.neon \ $(SRC)/Common/ArmEmitter.cpp \ $(SRC)/Common/ArmCPUDetect.cpp \ - $(SRC)/Common/ArmThunk.cpp \ $(SRC)/Common/ColorConvNEON.cpp.neon \ $(SRC)/Core/MIPS/ARM/ArmCompALU.cpp \ $(SRC)/Core/MIPS/ARM/ArmCompBranch.cpp \ @@ -102,7 +101,6 @@ ifeq ($(TARGET_ARCH_ABI),armeabi) ARCH_FILES := \ $(SRC)/Common/ArmEmitter.cpp \ $(SRC)/Common/ArmCPUDetect.cpp \ - $(SRC)/Common/ArmThunk.cpp \ $(SRC)/Core/MIPS/ARM/ArmCompALU.cpp \ $(SRC)/Core/MIPS/ARM/ArmCompBranch.cpp \ $(SRC)/Core/MIPS/ARM/ArmCompFPU.cpp \ diff --git a/unittest/TestArm64Emitter.cpp b/unittest/TestArm64Emitter.cpp index e4781a9905..6aea74f0dc 100644 --- a/unittest/TestArm64Emitter.cpp +++ b/unittest/TestArm64Emitter.cpp @@ -10,7 +10,7 @@ static bool CheckLast(Arm64Gen::ARM64XEmitter &emit, const char *comp) { u32 instr; - memcpy(&instr, emit.GetCodePtr() - 4, 4); + memcpy(&instr, emit.GetCodePointer() - 4, 4); char disasm[512]; Arm64Dis(0, instr, disasm, sizeof(disasm), true); EXPECT_EQ_STR(std::string(disasm), std::string(comp)); diff --git a/unittest/TestArmEmitter.cpp b/unittest/TestArmEmitter.cpp index 84b6bee9e0..aa9db3f72a 100644 --- a/unittest/TestArmEmitter.cpp +++ b/unittest/TestArmEmitter.cpp @@ -11,7 +11,7 @@ static bool CheckLast(ArmGen::ARMXEmitter &emit, const char *comp) { u32 instr; - memcpy(&instr, emit.GetCodePtr() - 4, 4); + memcpy(&instr, emit.GetCodePointer() - 4, 4); char disasm[512]; ArmDis(0, instr, disasm, sizeof(disasm), true); EXPECT_EQ_STR(std::string(disasm), std::string(comp)); @@ -227,7 +227,7 @@ bool TestArmEmitter() { //RET(CheckLast(emitter, "eef70a00 VMOV.f32 s1, #112")); - const u8 *codeStart = emitter.GetCodePtr(); + const u8 *codeStart = emitter.GetCodePointer(); MIPSState mips; MIPSComp::JitState js; @@ -269,7 +269,7 @@ bool TestArmEmitter() { fpr.QMapReg(C000, V_Quad, MAP_DIRTY); fpr.FlushAll(); - const u8 *codeEnd = emitter.GetCodePtr(); + const u8 *codeEnd = emitter.GetCodePointer(); DisassembleARMBetween(codeStart, codeEnd); diff --git a/unittest/TestX64Emitter.cpp b/unittest/TestX64Emitter.cpp index 6ff8d0b2c4..6fe2882859 100644 --- a/unittest/TestX64Emitter.cpp +++ b/unittest/TestX64Emitter.cpp @@ -11,13 +11,13 @@ static const u8 *prevStart = NULL; bool CheckLast(Gen::XEmitter &emit, const char *comp) { - auto vec = DisassembleX86(prevStart, emit.GetCodePtr() - prevStart); + auto vec = DisassembleX86(prevStart, emit.GetCodePointer() - prevStart); EXPECT_EQ_STR(vec[0], std::string(comp)); return true; } void PrintLast(Gen::XEmitter &emit) { - for (const u8 *p = prevStart; p < emit.GetCodePtr(); p++) { + for (const u8 *p = prevStart; p < emit.GetCodePointer(); p++) { printf("%02x ", *p); } printf("\n"); @@ -29,11 +29,11 @@ bool TestX64Emitter() { u32 code[512]; XEmitter emitter((u8 *)code); - prevStart = emitter.GetCodePtr(); + prevStart = emitter.GetCodePointer(); emitter.VADDSD(XMM0, XMM1, R(XMM7)); RET(CheckLast(emitter, "vaddsd xmm0, xmm1, xmm7")); - prevStart = emitter.GetCodePtr(); + prevStart = emitter.GetCodePointer(); emitter.VMULSD(XMM0, XMM1, R(XMM7)); RET(CheckLast(emitter, "vmulsd xmm0, xmm1, xmm7")); From ccce19e14a9b6d8d51b691fe933e5e0d81c558ec Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 1 May 2016 18:47:32 +0200 Subject: [PATCH 5/5] Fix accidentally truncated comment. --- Core/MIPS/JitCommon/JitBlockCache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index 03661b2855..7331961d9e 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -92,7 +92,7 @@ public: ~JitBlockCache(); int AllocateBlock(u32 em_address); - // When a proxy block is invalidated, the block located at the rootAddress + // When a proxy block is invalidated, the block located at the rootAddress is invalidated too. void ProxyBlock(u32 rootAddress, u32 startAddress, u32 size, const u8 *codePtr); void FinalizeBlock(int block_num, bool block_link);