mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
JitArm64/Jit64: Load the memory register without jumps and only when necessary.
This commit is contained in:
parent
17fa9dfc4e
commit
8bfcd2deb7
@ -490,6 +490,21 @@ void Jit64::FakeBLCall(u32 after)
|
|||||||
SetJumpTarget(skip_exit);
|
SetJumpTarget(skip_exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Jit64::EmitUpdateMembase()
|
||||||
|
{
|
||||||
|
MOV(64, R(RMEM), PPCSTATE(mem_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit64::EmitStoreMembase(const OpArg& msr, X64Reg scratch_reg)
|
||||||
|
{
|
||||||
|
auto& memory = m_system.GetMemory();
|
||||||
|
MOV(64, R(RMEM), ImmPtr(memory.GetLogicalBase()));
|
||||||
|
MOV(64, R(scratch_reg), ImmPtr(memory.GetPhysicalBase()));
|
||||||
|
TEST(32, msr, Imm32(1 << (31 - 27)));
|
||||||
|
CMOVcc(64, RMEM, R(scratch_reg), CC_Z);
|
||||||
|
MOV(64, PPCSTATE(mem_ptr), R(RMEM));
|
||||||
|
}
|
||||||
|
|
||||||
void Jit64::WriteExit(u32 destination, bool bl, u32 after)
|
void Jit64::WriteExit(u32 destination, bool bl, u32 after)
|
||||||
{
|
{
|
||||||
if (!m_enable_blr_optimization)
|
if (!m_enable_blr_optimization)
|
||||||
@ -599,6 +614,7 @@ void Jit64::WriteRfiExitDestInRSCRATCH()
|
|||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunctionP(PowerPC::CheckExceptionsFromJIT, &m_system.GetPowerPC());
|
ABI_CallFunctionP(PowerPC::CheckExceptionsFromJIT, &m_system.GetPowerPC());
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
|
EmitUpdateMembase();
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, Jump::Near);
|
JMP(asm_routines.dispatcher, Jump::Near);
|
||||||
}
|
}
|
||||||
@ -620,6 +636,7 @@ void Jit64::WriteExceptionExit()
|
|||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunctionP(PowerPC::CheckExceptionsFromJIT, &m_system.GetPowerPC());
|
ABI_CallFunctionP(PowerPC::CheckExceptionsFromJIT, &m_system.GetPowerPC());
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
|
EmitUpdateMembase();
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, Jump::Near);
|
JMP(asm_routines.dispatcher, Jump::Near);
|
||||||
}
|
}
|
||||||
@ -632,6 +649,7 @@ void Jit64::WriteExternalExceptionExit()
|
|||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunctionP(PowerPC::CheckExternalExceptionsFromJIT, &m_system.GetPowerPC());
|
ABI_CallFunctionP(PowerPC::CheckExternalExceptionsFromJIT, &m_system.GetPowerPC());
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
|
EmitUpdateMembase();
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, Jump::Near);
|
JMP(asm_routines.dispatcher, Jump::Near);
|
||||||
}
|
}
|
||||||
@ -639,6 +657,7 @@ void Jit64::WriteExternalExceptionExit()
|
|||||||
void Jit64::Run()
|
void Jit64::Run()
|
||||||
{
|
{
|
||||||
ProtectStack();
|
ProtectStack();
|
||||||
|
m_system.GetJitInterface().UpdateMembase();
|
||||||
|
|
||||||
CompiledCode pExecAddr = (CompiledCode)asm_routines.enter_code;
|
CompiledCode pExecAddr = (CompiledCode)asm_routines.enter_code;
|
||||||
pExecAddr();
|
pExecAddr();
|
||||||
@ -649,6 +668,7 @@ void Jit64::Run()
|
|||||||
void Jit64::SingleStep()
|
void Jit64::SingleStep()
|
||||||
{
|
{
|
||||||
ProtectStack();
|
ProtectStack();
|
||||||
|
m_system.GetJitInterface().UpdateMembase();
|
||||||
|
|
||||||
CompiledCode pExecAddr = (CompiledCode)asm_routines.enter_code;
|
CompiledCode pExecAddr = (CompiledCode)asm_routines.enter_code;
|
||||||
pExecAddr();
|
pExecAddr();
|
||||||
@ -745,6 +765,7 @@ void Jit64::Jit(u32 em_address, bool clear_cache_and_retry_on_failure)
|
|||||||
m_ppc_state.npc = nextPC;
|
m_ppc_state.npc = nextPC;
|
||||||
m_ppc_state.Exceptions |= EXCEPTION_ISI;
|
m_ppc_state.Exceptions |= EXCEPTION_ISI;
|
||||||
m_system.GetPowerPC().CheckExceptions();
|
m_system.GetPowerPC().CheckExceptions();
|
||||||
|
m_system.GetJitInterface().UpdateMembase();
|
||||||
WARN_LOG_FMT(POWERPC, "ISI exception at {:#010x}", nextPC);
|
WARN_LOG_FMT(POWERPC, "ISI exception at {:#010x}", nextPC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,8 @@ public:
|
|||||||
|
|
||||||
// Utilities for use by opcodes
|
// Utilities for use by opcodes
|
||||||
|
|
||||||
|
void EmitUpdateMembase();
|
||||||
|
void EmitStoreMembase(const Gen::OpArg& msr, Gen::X64Reg scratch_reg);
|
||||||
void FakeBLCall(u32 after);
|
void FakeBLCall(u32 after);
|
||||||
void WriteExit(u32 destination, bool bl = false, u32 after = 0);
|
void WriteExit(u32 destination, bool bl = false, u32 after = 0);
|
||||||
void JustWriteExit(u32 destination, bool bl, u32 after);
|
void JustWriteExit(u32 destination, bool bl, u32 after);
|
||||||
|
@ -65,6 +65,11 @@ void Jit64AsmRoutineManager::Generate()
|
|||||||
ABI_CallFunction(CoreTiming::GlobalAdvance);
|
ABI_CallFunction(CoreTiming::GlobalAdvance);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
|
|
||||||
|
// When we've just entered the jit we need to update the membase
|
||||||
|
// GlobalAdvance also checks exceptions after which we need to
|
||||||
|
// update the membase so it makes sense to do this here.
|
||||||
|
m_jit.EmitUpdateMembase();
|
||||||
|
|
||||||
// skip the sync and compare first time
|
// skip the sync and compare first time
|
||||||
FixupBranch skipToRealDispatch = J(enable_debugging ? Jump::Near : Jump::Short);
|
FixupBranch skipToRealDispatch = J(enable_debugging ? Jump::Near : Jump::Short);
|
||||||
|
|
||||||
@ -104,8 +109,6 @@ void Jit64AsmRoutineManager::Generate()
|
|||||||
|
|
||||||
dispatcher_no_check = GetCodePtr();
|
dispatcher_no_check = GetCodePtr();
|
||||||
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
|
|
||||||
// The following is a translation of JitBaseBlockCache::Dispatch into assembly.
|
// The following is a translation of JitBaseBlockCache::Dispatch into assembly.
|
||||||
const bool assembly_dispatcher = true;
|
const bool assembly_dispatcher = true;
|
||||||
if (assembly_dispatcher)
|
if (assembly_dispatcher)
|
||||||
@ -165,13 +168,6 @@ void Jit64AsmRoutineManager::Generate()
|
|||||||
FixupBranch state_mismatch = J_CC(CC_NE);
|
FixupBranch state_mismatch = J_CC(CC_NE);
|
||||||
|
|
||||||
// Success; branch to the block we found.
|
// Success; branch to the block we found.
|
||||||
// Switch to the correct memory base, in case MSR.DR has changed.
|
|
||||||
TEST(32, PPCSTATE(msr), Imm32(1 << (31 - 27)));
|
|
||||||
FixupBranch physmem = J_CC(CC_Z);
|
|
||||||
MOV(64, R(RMEM), ImmPtr(memory.GetLogicalBase()));
|
|
||||||
JMPptr(MDisp(RSCRATCH, static_cast<s32>(offsetof(JitBlockData, normalEntry))));
|
|
||||||
SetJumpTarget(physmem);
|
|
||||||
MOV(64, R(RMEM), ImmPtr(memory.GetPhysicalBase()));
|
|
||||||
JMPptr(MDisp(RSCRATCH, static_cast<s32>(offsetof(JitBlockData, normalEntry))));
|
JMPptr(MDisp(RSCRATCH, static_cast<s32>(offsetof(JitBlockData, normalEntry))));
|
||||||
|
|
||||||
SetJumpTarget(not_found);
|
SetJumpTarget(not_found);
|
||||||
@ -189,13 +185,7 @@ void Jit64AsmRoutineManager::Generate()
|
|||||||
TEST(64, R(ABI_RETURN), R(ABI_RETURN));
|
TEST(64, R(ABI_RETURN), R(ABI_RETURN));
|
||||||
FixupBranch no_block_available = J_CC(CC_Z);
|
FixupBranch no_block_available = J_CC(CC_Z);
|
||||||
|
|
||||||
// Switch to the correct memory base, in case MSR.DR has changed.
|
// Jump to the block
|
||||||
TEST(32, PPCSTATE(msr), Imm32(1 << (31 - 27)));
|
|
||||||
FixupBranch physmem = J_CC(CC_Z);
|
|
||||||
MOV(64, R(RMEM), ImmPtr(memory.GetLogicalBase()));
|
|
||||||
JMPptr(R(ABI_RETURN));
|
|
||||||
SetJumpTarget(physmem);
|
|
||||||
MOV(64, R(RMEM), ImmPtr(memory.GetPhysicalBase()));
|
|
||||||
JMPptr(R(ABI_RETURN));
|
JMPptr(R(ABI_RETURN));
|
||||||
|
|
||||||
SetJumpTarget(no_block_available);
|
SetJumpTarget(no_block_available);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
|
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
|
||||||
#include "Core/PowerPC/PPCAnalyst.h"
|
#include "Core/PowerPC/PPCAnalyst.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
// The branches are known good, or at least reasonably good.
|
// The branches are known good, or at least reasonably good.
|
||||||
// No need for a disable-mechanism.
|
// No need for a disable-mechanism.
|
||||||
@ -54,6 +55,9 @@ void Jit64::rfi(UGeckoInstruction inst)
|
|||||||
MOV(32, R(RSCRATCH), PPCSTATE_SRR1);
|
MOV(32, R(RSCRATCH), PPCSTATE_SRR1);
|
||||||
AND(32, R(RSCRATCH), Imm32(mask & clearMSR13));
|
AND(32, R(RSCRATCH), Imm32(mask & clearMSR13));
|
||||||
OR(32, PPCSTATE(msr), R(RSCRATCH));
|
OR(32, PPCSTATE(msr), R(RSCRATCH));
|
||||||
|
|
||||||
|
EmitStoreMembase(R(RSCRATCH), RSCRATCH2);
|
||||||
|
|
||||||
// NPC = SRR0;
|
// NPC = SRR0;
|
||||||
MOV(32, R(RSCRATCH), PPCSTATE_SRR0);
|
MOV(32, R(RSCRATCH), PPCSTATE_SRR0);
|
||||||
WriteRfiExitDestInRSCRATCH();
|
WriteRfiExitDestInRSCRATCH();
|
||||||
|
@ -438,7 +438,10 @@ void Jit64::mtmsr(UGeckoInstruction inst)
|
|||||||
RCOpArg Rs = gpr.BindOrImm(inst.RS, RCMode::Read);
|
RCOpArg Rs = gpr.BindOrImm(inst.RS, RCMode::Read);
|
||||||
RegCache::Realize(Rs);
|
RegCache::Realize(Rs);
|
||||||
MOV(32, PPCSTATE(msr), Rs);
|
MOV(32, PPCSTATE(msr), Rs);
|
||||||
|
|
||||||
|
EmitStoreMembase(PPCSTATE(msr), RSCRATCH2);
|
||||||
}
|
}
|
||||||
|
|
||||||
gpr.Flush();
|
gpr.Flush();
|
||||||
fpr.Flush();
|
fpr.Flush();
|
||||||
|
|
||||||
|
@ -127,8 +127,11 @@ bool JitArm64::HandleFault(uintptr_t access_address, SContext* ctx)
|
|||||||
{
|
{
|
||||||
ERROR_LOG_FMT(DYNA_REC,
|
ERROR_LOG_FMT(DYNA_REC,
|
||||||
"JitArm64 address calculation overflowed. This should never happen! "
|
"JitArm64 address calculation overflowed. This should never happen! "
|
||||||
"PC {:#018x}, access address {:#018x}, memory base {:#018x}, MSR.DR {}",
|
"PC {:#018x}, access address {:#018x}, memory base {:#018x}, MSR.DR {}, "
|
||||||
ctx->CTX_PC, access_address, memory_base, m_ppc_state.msr.DR);
|
"mem_ptr {}, pbase {}, lbase {}",
|
||||||
|
ctx->CTX_PC, access_address, memory_base, m_ppc_state.msr.DR,
|
||||||
|
fmt::ptr(m_ppc_state.mem_ptr), fmt::ptr(memory.GetPhysicalBase()),
|
||||||
|
fmt::ptr(memory.GetLogicalBase()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -353,6 +356,24 @@ void JitArm64::IntializeSpeculativeConstants()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm64::EmitUpdateMembase()
|
||||||
|
{
|
||||||
|
LDR(IndexType::Unsigned, MEM_REG, PPC_REG, PPCSTATE_OFF(mem_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitArm64::EmitStoreMembase(const ARM64Reg& msr)
|
||||||
|
{
|
||||||
|
auto& memory = m_system.GetMemory();
|
||||||
|
ARM64Reg WD = gpr.GetReg();
|
||||||
|
ARM64Reg XD = EncodeRegTo64(WD);
|
||||||
|
MOVP2R(MEM_REG, jo.fastmem_arena ? memory.GetLogicalBase() : memory.GetLogicalPageMappingsBase());
|
||||||
|
MOVP2R(XD, jo.fastmem_arena ? memory.GetPhysicalBase() : memory.GetPhysicalPageMappingsBase());
|
||||||
|
TST(msr, LogicalImm(1 << (31 - 27), 32));
|
||||||
|
CSEL(MEM_REG, MEM_REG, XD, CCFlags::CC_NEQ);
|
||||||
|
STR(IndexType::Unsigned, MEM_REG, PPC_REG, PPCSTATE_OFF(mem_ptr));
|
||||||
|
gpr.Unlock(WD);
|
||||||
|
}
|
||||||
|
|
||||||
void JitArm64::WriteExit(u32 destination, bool LK, u32 exit_address_after_return)
|
void JitArm64::WriteExit(u32 destination, bool LK, u32 exit_address_after_return)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
@ -523,6 +544,7 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external, bool always
|
|||||||
else
|
else
|
||||||
MOVP2R(EncodeRegTo64(DISPATCHER_PC), &PowerPC::CheckExceptionsFromJIT);
|
MOVP2R(EncodeRegTo64(DISPATCHER_PC), &PowerPC::CheckExceptionsFromJIT);
|
||||||
BLR(EncodeRegTo64(DISPATCHER_PC));
|
BLR(EncodeRegTo64(DISPATCHER_PC));
|
||||||
|
EmitUpdateMembase();
|
||||||
|
|
||||||
LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
|
LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
|
||||||
|
|
||||||
@ -636,6 +658,7 @@ void JitArm64::EndTimeProfile(JitBlock* b)
|
|||||||
void JitArm64::Run()
|
void JitArm64::Run()
|
||||||
{
|
{
|
||||||
ProtectStack();
|
ProtectStack();
|
||||||
|
m_system.GetJitInterface().UpdateMembase();
|
||||||
|
|
||||||
CompiledCode pExecAddr = (CompiledCode)enter_code;
|
CompiledCode pExecAddr = (CompiledCode)enter_code;
|
||||||
pExecAddr();
|
pExecAddr();
|
||||||
@ -646,6 +669,7 @@ void JitArm64::Run()
|
|||||||
void JitArm64::SingleStep()
|
void JitArm64::SingleStep()
|
||||||
{
|
{
|
||||||
ProtectStack();
|
ProtectStack();
|
||||||
|
m_system.GetJitInterface().UpdateMembase();
|
||||||
|
|
||||||
CompiledCode pExecAddr = (CompiledCode)enter_code;
|
CompiledCode pExecAddr = (CompiledCode)enter_code;
|
||||||
pExecAddr();
|
pExecAddr();
|
||||||
@ -747,6 +771,7 @@ void JitArm64::Jit(u32 em_address, bool clear_cache_and_retry_on_failure)
|
|||||||
m_ppc_state.npc = nextPC;
|
m_ppc_state.npc = nextPC;
|
||||||
m_ppc_state.Exceptions |= EXCEPTION_ISI;
|
m_ppc_state.Exceptions |= EXCEPTION_ISI;
|
||||||
m_system.GetPowerPC().CheckExceptions();
|
m_system.GetPowerPC().CheckExceptions();
|
||||||
|
m_system.GetJitInterface().UpdateMembase();
|
||||||
WARN_LOG_FMT(POWERPC, "ISI exception at {:#010x}", nextPC);
|
WARN_LOG_FMT(POWERPC, "ISI exception at {:#010x}", nextPC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -311,6 +311,9 @@ protected:
|
|||||||
void BeginTimeProfile(JitBlock* b);
|
void BeginTimeProfile(JitBlock* b);
|
||||||
void EndTimeProfile(JitBlock* b);
|
void EndTimeProfile(JitBlock* b);
|
||||||
|
|
||||||
|
void EmitUpdateMembase();
|
||||||
|
void EmitStoreMembase(const Arm64Gen::ARM64Reg& msr);
|
||||||
|
|
||||||
// Exits
|
// Exits
|
||||||
void WriteExit(u32 destination, bool LK = false, u32 exit_address_after_return = 0);
|
void WriteExit(u32 destination, bool LK = false, u32 exit_address_after_return = 0);
|
||||||
void WriteExit(Arm64Gen::ARM64Reg dest, bool LK = false, u32 exit_address_after_return = 0);
|
void WriteExit(Arm64Gen::ARM64Reg dest, bool LK = false, u32 exit_address_after_return = 0);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
@ -64,6 +65,8 @@ void JitArm64::rfi(UGeckoInstruction inst)
|
|||||||
|
|
||||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(msr)); // STR rB in to rA
|
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(msr)); // STR rB in to rA
|
||||||
|
|
||||||
|
EmitStoreMembase(WA);
|
||||||
|
|
||||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF_SPR(SPR_SRR0));
|
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF_SPR(SPR_SRR0));
|
||||||
gpr.Unlock(WB, WC);
|
gpr.Unlock(WB, WC);
|
||||||
|
|
||||||
|
@ -94,6 +94,8 @@ void JitArm64::mtmsr(UGeckoInstruction inst)
|
|||||||
gpr.BindToRegister(inst.RS, true);
|
gpr.BindToRegister(inst.RS, true);
|
||||||
STR(IndexType::Unsigned, gpr.R(inst.RS), PPC_REG, PPCSTATE_OFF(msr));
|
STR(IndexType::Unsigned, gpr.R(inst.RS), PPC_REG, PPCSTATE_OFF(msr));
|
||||||
|
|
||||||
|
EmitStoreMembase(gpr.R(inst.RS));
|
||||||
|
|
||||||
gpr.Flush(FlushMode::All, ARM64Reg::INVALID_REG);
|
gpr.Flush(FlushMode::All, ARM64Reg::INVALID_REG);
|
||||||
fpr.Flush(FlushMode::All, ARM64Reg::INVALID_REG);
|
fpr.Flush(FlushMode::All, ARM64Reg::INVALID_REG);
|
||||||
|
|
||||||
|
@ -95,26 +95,13 @@ void JitArm64::GenerateAsm()
|
|||||||
|
|
||||||
bool assembly_dispatcher = true;
|
bool assembly_dispatcher = true;
|
||||||
|
|
||||||
auto& memory = m_system.GetMemory();
|
|
||||||
|
|
||||||
if (assembly_dispatcher)
|
if (assembly_dispatcher)
|
||||||
{
|
{
|
||||||
// set the mem_base based on MSR flags
|
|
||||||
LDR(IndexType::Unsigned, ARM64Reg::W28, PPC_REG, PPCSTATE_OFF(msr));
|
|
||||||
FixupBranch physmem = TBNZ(ARM64Reg::W28, 31 - 27);
|
|
||||||
MOVP2R(MEM_REG,
|
|
||||||
jo.fastmem_arena ? memory.GetPhysicalBase() : memory.GetPhysicalPageMappingsBase());
|
|
||||||
FixupBranch membaseend = B();
|
|
||||||
SetJumpTarget(physmem);
|
|
||||||
MOVP2R(MEM_REG,
|
|
||||||
jo.fastmem_arena ? memory.GetLogicalBase() : memory.GetLogicalPageMappingsBase());
|
|
||||||
SetJumpTarget(membaseend);
|
|
||||||
|
|
||||||
if (GetBlockCache()->GetFastBlockMap())
|
if (GetBlockCache()->GetFastBlockMap())
|
||||||
{
|
{
|
||||||
// Check if there is a block
|
// Check if there is a block
|
||||||
ARM64Reg pc_masked = ARM64Reg::X25;
|
ARM64Reg pc_masked = ARM64Reg::X25;
|
||||||
ARM64Reg cache_base = ARM64Reg::X27;
|
ARM64Reg cache_base = ARM64Reg::X24;
|
||||||
ARM64Reg block = ARM64Reg::X30;
|
ARM64Reg block = ARM64Reg::X30;
|
||||||
LSL(pc_masked, DISPATCHER_PC, 1);
|
LSL(pc_masked, DISPATCHER_PC, 1);
|
||||||
MOVP2R(cache_base, GetBlockCache()->GetFastBlockMap());
|
MOVP2R(cache_base, GetBlockCache()->GetFastBlockMap());
|
||||||
@ -122,7 +109,7 @@ void JitArm64::GenerateAsm()
|
|||||||
FixupBranch not_found = CBZ(block);
|
FixupBranch not_found = CBZ(block);
|
||||||
|
|
||||||
// b.msrBits != msr
|
// b.msrBits != msr
|
||||||
ARM64Reg msr = ARM64Reg::W25;
|
ARM64Reg msr = ARM64Reg::W27;
|
||||||
ARM64Reg msr2 = ARM64Reg::W24;
|
ARM64Reg msr2 = ARM64Reg::W24;
|
||||||
LDR(IndexType::Unsigned, msr, PPC_REG, PPCSTATE_OFF(msr));
|
LDR(IndexType::Unsigned, msr, PPC_REG, PPCSTATE_OFF(msr));
|
||||||
AND(msr, msr, LogicalImm(JitBaseBlockCache::JIT_CACHE_MSR_MASK, 32));
|
AND(msr, msr, LogicalImm(JitBaseBlockCache::JIT_CACHE_MSR_MASK, 32));
|
||||||
@ -181,14 +168,6 @@ void JitArm64::GenerateAsm()
|
|||||||
|
|
||||||
FixupBranch no_block_available = CBZ(ARM64Reg::X0);
|
FixupBranch no_block_available = CBZ(ARM64Reg::X0);
|
||||||
|
|
||||||
// set the mem_base based on MSR flags and jump to next block.
|
|
||||||
LDR(IndexType::Unsigned, ARM64Reg::W28, PPC_REG, PPCSTATE_OFF(msr));
|
|
||||||
FixupBranch physmem = TBNZ(ARM64Reg::W28, 31 - 27);
|
|
||||||
MOVP2R(MEM_REG,
|
|
||||||
jo.fastmem_arena ? memory.GetPhysicalBase() : memory.GetPhysicalPageMappingsBase());
|
|
||||||
BR(ARM64Reg::X0);
|
|
||||||
SetJumpTarget(physmem);
|
|
||||||
MOVP2R(MEM_REG, jo.fastmem_arena ? memory.GetLogicalBase() : memory.GetLogicalPageMappingsBase());
|
|
||||||
BR(ARM64Reg::X0);
|
BR(ARM64Reg::X0);
|
||||||
|
|
||||||
// Call JIT
|
// Call JIT
|
||||||
@ -217,6 +196,11 @@ void JitArm64::GenerateAsm()
|
|||||||
MOVP2R(ARM64Reg::X8, &CoreTiming::GlobalAdvance);
|
MOVP2R(ARM64Reg::X8, &CoreTiming::GlobalAdvance);
|
||||||
BLR(ARM64Reg::X8);
|
BLR(ARM64Reg::X8);
|
||||||
|
|
||||||
|
// When we've just entered the jit we need to update the membase
|
||||||
|
// GlobalAdvance also checks exceptions after which we need to
|
||||||
|
// update the membase so it makes sense to do this here.
|
||||||
|
EmitUpdateMembase();
|
||||||
|
|
||||||
// Load the PC back into DISPATCHER_PC (the exception handler might have changed it)
|
// Load the PC back into DISPATCHER_PC (the exception handler might have changed it)
|
||||||
LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||||
|
|
||||||
|
@ -98,6 +98,25 @@ void JitInterface::SetProfilingState(ProfilingState state)
|
|||||||
m_jit->jo.profile_blocks = state == ProfilingState::Enabled;
|
m_jit->jo.profile_blocks = state == ProfilingState::Enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitInterface::UpdateMembase()
|
||||||
|
{
|
||||||
|
if (!m_jit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto& ppc_state = m_system.GetPPCState();
|
||||||
|
auto& memory = m_system.GetMemory();
|
||||||
|
if (ppc_state.msr.DR)
|
||||||
|
{
|
||||||
|
ppc_state.mem_ptr =
|
||||||
|
m_jit->jo.fastmem_arena ? memory.GetLogicalBase() : memory.GetLogicalPageMappingsBase();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ppc_state.mem_ptr =
|
||||||
|
m_jit->jo.fastmem_arena ? memory.GetPhysicalBase() : memory.GetPhysicalPageMappingsBase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void JitInterface::WriteProfileResults(const std::string& filename) const
|
void JitInterface::WriteProfileResults(const std::string& filename) const
|
||||||
{
|
{
|
||||||
Profiler::ProfileStats prof_stats;
|
Profiler::ProfileStats prof_stats;
|
||||||
|
@ -61,6 +61,7 @@ public:
|
|||||||
u32 entry_address;
|
u32 entry_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void UpdateMembase();
|
||||||
void SetProfilingState(ProfilingState state);
|
void SetProfilingState(ProfilingState state);
|
||||||
void WriteProfileResults(const std::string& filename) const;
|
void WriteProfileResults(const std::string& filename) const;
|
||||||
void GetProfileResults(Profiler::ProfileStats* prof_stats) const;
|
void GetProfileResults(Profiler::ProfileStats* prof_stats) const;
|
||||||
|
@ -569,7 +569,10 @@ void PowerPCManager::CheckExceptions()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CheckExternalExceptions();
|
CheckExternalExceptions();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_system.GetJitInterface().UpdateMembase();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerPCManager::CheckExternalExceptions()
|
void PowerPCManager::CheckExternalExceptions()
|
||||||
@ -623,6 +626,8 @@ void PowerPCManager::CheckExternalExceptions()
|
|||||||
exceptions);
|
exceptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_system.GetJitInterface().UpdateMembase();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerPCManager::CheckBreakPoints()
|
void PowerPCManager::CheckBreakPoints()
|
||||||
|
@ -169,6 +169,7 @@ struct PowerPCState
|
|||||||
|
|
||||||
// Storage for the stack pointer of the BLR optimization.
|
// Storage for the stack pointer of the BLR optimization.
|
||||||
u8* stored_stack_pointer = nullptr;
|
u8* stored_stack_pointer = nullptr;
|
||||||
|
u8* mem_ptr = nullptr;
|
||||||
|
|
||||||
std::array<std::array<TLBEntry, TLB_SIZE / TLB_WAYS>, NUM_TLBS> tlb;
|
std::array<std::array<TLBEntry, TLB_SIZE / TLB_WAYS>, NUM_TLBS> tlb;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user