mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-26 19:58:36 +01:00
Merge pull request #8716 from hrydgard/remove-preprocessor-hacks
Remove preprocessor hacks around the JITs
This commit is contained in:
commit
b6d7aab8dc
50 files changed
+642
-691
No files matched your search
+1
-3
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
@@ -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
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
@@ -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>
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
@@ -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)();
|
||||
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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) {}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -178,8 +178,5 @@ public:
|
||||
const u8 *breakpointBailout;
|
||||
};
|
||||
|
||||
typedef void (FakeJit::*MIPSCompileFunc)(MIPSOpcode opcode);
|
||||
typedef int (FakeJit::*MIPSReplaceFunc)();
|
||||
|
||||
} // namespace MIPSComp
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
@@ -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 \
|
||||
|
||||
@@ -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
@@ -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
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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"));
|
||||
|
||||
|
||||
Reference in new issue
Block a user