mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-07 12:05:52 +00:00
CPU/NewRec/AArch64: Don't recreate assembler every time
This commit is contained in:
parent
9d14ba0541
commit
d00ed000f9
@ -8,6 +8,7 @@
|
|||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "cpu_core_private.h"
|
#include "cpu_core_private.h"
|
||||||
#include "cpu_recompiler_thunks.h"
|
#include "cpu_recompiler_thunks.h"
|
||||||
|
#include "cpu_recompiler_types.h"
|
||||||
#include "gte.h"
|
#include "gte.h"
|
||||||
#include "pgxp.h"
|
#include "pgxp.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
@ -15,31 +16,12 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
Log_SetChannel(CPU::NewRec);
|
Log_SetChannel(CPU::NewRec);
|
||||||
|
|
||||||
#define DUMP_BLOCKS
|
|
||||||
|
|
||||||
#ifdef DUMP_BLOCKS
|
|
||||||
#include "vixl/aarch64/disasm-aarch64.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace vixl::aarch64;
|
|
||||||
|
|
||||||
#define RWRET vixl::aarch64::w0
|
|
||||||
#define RXRET vixl::aarch64::x0
|
|
||||||
#define RWARG1 vixl::aarch64::w0
|
|
||||||
#define RXARG1 vixl::aarch64::x0
|
|
||||||
#define RWARG2 vixl::aarch64::w1
|
|
||||||
#define RXARG2 vixl::aarch64::x1
|
|
||||||
#define RWARG3 vixl::aarch64::w2
|
|
||||||
#define RXARG3 vixl::aarch64::x2
|
|
||||||
#define RWSCRATCH vixl::aarch64::w16
|
|
||||||
#define RXSCRATCH vixl::aarch64::x16
|
|
||||||
#define RSTATE vixl::aarch64::x19
|
|
||||||
#define RMEMBASE vixl::aarch64::x20
|
|
||||||
|
|
||||||
#define PTR(x) vixl::aarch64::MemOperand(RSTATE, (u32)(((u8*)(x)) - ((u8*)&g_state)))
|
#define PTR(x) vixl::aarch64::MemOperand(RSTATE, (u32)(((u8*)(x)) - ((u8*)&g_state)))
|
||||||
|
|
||||||
namespace CPU::NewRec {
|
namespace CPU::NewRec {
|
||||||
|
|
||||||
|
using namespace vixl::aarch64;
|
||||||
|
|
||||||
using CPU::Recompiler::armEmitCall;
|
using CPU::Recompiler::armEmitCall;
|
||||||
using CPU::Recompiler::armEmitCondBranch;
|
using CPU::Recompiler::armEmitCondBranch;
|
||||||
using CPU::Recompiler::armEmitJmp;
|
using CPU::Recompiler::armEmitJmp;
|
||||||
@ -54,7 +36,11 @@ Compiler* g_compiler = &s_instance;
|
|||||||
|
|
||||||
} // namespace CPU::NewRec
|
} // namespace CPU::NewRec
|
||||||
|
|
||||||
CPU::NewRec::AArch64Compiler::AArch64Compiler() = default;
|
CPU::NewRec::AArch64Compiler::AArch64Compiler()
|
||||||
|
: m_emitter(PositionDependentCode)
|
||||||
|
, m_far_emitter(PositionIndependentCode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CPU::NewRec::AArch64Compiler::~AArch64Compiler() = default;
|
CPU::NewRec::AArch64Compiler::~AArch64Compiler() = default;
|
||||||
|
|
||||||
@ -69,10 +55,10 @@ void CPU::NewRec::AArch64Compiler::Reset(CodeCache::Block* block, u8* code_buffe
|
|||||||
Compiler::Reset(block, code_buffer, code_buffer_space, far_code_buffer, far_code_space);
|
Compiler::Reset(block, code_buffer, code_buffer_space, far_code_buffer, far_code_space);
|
||||||
|
|
||||||
// TODO: don't recreate this every time..
|
// TODO: don't recreate this every time..
|
||||||
DebugAssert(!m_emitter && !m_far_emitter && !armAsm);
|
DebugAssert(!armAsm);
|
||||||
m_emitter = std::make_unique<Assembler>(code_buffer, code_buffer_space, PositionDependentCode);
|
m_emitter.GetBuffer()->Reset(code_buffer, code_buffer_space);
|
||||||
m_far_emitter = std::make_unique<Assembler>(far_code_buffer, far_code_space, PositionDependentCode);
|
m_far_emitter.GetBuffer()->Reset(far_code_buffer, far_code_space);
|
||||||
armAsm = m_emitter.get();
|
armAsm = &m_emitter;
|
||||||
|
|
||||||
#ifdef VIXL_DEBUG
|
#ifdef VIXL_DEBUG
|
||||||
m_emitter_check = std::make_unique<vixl::CodeBufferCheckScope>(m_emitter.get(), code_buffer_space,
|
m_emitter_check = std::make_unique<vixl::CodeBufferCheckScope>(m_emitter.get(), code_buffer_space,
|
||||||
@ -101,10 +87,10 @@ void CPU::NewRec::AArch64Compiler::Reset(CodeCache::Block* block, u8* code_buffe
|
|||||||
|
|
||||||
void CPU::NewRec::AArch64Compiler::SwitchToFarCode(bool emit_jump, vixl::aarch64::Condition cond)
|
void CPU::NewRec::AArch64Compiler::SwitchToFarCode(bool emit_jump, vixl::aarch64::Condition cond)
|
||||||
{
|
{
|
||||||
DebugAssert(armAsm == m_emitter.get());
|
DebugAssert(armAsm == &m_emitter);
|
||||||
if (emit_jump)
|
if (emit_jump)
|
||||||
{
|
{
|
||||||
const s64 disp = armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter->GetCursorAddress<const void*>());
|
const s64 disp = armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter.GetCursorAddress<const void*>());
|
||||||
if (cond != Condition::al)
|
if (cond != Condition::al)
|
||||||
{
|
{
|
||||||
if (vixl::IsInt19(disp))
|
if (vixl::IsInt19(disp))
|
||||||
@ -115,7 +101,7 @@ void CPU::NewRec::AArch64Compiler::SwitchToFarCode(bool emit_jump, vixl::aarch64
|
|||||||
{
|
{
|
||||||
Label skip;
|
Label skip;
|
||||||
armAsm->b(&skip, vixl::aarch64::InvertCondition(cond));
|
armAsm->b(&skip, vixl::aarch64::InvertCondition(cond));
|
||||||
armAsm->b(armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter->GetCursorAddress<const void*>()));
|
armAsm->b(armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter.GetCursorAddress<const void*>()));
|
||||||
armAsm->bind(&skip);
|
armAsm->bind(&skip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,12 +110,12 @@ void CPU::NewRec::AArch64Compiler::SwitchToFarCode(bool emit_jump, vixl::aarch64
|
|||||||
armAsm->b(disp);
|
armAsm->b(disp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
armAsm = m_far_emitter.get();
|
armAsm = &m_far_emitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::NewRec::AArch64Compiler::SwitchToFarCodeIfBitSet(const vixl::aarch64::Register& reg, u32 bit)
|
void CPU::NewRec::AArch64Compiler::SwitchToFarCodeIfBitSet(const vixl::aarch64::Register& reg, u32 bit)
|
||||||
{
|
{
|
||||||
const s64 disp = armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter->GetCursorAddress<const void*>());
|
const s64 disp = armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter.GetCursorAddress<const void*>());
|
||||||
if (vixl::IsInt14(disp))
|
if (vixl::IsInt14(disp))
|
||||||
{
|
{
|
||||||
armAsm->tbnz(reg, bit, disp);
|
armAsm->tbnz(reg, bit, disp);
|
||||||
@ -138,16 +124,16 @@ void CPU::NewRec::AArch64Compiler::SwitchToFarCodeIfBitSet(const vixl::aarch64::
|
|||||||
{
|
{
|
||||||
Label skip;
|
Label skip;
|
||||||
armAsm->tbz(reg, bit, &skip);
|
armAsm->tbz(reg, bit, &skip);
|
||||||
armAsm->b(armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter->GetCursorAddress<const void*>()));
|
armAsm->b(armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter.GetCursorAddress<const void*>()));
|
||||||
armAsm->bind(&skip);
|
armAsm->bind(&skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
armAsm = m_far_emitter.get();
|
armAsm = &m_far_emitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::NewRec::AArch64Compiler::SwitchToFarCodeIfRegZeroOrNonZero(const vixl::aarch64::Register& reg, bool nonzero)
|
void CPU::NewRec::AArch64Compiler::SwitchToFarCodeIfRegZeroOrNonZero(const vixl::aarch64::Register& reg, bool nonzero)
|
||||||
{
|
{
|
||||||
const s64 disp = armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter->GetCursorAddress<const void*>());
|
const s64 disp = armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter.GetCursorAddress<const void*>());
|
||||||
if (vixl::IsInt19(disp))
|
if (vixl::IsInt19(disp))
|
||||||
{
|
{
|
||||||
nonzero ? armAsm->cbnz(reg, disp) : armAsm->cbz(reg, disp);
|
nonzero ? armAsm->cbnz(reg, disp) : armAsm->cbz(reg, disp);
|
||||||
@ -156,22 +142,22 @@ void CPU::NewRec::AArch64Compiler::SwitchToFarCodeIfRegZeroOrNonZero(const vixl:
|
|||||||
{
|
{
|
||||||
Label skip;
|
Label skip;
|
||||||
nonzero ? armAsm->cbz(reg, &skip) : armAsm->cbnz(reg, &skip);
|
nonzero ? armAsm->cbz(reg, &skip) : armAsm->cbnz(reg, &skip);
|
||||||
armAsm->b(armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter->GetCursorAddress<const void*>()));
|
armAsm->b(armGetPCDisplacement(GetCurrentCodePointer(), m_far_emitter.GetCursorAddress<const void*>()));
|
||||||
armAsm->bind(&skip);
|
armAsm->bind(&skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
armAsm = m_far_emitter.get();
|
armAsm = &m_far_emitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::NewRec::AArch64Compiler::SwitchToNearCode(bool emit_jump, vixl::aarch64::Condition cond)
|
void CPU::NewRec::AArch64Compiler::SwitchToNearCode(bool emit_jump, vixl::aarch64::Condition cond)
|
||||||
{
|
{
|
||||||
DebugAssert(armAsm == m_far_emitter.get());
|
DebugAssert(armAsm == &m_far_emitter);
|
||||||
if (emit_jump)
|
if (emit_jump)
|
||||||
{
|
{
|
||||||
const s64 disp = armGetPCDisplacement(GetCurrentCodePointer(), m_emitter->GetCursorAddress<const void*>());
|
const s64 disp = armGetPCDisplacement(GetCurrentCodePointer(), m_emitter.GetCursorAddress<const void*>());
|
||||||
(cond != Condition::al) ? armAsm->b(disp, cond) : armAsm->b(disp);
|
(cond != Condition::al) ? armAsm->b(disp, cond) : armAsm->b(disp);
|
||||||
}
|
}
|
||||||
armAsm = m_emitter.get();
|
armAsm = &m_emitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::NewRec::AArch64Compiler::EmitMov(const vixl::aarch64::WRegister& dst, u32 val)
|
void CPU::NewRec::AArch64Compiler::EmitMov(const vixl::aarch64::WRegister& dst, u32 val)
|
||||||
@ -436,15 +422,13 @@ const void* CPU::NewRec::AArch64Compiler::EndCompile(u32* code_size, u32* far_co
|
|||||||
m_far_emitter_check.reset();
|
m_far_emitter_check.reset();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_emitter->FinalizeCode();
|
m_emitter.FinalizeCode();
|
||||||
m_far_emitter->FinalizeCode();
|
m_far_emitter.FinalizeCode();
|
||||||
|
|
||||||
u8* const code = m_emitter->GetBuffer()->GetStartAddress<u8*>();
|
u8* const code = m_emitter.GetBuffer()->GetStartAddress<u8*>();
|
||||||
*code_size = static_cast<u32>(m_emitter->GetCursorOffset());
|
*code_size = static_cast<u32>(m_emitter.GetCursorOffset());
|
||||||
*far_code_size = static_cast<u32>(m_far_emitter->GetCursorOffset());
|
*far_code_size = static_cast<u32>(m_far_emitter.GetCursorOffset());
|
||||||
armAsm = nullptr;
|
armAsm = nullptr;
|
||||||
m_far_emitter.reset();
|
|
||||||
m_emitter.reset();
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1349,7 +1333,7 @@ vixl::aarch64::WRegister CPU::NewRec::AArch64Compiler::GenerateLoad(const vixl::
|
|||||||
|
|
||||||
const MemOperand mem =
|
const MemOperand mem =
|
||||||
MemOperand((g_settings.cpu_fastmem_mode == CPUFastmemMode::LUT) ? RXARG3 : RMEMBASE, addr_reg.X());
|
MemOperand((g_settings.cpu_fastmem_mode == CPUFastmemMode::LUT) ? RXARG3 : RMEMBASE, addr_reg.X());
|
||||||
u8* start = m_emitter->GetCursorAddress<u8*>();
|
u8* start = armAsm->GetCursorAddress<u8*>();
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case MemoryAccessSize::Byte:
|
case MemoryAccessSize::Byte:
|
||||||
@ -1459,7 +1443,7 @@ void CPU::NewRec::AArch64Compiler::GenerateStore(const vixl::aarch64::WRegister&
|
|||||||
|
|
||||||
const MemOperand mem =
|
const MemOperand mem =
|
||||||
MemOperand((g_settings.cpu_fastmem_mode == CPUFastmemMode::LUT) ? RXARG3 : RMEMBASE, addr_reg.X());
|
MemOperand((g_settings.cpu_fastmem_mode == CPUFastmemMode::LUT) ? RXARG3 : RMEMBASE, addr_reg.X());
|
||||||
u8* start = m_emitter->GetCursorAddress<u8*>();
|
u8* start = armAsm->GetCursorAddress<u8*>();
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case MemoryAccessSize::Byte:
|
case MemoryAccessSize::Byte:
|
||||||
|
@ -151,8 +151,8 @@ private:
|
|||||||
void MoveTToReg(const vixl::aarch64::WRegister& dst, CompileFlags cf);
|
void MoveTToReg(const vixl::aarch64::WRegister& dst, CompileFlags cf);
|
||||||
void MoveMIPSRegToReg(const vixl::aarch64::WRegister& dst, Reg reg);
|
void MoveMIPSRegToReg(const vixl::aarch64::WRegister& dst, Reg reg);
|
||||||
|
|
||||||
std::unique_ptr<vixl::aarch64::Assembler> m_emitter;
|
vixl::aarch64::Assembler m_emitter;
|
||||||
std::unique_ptr<vixl::aarch64::Assembler> m_far_emitter;
|
vixl::aarch64::Assembler m_far_emitter;
|
||||||
vixl::aarch64::Assembler* armAsm;
|
vixl::aarch64::Assembler* armAsm;
|
||||||
|
|
||||||
#ifdef VIXL_DEBUG
|
#ifdef VIXL_DEBUG
|
||||||
|
Loading…
x
Reference in New Issue
Block a user