Merge pull request #8716 from hrydgard/remove-preprocessor-hacks

Remove preprocessor hacks around the JITs
This commit is contained in:
Henrik Rydgård committed 2016-05-01 18:47:59 +02:00
commit b6d7aab8dc
50 files changed
+642 -691

No files matched your search

+1 -3
View File
@@ -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)
@@ -1389,7 +1388,6 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/FileLoaders/RetryingFileLoader.h
Core/MIPS/JitCommon/JitCommon.cpp
Core/MIPS/JitCommon/JitCommon.h
Core/MIPS/JitCommon/NativeJit.h
Core/MIPS/JitCommon/JitBlockCache.cpp
Core/MIPS/JitCommon/JitBlockCache.h
Core/MIPS/JitCommon/JitState.cpp
+5 -5
View File
@@ -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;
+3 -2
View File
@@ -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();
+2 -2
View File
@@ -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;
}
+3 -2
View File
@@ -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();
-74
View File
@@ -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.");
}
+41 -25
View File
@@ -11,20 +11,42 @@
// 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<ARMXEmitter> {}
template<class T> class CodeBlock : public T, NonCopyable
// class JIT : public CodeBlock<ARMXEmitter>, public JitInterface {}
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 T> 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);
}
};
+1 -7
View File
@@ -258,12 +258,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="ArmEmitter.cpp" />
<ClCompile Include="ArmThunk.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="ColorConvNEON.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -332,4 +326,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
+1 -2
View File
@@ -104,7 +104,6 @@
<Filter>Crypto</Filter>
</ClCompile>
<ClCompile Include="ChunkFile.cpp" />
<ClCompile Include="ArmThunk.cpp" />
<ClCompile Include="MipsEmitter.cpp" />
<ClCompile Include="Arm64Emitter.cpp" />
<ClCompile Include="ColorConv.cpp" />
@@ -151,4 +150,4 @@
<UniqueIdentifier>{c14d66ef-5f7c-4565-975a-72774e7ccfb9}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
</Project>
+1 -9
View File
@@ -20,11 +20,7 @@
#include <map>
#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
{
+3 -3
View File
@@ -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 &&
+3 -2
View File
@@ -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; }
+1 -2
View File
@@ -666,7 +666,6 @@
<ClInclude Include="MIPS\ARM\ArmRegCacheFPU.h" />
<ClInclude Include="MIPS\JitCommon\JitBlockCache.h" />
<ClInclude Include="MIPS\JitCommon\JitCommon.h" />
<ClInclude Include="MIPS\JitCommon\NativeJit.h" />
<ClInclude Include="MIPS\JitCommon\JitState.h" />
<ClInclude Include="MIPS\MIPS.h" />
<ClInclude Include="MIPS\MIPSAnalyst.h" />
@@ -737,4 +736,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
-3
View File
@@ -678,9 +678,6 @@
<ClInclude Include="MIPS\JitCommon\JitCommon.h">
<Filter>MIPS\JitCommon</Filter>
</ClInclude>
<ClInclude Include="MIPS\JitCommon\NativeJit.h">
<Filter>MIPS\JitCommon</Filter>
</ClInclude>
<ClInclude Include="FileSystems\DirectoryFileSystem.h">
<Filter>FileSystems</Filter>
</ClInclude>
+1 -1
View File
@@ -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"
+4 -2
View File
@@ -15,14 +15,16 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <cstdio>
#include "Common/Log.h"
#include "Core/Core.h"
#include "Core/Debugger/Breakpoints.h"
#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"
#include <cstdio>
std::vector<BreakPoint> CBreakPoints::breakPoints_;
u32 CBreakPoints::breakSkipFirstAt_ = 0;
+1 -11
View File
@@ -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[] = {
+1 -1
View File
@@ -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)();
+34 -3
View File
@@ -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.GetCodePointer());
bool prelinked = (op & 0xFF000000) == 0xEA000000;
// Jump directly to the block, yay.
emit.B(checkedEntry);
if (!prelinked) {
do {
op = *((const u32 *)emit.GetCodePointer());
// 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;
+85 -76
View File
@@ -22,6 +22,7 @@
#include "Common/ArmEmitter.h"
#include "Core/MIPS/JitCommon/JitState.h"
#include "Core/MIPS/JitCommon/JitBlockCache.h"
#include "Core/MIPS/JitCommon/JitCommon.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,24 @@ 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;
}
void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override;
void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override;
private:
const u8 *DoJit(u32 em_address, JitBlock *b);
void GenerateFixedCode();
void FlushAll();
void FlushPrefixV();
+21 -3
View File
@@ -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;
+78 -70
View File
@@ -22,6 +22,7 @@
#include "Common/Arm64Emitter.h"
#include "Core/MIPS/JitCommon/JitState.h"
#include "Core/MIPS/JitCommon/JitBlockCache.h"
#include "Core/MIPS/JitCommon/JitCommon.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,13 @@ public:
void EatPrefix() { js.EatPrefix(); }
const u8 *GetDispatcher() const override {
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();
+4 -88
View File
@@ -42,11 +42,7 @@
#include "Core/MIPS/JitCommon/JitBlockCache.h"
#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,19 +57,9 @@ op_agent_t agent;
#pragma comment(lib, "jitprofiling.lib")
#endif
#ifdef ARM
using namespace ArmGen;
using namespace ArmJitConstants;
#elif defined(_M_X64) || defined(_M_IX86)
using namespace Gen;
#elif defined(ARM64)
using namespace Arm64Gen;
using namespace Arm64JitConstants;
#endif
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) {
}
@@ -196,7 +182,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_);
@@ -414,46 +400,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
}
}
}
@@ -586,39 +534,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->dispatcher);
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->dispatcher);
emit.FlushIcache();
#endif
MIPSComp::jit->UnlinkBlock(b->checkedEntry, b->originalAddress);
}
void JitBlockCache::InvalidateICache(u32 address, const u32 length) {
+5 -27
View File
@@ -23,31 +23,10 @@
#include <string>
#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
@@ -73,7 +52,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
@@ -109,12 +88,11 @@ 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
// is invalidated too.
// 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);
@@ -174,7 +152,7 @@ private:
MIPSOpcode GetEmuHackOpForBlock(int block_num) const;
MIPSState *mips_;
NativeCodeBlock *codeBlock_;
CodeBlockCommon *codeBlock_;
JitBlock *blocks_;
std::unordered_multimap<u32, int> proxyBlockMap_;
+35 -18
View File
@@ -15,36 +15,53 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <stdlib.h>
#include "Core/MIPS/JitCommon/JitCommon.h"
#include "Core/MIPS/JitCommon/NativeJit.h"
#include "Common/StringUtils.h"
#include <cstdlib>
#include "ext/disarm.h"
#include "ext/udis86/udis86.h"
#include "Common/StringUtils.h"
#include "Core/Util/DisArm64.h"
#if (defined(_M_IX86) || defined(_M_X64)) && defined(_WIN32)
#define DISASM_ALL 1
#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 {
#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
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
#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.
+109 -1
View File
@@ -21,12 +21,120 @@
#include <string>
#include "Common/Common.h"
#include "Common/CommonTypes.h"
#include "Core/MIPS/MIPS.h"
// TODO: Find a better place for these.
std::vector<std::string> DisassembleArm2(const u8 *data, int size);
std::vector<std::string> DisassembleArm64(const u8 *data, int size);
std::vector<std::string> 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();
}
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);
}
+4
View File
@@ -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;
};
}
-48
View File
@@ -1,48 +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
struct JitBlock;
#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
namespace MIPSComp {
extern NativeJit *jit;
typedef void (NativeJit::*MIPSCompileFunc)(MIPSOpcode opcode);
typedef int (NativeJit::*MIPSReplaceFunc)();
}
+2 -24
View File
@@ -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;
@@ -209,17 +207,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 +227,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;
+68 -68
View File
@@ -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) {}
+1
View File
@@ -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"
+1 -1
View File
@@ -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
+2 -12
View File
@@ -29,7 +29,7 @@
#include "Core/Reporting.h"
#include "Core/Debugger/Breakpoints.h"
#include "JitCommon/NativeJit.h"
#include "JitCommon/JitCommon.h"
enum MipsEncoding {
Imme,
@@ -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;
+1 -1
View File
@@ -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();
-3
View File
@@ -178,8 +178,5 @@ public:
const u8 *breakpointBailout;
};
typedef void (FakeJit::*MIPSCompileFunc)(MIPSOpcode opcode);
typedef int (FakeJit::*MIPSReplaceFunc)();
} // namespace MIPSComp
+2 -1
View File
@@ -16,8 +16,9 @@
// 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"
static const u64 MEMORY_ALIGNED16(ssNoSignMask[2]) = {0x7FFFFFFF7FFFFFFFULL, 0x7FFFFFFF7FFFFFFFULL};
+25 -1
View File
@@ -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.GetCodePointer() == 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;
+77 -73
View File
@@ -28,6 +28,7 @@
#include "Common/x64Emitter.h"
#include "Core/MIPS/JitCommon/JitBlockCache.h"
#include "Core/MIPS/JitCommon/JitState.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"
@@ -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,17 +163,20 @@ 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;
}
void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override;
void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override;
private:
void GenerateFixedCode(JitOptions &jo);
void GetStateAndFlushAll(RegCacheState &state);
+1
View File
@@ -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 {
+1
View File
@@ -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"
+1 -2
View File
@@ -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 \
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -34,7 +34,7 @@
#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"
#include "GPU/GPUState.h"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
-2
View File
@@ -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 \
+1 -1
View File
@@ -21,7 +21,7 @@
#include "base/NativeApp.h"
#include "input/input_state.h"
#include "Core/MIPS/JitCommon/JitCommon.h"
#include "Core/MIPS/JitCommon/NativeJit.h"
#include "Core/MIPS/JitCommon/JitBlockCache.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/MIPS/MIPSDebugInterface.h"
#include "Core/MIPS/MIPSAsm.h"
+1 -1
View File
@@ -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));
+3 -3
View File
@@ -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);
+4 -4
View File
@@ -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"));