diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2b7c3a2d73..cb370df423 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1091,7 +1091,6 @@ elseif(ARM64)
elseif(X86)
set(CoreExtra ${CoreExtra}
Core/MIPS/x86/Asm.cpp
- Core/MIPS/x86/Asm.h
Core/MIPS/x86/CompALU.cpp
Core/MIPS/x86/CompBranch.cpp
Core/MIPS/x86/CompFPU.cpp
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index d84ff688e7..6358eb313a 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -679,7 +679,6 @@
true
true
-
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index c004922624..0752ffdb08 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -666,9 +666,6 @@
MIPS\x86
-
- MIPS\x86
-
MIPS\x86
diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp
index 2e49d4834b..9fa6ceb040 100644
--- a/Core/MIPS/JitCommon/JitBlockCache.cpp
+++ b/Core/MIPS/JitCommon/JitBlockCache.cpp
@@ -46,7 +46,6 @@
#if defined(_M_IX86) || defined(_M_X64)
#include "Common/x64Analyzer.h"
-#include "Core/MIPS/x86/Asm.h"
#endif
// #include "JitBase.h"
@@ -593,7 +592,7 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate) {
// 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->Asm().dispatcher, true);
+ emit.JMP(MIPSComp::jit->GetDispatcher(), true);
#elif defined(ARM64)
diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp
index d96a69ce65..0591f5b286 100644
--- a/Core/MIPS/JitCommon/JitCommon.cpp
+++ b/Core/MIPS/JitCommon/JitCommon.cpp
@@ -154,15 +154,12 @@ const char *ppsspp_resolver(struct ud*,
*offset = addr - (uint64_t)(¤tMIPS->v[0]);
return "mips.v";
}
+
// But these do.
if (MIPSComp::jit->IsInSpace((u8 *)(intptr_t)addr)) {
*offset = addr - (uint64_t)MIPSComp::jit->GetBasePtr();
return "jitcode";
}
- if (MIPSComp::jit->Asm().IsInSpace((u8 *)(intptr_t)addr)) {
- *offset = addr - (uint64_t)MIPSComp::jit->Asm().GetBasePtr();
- return "dispatcher";
- }
return NULL;
}
diff --git a/Core/MIPS/x86/Asm.cpp b/Core/MIPS/x86/Asm.cpp
index 2fb8301397..253a3c2a3d 100644
--- a/Core/MIPS/x86/Asm.cpp
+++ b/Core/MIPS/x86/Asm.cpp
@@ -28,12 +28,16 @@
#include "Common/MemoryUtil.h"
#include "Core/MIPS/JitCommon/JitCommon.h"
-#include "Core/MIPS/x86/Asm.h"
#include "Core/MIPS/x86/Jit.h"
using namespace Gen;
using namespace X64JitConstants;
+extern volatile CoreState coreState;
+
+namespace MIPSComp
+{
+
//TODO - make an option
//#if _DEBUG
static bool enableDebug = false;
@@ -54,25 +58,23 @@ static bool enableDebug = false;
//R14 - Pointer to fpr/gpr regs
//R15 - Pointer to array of block pointers
-extern volatile CoreState coreState;
-
void ImHere() {
DEBUG_LOG(CPU, "JIT Here: %08x", currentMIPS->pc);
}
-void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::JitOptions *jo) {
+void Jit::GenerateFixedCode(JitOptions &jo) {
const u8 *start = AlignCode16();
restoreRoundingMode = AlignCode16(); {
- STMXCSR(M(&mips->temp));
+ STMXCSR(M(&mips_->temp));
// Clear the rounding mode and flush-to-zero bits back to 0.
- AND(32, M(&mips->temp), Imm32(~(7 << 13)));
- LDMXCSR(M(&mips->temp));
+ AND(32, M(&mips_->temp), Imm32(~(7 << 13)));
+ LDMXCSR(M(&mips_->temp));
RET();
}
applyRoundingMode = AlignCode16(); {
- MOV(32, R(EAX), M(&mips->fcr31));
+ MOV(32, R(EAX), M(&mips_->fcr31));
AND(32, R(EAX), Imm32(0x1000003));
// If it's 0, we don't actually bother setting. This is the most common.
@@ -80,7 +82,7 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::
// flush-to-zero disabled.
FixupBranch skip = J_CC(CC_Z);
- STMXCSR(M(&mips->temp));
+ STMXCSR(M(&mips_->temp));
// The MIPS bits don't correspond exactly, so we have to adjust.
// 0 -> 0 (skip2), 1 -> 3, 2 -> 2 (skip2), 3 -> 1
@@ -90,14 +92,14 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::
SetJumpTarget(skip2);
SHL(32, R(EAX), Imm8(13));
- OR(32, M(&mips->temp), R(EAX));
+ OR(32, M(&mips_->temp), R(EAX));
- TEST(32, M(&mips->fcr31), Imm32(1 << 24));
+ TEST(32, M(&mips_->fcr31), Imm32(1 << 24));
FixupBranch skip3 = J_CC(CC_Z);
- OR(32, M(&mips->temp), Imm32(1 << 15));
+ OR(32, M(&mips_->temp), Imm32(1 << 15));
SetJumpTarget(skip3);
- LDMXCSR(M(&mips->temp));
+ LDMXCSR(M(&mips_->temp));
SetJumpTarget(skip);
RET();
}
@@ -105,14 +107,14 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::
updateRoundingMode = AlignCode16(); {
// If it's only ever 0, we don't actually bother applying or restoring it.
// This is the most common situation.
- TEST(32, M(&mips->fcr31), Imm32(0x01000003));
+ TEST(32, M(&mips_->fcr31), Imm32(0x01000003));
FixupBranch skip = J_CC(CC_Z);
#ifdef _M_X64
// TODO: Move the hasSetRounding flag somewhere we can reach it through the context pointer, or something.
- MOV(64, R(RAX), Imm64((uintptr_t)&jit->js.hasSetRounding));
+ MOV(64, R(RAX), Imm64((uintptr_t)&js.hasSetRounding));
MOV(8, MatR(RAX), Imm8(1));
#else
- MOV(8, M(&jit->js.hasSetRounding), Imm8(1));
+ MOV(8, M(&js.hasSetRounding), Imm8(1));
#endif
SetJumpTarget(skip);
@@ -124,20 +126,19 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::
#ifdef _M_X64
// Two statically allocated registers.
MOV(64, R(MEMBASEREG), ImmPtr(Memory::base));
- uintptr_t jitbase = (uintptr_t)jit->GetBasePtr();
- if (jitbase > 0x7FFFFFFFULL)
- {
- MOV(64, R(JITBASEREG), ImmPtr(jit->GetBasePtr()));
- jo->reserveR15ForAsm = true;
+ uintptr_t jitbase = (uintptr_t)GetBasePtr();
+ if (jitbase > 0x7FFFFFFFULL) {
+ MOV(64, R(JITBASEREG), ImmPtr(GetBasePtr()));
+ jo.reserveR15ForAsm = true;
}
#endif
// From the start of the FP reg, a single byte offset can reach all GPR + all FPR (but no VFPUR)
- MOV(PTRBITS, R(CTXREG), ImmPtr(&mips->f[0]));
+ MOV(PTRBITS, R(CTXREG), ImmPtr(&mips_->f[0]));
outerLoop = GetCodePtr();
- jit->RestoreRoundingMode(true, this);
+ RestoreRoundingMode(true);
ABI_CallFunction(reinterpret_cast(&CoreTiming::Advance));
- jit->ApplyRoundingMode(true, this);
+ ApplyRoundingMode(true);
FixupBranch skipToRealDispatch = J(); //skip the sync and compare first time
dispatcherCheckCoreState = GetCodePtr();
@@ -161,7 +162,7 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::
dispatcherNoCheck = GetCodePtr();
- MOV(32, R(EAX), M(&mips->pc));
+ MOV(32, R(EAX), M(&mips_->pc));
dispatcherInEAXNoCheck = GetCodePtr();
#ifdef _M_IX86
@@ -178,14 +179,14 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::
FixupBranch notfound = J_CC(CC_NE);
if (enableDebug)
{
- ADD(32, M(&mips->debugCount), Imm8(1));
+ ADD(32, M(&mips_->debugCount), Imm8(1));
}
//grab from list and jump to it
AND(32, R(EAX), Imm32(MIPS_EMUHACK_VALUE_MASK));
#ifdef _M_IX86
- ADD(32, R(EAX), ImmPtr(jit->GetBasePtr()));
+ ADD(32, R(EAX), ImmPtr(GetBasePtr()));
#elif _M_X64
- if (jo->reserveR15ForAsm)
+ if (jo.reserveR15ForAsm)
ADD(64, R(RAX), R(JITBASEREG));
else
ADD(64, R(EAX), Imm32(jitbase));
@@ -194,9 +195,9 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::
SetJumpTarget(notfound);
//Ok, no block, let's jit
- jit->RestoreRoundingMode(true, this);
+ RestoreRoundingMode(true);
ABI_CallFunction(&MIPSComp::JitAt);
- jit->ApplyRoundingMode(true, this);
+ ApplyRoundingMode(true);
JMP(dispatcherNoCheck, true); // Let's just dispatch again, we'll enter the block since we know it's there.
SetJumpTarget(bail);
@@ -206,12 +207,14 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::
J_CC(CC_Z, outerLoop, true);
SetJumpTarget(badCoreState);
- jit->RestoreRoundingMode(true, this);
+ RestoreRoundingMode(true);
ABI_PopAllCalleeSavedRegsAndAdjustStack();
RET();
breakpointBailout = GetCodePtr();
- jit->RestoreRoundingMode(true, this);
+ RestoreRoundingMode(true);
ABI_PopAllCalleeSavedRegsAndAdjustStack();
RET();
}
+
+} // namespace
\ No newline at end of file
diff --git a/Core/MIPS/x86/Asm.h b/Core/MIPS/x86/Asm.h
deleted file mode 100644
index af841b8256..0000000000
--- a/Core/MIPS/x86/Asm.h
+++ /dev/null
@@ -1,54 +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 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 SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#pragma once
-
-#include "Common/x64Emitter.h"
-#include "Core/MIPS/MIPS.h"
-
-// Runtime generated assembly routines, like the Dispatcher.
-
-namespace MIPSComp {
- class Jit;
- struct JitOptions;
-}
-
-class AsmRoutineManager : public Gen::XCodeBlock {
-private:
- void Generate(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::JitOptions *jo);
-
-public:
- void Init(MIPSState *mips, MIPSComp::Jit *jit, MIPSComp::JitOptions *jo) {
- AllocCodeSpace(8192);
- Generate(mips, jit, jo);
- WriteProtect();
- }
-
- const u8 *enterDispatcher;
-
- const u8 *outerLoop;
- const u8 *dispatcher;
- const u8 *dispatcherCheckCoreState;
- const u8 *dispatcherNoCheck;
- const u8 *dispatcherInEAXNoCheck;
-
- const u8 *breakpointBailout;
-
- const u8 *restoreRoundingMode;
- const u8 *applyRoundingMode;
- const u8 *updateRoundingMode;
-};
diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp
index abb7c2a883..7f14c537af 100644
--- a/Core/MIPS/x86/Jit.cpp
+++ b/Core/MIPS/x86/Jit.cpp
@@ -119,13 +119,13 @@ static void JitLogMiss(MIPSOpcode op)
// JitBlockCache doesn't use this, just stores it.
#pragma warning(disable:4355)
#endif
-Jit::Jit(MIPSState *mips) : blocks(mips, this), mips_(mips)
-{
+Jit::Jit(MIPSState *mips)
+ : blocks(mips, this), mips_(mips) {
blocks.Init();
gpr.SetEmitter(this);
fpr.SetEmitter(this);
AllocCodeSpace(1024 * 1024 * 16);
- asm_.Init(mips, this, &jo);
+ GenerateFixedCode(jo);
safeMemFuncs.Init(&thunks);
js.startDefaultPrefix = mips_->HasDefaultPrefix();
@@ -220,34 +220,29 @@ void Jit::WriteDowncount(int offset)
SUB(32, M(&mips_->downcount), downcount > 127 ? Imm32(downcount) : Imm8(downcount));
}
-void Jit::RestoreRoundingMode(bool force, XEmitter *emitter) {
+void Jit::RestoreRoundingMode(bool force) {
// If the game has never set an interesting rounding mode, we can safely skip this.
if (force || js.hasSetRounding) {
- if (emitter == NULL)
- emitter = this;
- emitter->CALL(asm_.restoreRoundingMode);
+ CALL(restoreRoundingMode);
}
}
-void Jit::ApplyRoundingMode(bool force, XEmitter *emitter) {
+void Jit::ApplyRoundingMode(bool force) {
// If the game has never set an interesting rounding mode, we can safely skip this.
if (force || js.hasSetRounding) {
- if (emitter == NULL)
- emitter = this;
- emitter->CALL(asm_.applyRoundingMode);
+ CALL(applyRoundingMode);
}
}
-void Jit::UpdateRoundingMode(XEmitter *emitter) {
- if (emitter == NULL)
- emitter = this;
- emitter->CALL(asm_.updateRoundingMode);
+void Jit::UpdateRoundingMode() {
+ CALL(updateRoundingMode);
}
void Jit::ClearCache()
{
blocks.Clear();
ClearCodeSpace();
+ GenerateFixedCode(jo);
}
void Jit::InvalidateCache()
@@ -337,7 +332,7 @@ void Jit::Compile(u32 em_address)
void Jit::RunLoopUntil(u64 globalticks)
{
PROFILE_THIS_SCOPE("jit");
- ((void (*)())asm_.enterDispatcher)();
+ ((void (*)())enterDispatcher)();
}
u32 Jit::GetCompilerPC() {
@@ -367,7 +362,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
// 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));
- JMP(asm_.outerLoop, true); // downcount hit zero - go advance.
+ JMP(outerLoop, true); // downcount hit zero - go advance.
SetJumpTarget(skip);
b->normalEntry = GetCodePtr();
@@ -445,15 +440,13 @@ void Jit::AddContinuedBlock(u32 dest)
js.lastContinuedPC = dest;
}
-bool Jit::DescribeCodePtr(const u8 *ptr, std::string &name)
-{
+bool Jit::DescribeCodePtr(const u8 *ptr, std::string &name) {
u32 jitAddr = blocks.GetAddressFromBlockPtr(ptr);
// Returns 0 when it's valid, but unknown.
if (jitAddr == 0)
name = "UnknownOrDeletedBlock";
- else if (jitAddr != (u32)-1)
- {
+ else if (jitAddr != (u32)-1) {
char temp[1024];
const std::string label = symbolMap.GetDescription(jitAddr);
if (!label.empty())
@@ -462,7 +455,7 @@ bool Jit::DescribeCodePtr(const u8 *ptr, std::string &name)
snprintf(temp, sizeof(temp), "%08x", jitAddr);
name = temp;
}
- else if (asm_.IsInSpace(ptr))
+ else if (IsInSpace(ptr))
name = "RunLoopUntil";
else if (thunks.IsInSpace(ptr))
name = "Thunk";
@@ -660,7 +653,7 @@ void Jit::WriteExit(u32 destination, int exit_num)
} else {
// No blocklinking.
MOV(32, M(&mips_->pc), Imm32(destination));
- JMP(asm_.dispatcher, true);
+ JMP(dispatcher, true);
// Normally, exits are 15 bytes (MOV + &pc + dest + JMP + dest) on 64 or 32 bit.
// But just in case we somehow optimized, pad.
@@ -699,8 +692,8 @@ void Jit::WriteExitDestInReg(X64Reg reg)
// Need to set neg flag again.
SUB(32, M(&mips_->downcount), Imm8(0));
if (reg == EAX)
- J_CC(CC_NS, asm_.dispatcherInEAXNoCheck, true);
- JMP(asm_.dispatcher, true);
+ J_CC(CC_NS, dispatcherInEAXNoCheck, true);
+ JMP(dispatcher, true);
SetJumpTarget(tooLow);
SetJumpTarget(tooHigh);
@@ -717,15 +710,15 @@ void Jit::WriteExitDestInReg(X64Reg reg)
}
SUB(32, M(&mips_->downcount), Imm8(0));
- JMP(asm_.dispatcherCheckCoreState, true);
+ JMP(dispatcherCheckCoreState, true);
}
else if (reg == EAX)
{
- J_CC(CC_NS, asm_.dispatcherInEAXNoCheck, true);
- JMP(asm_.dispatcher, true);
+ J_CC(CC_NS, dispatcherInEAXNoCheck, true);
+ JMP(dispatcher, true);
}
else
- JMP(asm_.dispatcher, true);
+ JMP(dispatcher, true);
}
void Jit::WriteSyscallExit()
@@ -736,7 +729,7 @@ void Jit::WriteSyscallExit()
ABI_CallFunction(&JitMemCheckCleanup);
ApplyRoundingMode();
}
- JMP(asm_.dispatcherCheckCoreState, true);
+ JMP(dispatcherCheckCoreState, true);
}
bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset)
@@ -756,7 +749,7 @@ bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset)
ApplyRoundingMode();
// Just to fix the stack.
LOAD_FLAGS;
- JMP(asm_.dispatcherCheckCoreState, true);
+ JMP(dispatcherCheckCoreState, true);
SetJumpTarget(skip);
ApplyRoundingMode();
diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h
index 703be6e341..d5650d19b9 100644
--- a/Core/MIPS/x86/Jit.h
+++ b/Core/MIPS/x86/Jit.h
@@ -20,7 +20,6 @@
#include "Common/CommonTypes.h"
#include "Common/Thunk.h"
#include "Common/x64Emitter.h"
-#include "Core/MIPS/x86/Asm.h"
#if defined(ARM)
#error DO NOT BUILD X86 JIT ON ARM
@@ -156,12 +155,11 @@ public:
void GetVectorRegsPrefixD(u8 *regs, VectorSize sz, int vectorReg);
void EatPrefix() { js.EatPrefix(); }
- void RestoreRoundingMode(bool force = false, XEmitter *emitter = NULL);
- void ApplyRoundingMode(bool force = false, XEmitter *emitter = NULL);
- void UpdateRoundingMode(XEmitter *emitter = NULL);
+ void RestoreRoundingMode(bool force = false);
+ void ApplyRoundingMode(bool force = false);
+ void UpdateRoundingMode();
JitBlockCache *GetBlockCache() { return &blocks; }
- AsmRoutineManager &Asm() { return asm_; }
void ClearCache();
void InvalidateCache();
@@ -171,7 +169,12 @@ public:
}
}
+ const u8 *GetDispatcher() const {
+ return dispatcher;
+ }
+
private:
+ void GenerateFixedCode(JitOptions &jo);
void GetStateAndFlushAll(RegCacheState &state);
void RestoreState(const RegCacheState& state);
void FlushAll();
@@ -295,15 +298,28 @@ private:
GPRRegCache gpr;
FPURegCache fpr;
- AsmRoutineManager asm_;
ThunkManager thunks;
JitSafeMemFuncs safeMemFuncs;
MIPSState *mips_;
+
+ const u8 *enterDispatcher;
+
+ const u8 *outerLoop;
+ const u8 *dispatcher;
+ const u8 *dispatcherCheckCoreState;
+ const u8 *dispatcherNoCheck;
+ const u8 *dispatcherInEAXNoCheck;
+
+ const u8 *breakpointBailout;
+
+ const u8 *restoreRoundingMode;
+ const u8 *applyRoundingMode;
+ const u8 *updateRoundingMode;
+
friend class JitSafeMem;
friend class JitSafeMemFuncs;
- friend class AsmRoutineManager;
};
} // namespace MIPSComp
diff --git a/Core/MIPS/x86/RegCache.cpp b/Core/MIPS/x86/RegCache.cpp
index d93df0b8fd..5a48b290f2 100644
--- a/Core/MIPS/x86/RegCache.cpp
+++ b/Core/MIPS/x86/RegCache.cpp
@@ -23,7 +23,6 @@
#include "Core/MIPS/MIPSTables.h"
#include "Core/MIPS/MIPSAnalyst.h"
#include "Core/MIPS/x86/Jit.h"
-#include "Core/MIPS/x86/Asm.h"
#include "Core/MIPS/x86/RegCache.h"
using namespace Gen;