JitArm64: Inline JitAsm in JitArm64.
So they share the same emitter, and so they are in the same 128MB range. This allows us to use B() to jump to the dispatcher. However, so we have to regenerate them on every cache clear.
This commit is contained in:
parent
0283ce2a7c
commit
b2be9bd7f7
|
@ -48,7 +48,7 @@ void JitArm64::Init()
|
||||||
fpr.Init(this);
|
fpr.Init(this);
|
||||||
|
|
||||||
blocks.Init();
|
blocks.Init();
|
||||||
asm_routines.Init();
|
GenerateAsm();
|
||||||
|
|
||||||
code_block.m_stats = &js.st;
|
code_block.m_stats = &js.st;
|
||||||
code_block.m_gpa = &js.gpa;
|
code_block.m_gpa = &js.gpa;
|
||||||
|
@ -67,13 +67,14 @@ void JitArm64::ClearCache()
|
||||||
ClearCodeSpace();
|
ClearCodeSpace();
|
||||||
farcode.ClearCodeSpace();
|
farcode.ClearCodeSpace();
|
||||||
UpdateMemoryOptions();
|
UpdateMemoryOptions();
|
||||||
|
|
||||||
|
GenerateAsm();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::Shutdown()
|
void JitArm64::Shutdown()
|
||||||
{
|
{
|
||||||
FreeCodeSpace();
|
FreeCodeSpace();
|
||||||
blocks.Shutdown();
|
blocks.Shutdown();
|
||||||
asm_routines.Shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
||||||
|
@ -196,7 +197,7 @@ void JitArm64::WriteExit(u32 destination)
|
||||||
b->linkData.push_back(linkData);
|
b->linkData.push_back(linkData);
|
||||||
|
|
||||||
// the code generated in JitArm64BlockCache::WriteDestroyBlock must fit in this block
|
// the code generated in JitArm64BlockCache::WriteDestroyBlock must fit in this block
|
||||||
MOVI2R(X30, (u64)asm_routines.dispatcher);
|
MOVI2R(X30, (u64)dispatcher);
|
||||||
MOVI2R(DISPATCHER_PC, destination);
|
MOVI2R(DISPATCHER_PC, destination);
|
||||||
BR(X30);
|
BR(X30);
|
||||||
}
|
}
|
||||||
|
@ -213,7 +214,7 @@ void JitArm64::WriteExit(ARM64Reg Reg)
|
||||||
if (Profiler::g_ProfileBlocks)
|
if (Profiler::g_ProfileBlocks)
|
||||||
EndTimeProfile(js.curBlock);
|
EndTimeProfile(js.curBlock);
|
||||||
|
|
||||||
MOVI2R(X30, (u64)asm_routines.dispatcher);
|
MOVI2R(X30, (u64)dispatcher);
|
||||||
BR(X30);
|
BR(X30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +241,7 @@ void JitArm64::WriteExceptionExit(u32 destination, bool only_external)
|
||||||
if (Profiler::g_ProfileBlocks)
|
if (Profiler::g_ProfileBlocks)
|
||||||
EndTimeProfile(js.curBlock);
|
EndTimeProfile(js.curBlock);
|
||||||
|
|
||||||
MOVI2R(X30, (u64)asm_routines.dispatcher);
|
MOVI2R(X30, (u64)dispatcher);
|
||||||
BR(X30);
|
BR(X30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +273,7 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external)
|
||||||
if (Profiler::g_ProfileBlocks)
|
if (Profiler::g_ProfileBlocks)
|
||||||
EndTimeProfile(js.curBlock);
|
EndTimeProfile(js.curBlock);
|
||||||
|
|
||||||
MOVI2R(X30, (u64)asm_routines.dispatcher);
|
MOVI2R(X30, (u64)dispatcher);
|
||||||
BR(X30);
|
BR(X30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,13 +352,13 @@ void JitArm64::EndTimeProfile(JitBlock* b)
|
||||||
|
|
||||||
void JitArm64::Run()
|
void JitArm64::Run()
|
||||||
{
|
{
|
||||||
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
|
CompiledCode pExecAddr = (CompiledCode)enterCode;
|
||||||
pExecAddr();
|
pExecAddr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::SingleStep()
|
void JitArm64::SingleStep()
|
||||||
{
|
{
|
||||||
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
|
CompiledCode pExecAddr = (CompiledCode)enterCode;
|
||||||
pExecAddr();
|
pExecAddr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +416,7 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
|
||||||
ARM64Reg WA = gpr.GetReg();
|
ARM64Reg WA = gpr.GetReg();
|
||||||
ARM64Reg XA = EncodeRegTo64(WA);
|
ARM64Reg XA = EncodeRegTo64(WA);
|
||||||
MOVI2R(DISPATCHER_PC, js.blockStart);
|
MOVI2R(DISPATCHER_PC, js.blockStart);
|
||||||
MOVI2R(XA, (u64)asm_routines.doTiming);
|
MOVI2R(XA, (u64)doTiming);
|
||||||
BR(XA);
|
BR(XA);
|
||||||
gpr.Unlock(WA);
|
gpr.Unlock(WA);
|
||||||
SetJumpTarget(bail);
|
SetJumpTarget(bail);
|
||||||
|
@ -452,7 +453,7 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
|
||||||
MOVI2R(W0, (u32)JitInterface::ExceptionType::EXCEPTIONS_PAIRED_QUANTIZE);
|
MOVI2R(W0, (u32)JitInterface::ExceptionType::EXCEPTIONS_PAIRED_QUANTIZE);
|
||||||
MOVI2R(X1, (u64)&JitInterface::CompileExceptionCheck);
|
MOVI2R(X1, (u64)&JitInterface::CompileExceptionCheck);
|
||||||
BLR(X1);
|
BLR(X1);
|
||||||
MOVI2R(X1, (u64)asm_routines.dispatcher);
|
MOVI2R(X1, (u64)dispatcher);
|
||||||
BR(X1);
|
BR(X1);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
SetJumpTarget(no_fail);
|
SetJumpTarget(no_fail);
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
#include "Core/PowerPC/PPCAnalyst.h"
|
#include "Core/PowerPC/PPCAnalyst.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitArm64Cache.h"
|
#include "Core/PowerPC/JitArm64/JitArm64Cache.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitAsm.h"
|
|
||||||
#include "Core/PowerPC/JitArmCommon/BackPatch.h"
|
#include "Core/PowerPC/JitArmCommon/BackPatch.h"
|
||||||
|
#include "Core/PowerPC/JitCommon/JitAsmCommon.h"
|
||||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||||
|
|
||||||
class JitArm64 : public JitBase, public Arm64Gen::ARM64CodeBlock
|
class JitArm64 : public JitBase, public Arm64Gen::ARM64CodeBlock, public CommonAsmRoutinesBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JitArm64() : code_buffer(32000), m_float_emit(this) {}
|
JitArm64() : code_buffer(32000), m_float_emit(this) {}
|
||||||
|
@ -34,9 +34,9 @@ public:
|
||||||
|
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
|
|
||||||
CommonAsmRoutinesBase *GetAsmRoutines()
|
CommonAsmRoutinesBase *GetAsmRoutines() override
|
||||||
{
|
{
|
||||||
return &asm_routines;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Run();
|
void Run();
|
||||||
|
@ -181,7 +181,6 @@ private:
|
||||||
Arm64FPRCache fpr;
|
Arm64FPRCache fpr;
|
||||||
|
|
||||||
JitArm64BlockCache blocks;
|
JitArm64BlockCache blocks;
|
||||||
JitArm64AsmRoutineManager asm_routines;
|
|
||||||
|
|
||||||
PPCAnalyst::CodeBuffer code_buffer;
|
PPCAnalyst::CodeBuffer code_buffer;
|
||||||
|
|
||||||
|
@ -227,6 +226,11 @@ private:
|
||||||
void DoDownCount();
|
void DoDownCount();
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
|
|
||||||
|
// AsmRoutines
|
||||||
|
void GenerateAsm();
|
||||||
|
void GenerateCommonAsm();
|
||||||
|
void GenMfcr();
|
||||||
|
|
||||||
// Profiling
|
// Profiling
|
||||||
void BeginTimeProfile(JitBlock* b);
|
void BeginTimeProfile(JitBlock* b);
|
||||||
void EndTimeProfile(JitBlock* b);
|
void EndTimeProfile(JitBlock* b);
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitAsm.h"
|
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitAsm.h"
|
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitAsm.h"
|
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#include "Core/PowerPC/JitArm64/Jit_Util.h"
|
#include "Core/PowerPC/JitArm64/Jit_Util.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitAsm.h"
|
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitAsm.h"
|
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitAsm.h"
|
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
|
@ -80,7 +79,7 @@ void JitArm64::psq_l(UGeckoInstruction inst)
|
||||||
UBFM(type_reg, scale_reg, 16, 18); // Type
|
UBFM(type_reg, scale_reg, 16, 18); // Type
|
||||||
UBFM(scale_reg, scale_reg, 24, 29); // Scale
|
UBFM(scale_reg, scale_reg, 24, 29); // Scale
|
||||||
|
|
||||||
MOVI2R(X30, (u64)&asm_routines.pairedLoadQuantized[inst.W * 8]);
|
MOVI2R(X30, (u64)&pairedLoadQuantized[inst.W * 8]);
|
||||||
LDR(X30, X30, ArithOption(EncodeRegTo64(type_reg), true));
|
LDR(X30, X30, ArithOption(EncodeRegTo64(type_reg), true));
|
||||||
BLR(X30);
|
BLR(X30);
|
||||||
|
|
||||||
|
@ -191,7 +190,7 @@ void JitArm64::psq_st(UGeckoInstruction inst)
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
SetJumpTarget(fail);
|
SetJumpTarget(fail);
|
||||||
// Slow
|
// Slow
|
||||||
MOVI2R(X30, (u64)&asm_routines.pairedStoreQuantized[16 + inst.W * 8]);
|
MOVI2R(X30, (u64)&pairedStoreQuantized[16 + inst.W * 8]);
|
||||||
LDR(EncodeRegTo64(type_reg), X30, ArithOption(EncodeRegTo64(type_reg), true));
|
LDR(EncodeRegTo64(type_reg), X30, ArithOption(EncodeRegTo64(type_reg), true));
|
||||||
|
|
||||||
ABI_PushRegisters(gprs_in_use);
|
ABI_PushRegisters(gprs_in_use);
|
||||||
|
@ -204,7 +203,7 @@ void JitArm64::psq_st(UGeckoInstruction inst)
|
||||||
SetJumpTarget(pass);
|
SetJumpTarget(pass);
|
||||||
|
|
||||||
// Fast
|
// Fast
|
||||||
MOVI2R(X30, (u64)&asm_routines.pairedStoreQuantized[inst.W * 8]);
|
MOVI2R(X30, (u64)&pairedStoreQuantized[inst.W * 8]);
|
||||||
LDR(EncodeRegTo64(type_reg), X30, ArithOption(EncodeRegTo64(type_reg), true));
|
LDR(EncodeRegTo64(type_reg), X30, ArithOption(EncodeRegTo64(type_reg), true));
|
||||||
BLR(EncodeRegTo64(type_reg));
|
BLR(EncodeRegTo64(type_reg));
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitAsm.h"
|
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitAsm.h"
|
|
||||||
|
|
||||||
FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
|
FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
|
||||||
{
|
{
|
||||||
|
@ -590,7 +589,7 @@ void JitArm64::mfcr(UGeckoInstruction inst)
|
||||||
JITDISABLE(bJITSystemRegistersOff);
|
JITDISABLE(bJITSystemRegistersOff);
|
||||||
|
|
||||||
gpr.Lock(W0, W1, W2, W30);
|
gpr.Lock(W0, W1, W2, W30);
|
||||||
MOVI2R(X0, (u64)asm_routines.mfcr);
|
MOVI2R(X0, (u64)GetAsmRoutines()->mfcr);
|
||||||
BLR(X0);
|
BLR(X0);
|
||||||
gpr.Unlock(W1, W2, W30);
|
gpr.Unlock(W1, W2, W30);
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,12 @@
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#include "Core/PowerPC/JitArm64/JitAsm.h"
|
|
||||||
#include "Core/PowerPC/JitCommon/JitAsmCommon.h"
|
#include "Core/PowerPC/JitCommon/JitAsmCommon.h"
|
||||||
#include "Core/PowerPC/JitCommon/JitCache.h"
|
#include "Core/PowerPC/JitCommon/JitCache.h"
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
void JitArm64AsmRoutineManager::Generate()
|
void JitArm64::GenerateAsm()
|
||||||
{
|
{
|
||||||
// This value is all of the callee saved registers that we are required to save.
|
// This value is all of the callee saved registers that we are required to save.
|
||||||
// According to the AACPS64 we need to save R19 ~ R30.
|
// According to the AACPS64 we need to save R19 ~ R30.
|
||||||
|
@ -66,7 +65,7 @@ void JitArm64AsmRoutineManager::Generate()
|
||||||
|
|
||||||
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||||
|
|
||||||
MOVI2R(X30, (u64)&Jit);
|
MOVI2R(X30, (u64)&::Jit);
|
||||||
BLR(X30);
|
BLR(X30);
|
||||||
|
|
||||||
B(dispatcherNoCheck);
|
B(dispatcherNoCheck);
|
||||||
|
@ -105,12 +104,12 @@ void JitArm64AsmRoutineManager::Generate()
|
||||||
|
|
||||||
JitRegister::Register(enterCode, GetCodePtr(), "JIT_Dispatcher");
|
JitRegister::Register(enterCode, GetCodePtr(), "JIT_Dispatcher");
|
||||||
|
|
||||||
GenerateCommon();
|
GenerateCommonAsm();
|
||||||
|
|
||||||
FlushIcache();
|
FlushIcache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64AsmRoutineManager::GenerateCommon()
|
void JitArm64::GenerateCommonAsm()
|
||||||
{
|
{
|
||||||
// X0 is the scale
|
// X0 is the scale
|
||||||
// X1 is address
|
// X1 is address
|
||||||
|
@ -577,11 +576,11 @@ void JitArm64AsmRoutineManager::GenerateCommon()
|
||||||
pairedStoreQuantized[30] = storeSingleS8Slow;
|
pairedStoreQuantized[30] = storeSingleS8Slow;
|
||||||
pairedStoreQuantized[31] = storeSingleS16Slow;
|
pairedStoreQuantized[31] = storeSingleS16Slow;
|
||||||
|
|
||||||
mfcr = AlignCode16();
|
GetAsmRoutines()->mfcr = AlignCode16();
|
||||||
GenMfcr();
|
GenMfcr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64AsmRoutineManager::GenMfcr()
|
void JitArm64::GenMfcr()
|
||||||
{
|
{
|
||||||
// Input: Nothing
|
// Input: Nothing
|
||||||
// Returns: W0
|
// Returns: W0
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
// Copyright 2008 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common/Arm64Emitter.h"
|
|
||||||
#include "Core/PowerPC/JitCommon/JitAsmCommon.h"
|
|
||||||
|
|
||||||
class JitArm64AsmRoutineManager : public CommonAsmRoutinesBase, public Arm64Gen::ARM64CodeBlock
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
void Generate();
|
|
||||||
void GenerateCommon();
|
|
||||||
void GenMfcr();
|
|
||||||
|
|
||||||
public:
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
AllocCodeSpace(16384);
|
|
||||||
Generate();
|
|
||||||
WriteProtect();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shutdown()
|
|
||||||
{
|
|
||||||
FreeCodeSpace();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue