backend/x64: Move cycles_remaining and cycles_to_run from JitState to stack

This commit is contained in:
MerryMage 2021-05-04 14:39:09 +01:00
parent d6592c7142
commit 3b2c6afdc2
8 changed files with 25 additions and 29 deletions

View file

@ -787,16 +787,16 @@ void A32EmitX64::EmitA32CallSupervisor(A32EmitContext& ctx, IR::Inst* inst) {
ctx.reg_alloc.HostCall(nullptr); ctx.reg_alloc.HostCall(nullptr);
code.SwitchMxcsrOnExit(); code.SwitchMxcsrOnExit();
code.mov(code.ABI_PARAM2, qword[r15 + offsetof(A32JitState, cycles_to_run)]); code.mov(code.ABI_PARAM2, qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)]);
code.sub(code.ABI_PARAM2, qword[r15 + offsetof(A32JitState, cycles_remaining)]); code.sub(code.ABI_PARAM2, qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)]);
Devirtualize<&A32::UserCallbacks::AddTicks>(conf.callbacks).EmitCall(code); Devirtualize<&A32::UserCallbacks::AddTicks>(conf.callbacks).EmitCall(code);
ctx.reg_alloc.EndOfAllocScope(); ctx.reg_alloc.EndOfAllocScope();
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ctx.reg_alloc.HostCall(nullptr, {}, args[0]); ctx.reg_alloc.HostCall(nullptr, {}, args[0]);
Devirtualize<&A32::UserCallbacks::CallSVC>(conf.callbacks).EmitCall(code); Devirtualize<&A32::UserCallbacks::CallSVC>(conf.callbacks).EmitCall(code);
Devirtualize<&A32::UserCallbacks::GetTicksRemaining>(conf.callbacks).EmitCall(code); Devirtualize<&A32::UserCallbacks::GetTicksRemaining>(conf.callbacks).EmitCall(code);
code.mov(qword[r15 + offsetof(A32JitState, cycles_to_run)], code.ABI_RETURN); code.mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)], code.ABI_RETURN);
code.mov(qword[r15 + offsetof(A32JitState, cycles_remaining)], code.ABI_RETURN); code.mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], code.ABI_RETURN);
code.SwitchMxcsrOnEntry(); code.SwitchMxcsrOnEntry();
} }
@ -1538,7 +1538,7 @@ void A32EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc
return; return;
} }
code.cmp(qword[r15 + offsetof(A32JitState, cycles_remaining)], 0); code.cmp(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 0);
patch_information[terminal.next].jg.emplace_back(code.getCurr()); patch_information[terminal.next].jg.emplace_back(code.getCurr());
if (const auto next_bb = GetBasicBlock(terminal.next)) { if (const auto next_bb = GetBasicBlock(terminal.next)) {

View file

@ -42,8 +42,6 @@ struct A32JitState {
// For internal use (See: BlockOfCode::RunCode) // For internal use (See: BlockOfCode::RunCode)
u32 guest_MXCSR = 0x00001f80; u32 guest_MXCSR = 0x00001f80;
u32 asimd_MXCSR = 0x00009fc0; u32 asimd_MXCSR = 0x00009fc0;
s64 cycles_to_run = 0;
s64 cycles_remaining = 0;
bool halt_requested = false; bool halt_requested = false;
// Exclusive state // Exclusive state

View file

@ -1236,7 +1236,7 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc
return; return;
} }
code.cmp(qword[r15 + offsetof(A64JitState, cycles_remaining)], 0); code.cmp(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 0);
patch_information[terminal.next].jg.emplace_back(code.getCurr()); patch_information[terminal.next].jg.emplace_back(code.getCurr());
if (auto next_bb = GetBasicBlock(terminal.next)) { if (auto next_bb = GetBasicBlock(terminal.next)) {

View file

@ -45,8 +45,6 @@ struct A64JitState {
// For internal use (See: BlockOfCode::RunCode) // For internal use (See: BlockOfCode::RunCode)
u32 guest_MXCSR = 0x00001f80; u32 guest_MXCSR = 0x00001f80;
u32 asimd_MXCSR = 0x00009fc0; u32 asimd_MXCSR = 0x00009fc0;
s64 cycles_to_run = 0;
s64 cycles_remaining = 0;
bool halt_requested = false; bool halt_requested = false;
// Exclusive state // Exclusive state

View file

@ -162,8 +162,8 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
mov(rbx, ABI_PARAM2); // save temporarily in non-volatile register mov(rbx, ABI_PARAM2); // save temporarily in non-volatile register
cb.GetTicksRemaining->EmitCall(*this); cb.GetTicksRemaining->EmitCall(*this);
mov(qword[r15 + jsi.offsetof_cycles_to_run], ABI_RETURN); mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)], ABI_RETURN);
mov(qword[r15 + jsi.offsetof_cycles_remaining], ABI_RETURN); mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], ABI_RETURN);
rcp(*this); rcp(*this);
@ -177,8 +177,8 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
mov(r15, ABI_PARAM1); mov(r15, ABI_PARAM1);
mov(qword[r15 + jsi.offsetof_cycles_to_run], 1); mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)], 1);
mov(qword[r15 + jsi.offsetof_cycles_remaining], 1); mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 1);
rcp(*this); rcp(*this);
@ -194,7 +194,7 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
align(); align();
return_from_run_code[0] = getCurr<const void*>(); return_from_run_code[0] = getCurr<const void*>();
cmp(qword[r15 + jsi.offsetof_cycles_remaining], 0); cmp(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 0);
jng(return_to_caller); jng(return_to_caller);
cb.LookupBlock->EmitCall(*this); cb.LookupBlock->EmitCall(*this);
jmp(ABI_RETURN); jmp(ABI_RETURN);
@ -202,7 +202,7 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
align(); align();
return_from_run_code[MXCSR_ALREADY_EXITED] = getCurr<const void*>(); return_from_run_code[MXCSR_ALREADY_EXITED] = getCurr<const void*>();
cmp(qword[r15 + jsi.offsetof_cycles_remaining], 0); cmp(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 0);
jng(return_to_caller_mxcsr_already_exited); jng(return_to_caller_mxcsr_already_exited);
SwitchMxcsrOnEntry(); SwitchMxcsrOnEntry();
cb.LookupBlock->EmitCall(*this); cb.LookupBlock->EmitCall(*this);
@ -219,8 +219,8 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
L(return_to_caller_mxcsr_already_exited); L(return_to_caller_mxcsr_already_exited);
cb.AddTicks->EmitCall(*this, [this](RegList param) { cb.AddTicks->EmitCall(*this, [this](RegList param) {
mov(param[0], qword[r15 + jsi.offsetof_cycles_to_run]); mov(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)]);
sub(param[0], qword[r15 + jsi.offsetof_cycles_remaining]); sub(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)]);
}); });
ABI_PopCalleeSaveRegistersAndAdjustStack(*this, sizeof(StackLayout)); ABI_PopCalleeSaveRegistersAndAdjustStack(*this, sizeof(StackLayout));
@ -251,13 +251,13 @@ void BlockOfCode::LeaveStandardASIMD() {
void BlockOfCode::UpdateTicks() { void BlockOfCode::UpdateTicks() {
cb.AddTicks->EmitCall(*this, [this](RegList param) { cb.AddTicks->EmitCall(*this, [this](RegList param) {
mov(param[0], qword[r15 + jsi.offsetof_cycles_to_run]); mov(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)]);
sub(param[0], qword[r15 + jsi.offsetof_cycles_remaining]); sub(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)]);
}); });
cb.GetTicksRemaining->EmitCall(*this); cb.GetTicksRemaining->EmitCall(*this);
mov(qword[r15 + jsi.offsetof_cycles_to_run], ABI_RETURN); mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)], ABI_RETURN);
mov(qword[r15 + jsi.offsetof_cycles_remaining], ABI_RETURN); mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], ABI_RETURN);
} }
void BlockOfCode::LookupBlock() { void BlockOfCode::LookupBlock() {

View file

@ -11,6 +11,7 @@
#include "backend/x64/emit_x64.h" #include "backend/x64/emit_x64.h"
#include "backend/x64/nzcv_util.h" #include "backend/x64/nzcv_util.h"
#include "backend/x64/perf_map.h" #include "backend/x64/perf_map.h"
#include "backend/x64/stack_layout.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/bit_util.h" #include "common/bit_util.h"
#include "common/common_types.h" #include "common/common_types.h"
@ -181,8 +182,8 @@ void EmitX64::EmitNZCVFromPackedFlags(EmitContext& ctx, IR::Inst* inst) {
} }
void EmitX64::EmitAddCycles(size_t cycles) { void EmitX64::EmitAddCycles(size_t cycles) {
ASSERT(cycles < std::numeric_limits<u32>::max()); ASSERT(cycles < std::numeric_limits<s32>::max());
code.sub(qword[r15 + code.GetJitStateInfo().offsetof_cycles_remaining], static_cast<u32>(cycles)); code.sub(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], static_cast<u32>(cycles));
} }
Xbyak::Label EmitX64::EmitCond(IR::Cond cond) { Xbyak::Label EmitX64::EmitCond(IR::Cond cond) {

View file

@ -12,9 +12,7 @@ namespace Dynarmic::Backend::X64 {
struct JitStateInfo { struct JitStateInfo {
template <typename JitStateType> template <typename JitStateType>
JitStateInfo(const JitStateType&) JitStateInfo(const JitStateType&)
: offsetof_cycles_remaining(offsetof(JitStateType, cycles_remaining)) : offsetof_guest_MXCSR(offsetof(JitStateType, guest_MXCSR))
, offsetof_cycles_to_run(offsetof(JitStateType, cycles_to_run))
, offsetof_guest_MXCSR(offsetof(JitStateType, guest_MXCSR))
, offsetof_asimd_MXCSR(offsetof(JitStateType, asimd_MXCSR)) , offsetof_asimd_MXCSR(offsetof(JitStateType, asimd_MXCSR))
, offsetof_rsb_ptr(offsetof(JitStateType, rsb_ptr)) , offsetof_rsb_ptr(offsetof(JitStateType, rsb_ptr))
, rsb_ptr_mask(JitStateType::RSBPtrMask) , rsb_ptr_mask(JitStateType::RSBPtrMask)
@ -25,8 +23,6 @@ struct JitStateInfo {
, offsetof_fpsr_qc(offsetof(JitStateType, fpsr_qc)) , offsetof_fpsr_qc(offsetof(JitStateType, fpsr_qc))
{} {}
const size_t offsetof_cycles_remaining;
const size_t offsetof_cycles_to_run;
const size_t offsetof_guest_MXCSR; const size_t offsetof_guest_MXCSR;
const size_t offsetof_asimd_MXCSR; const size_t offsetof_asimd_MXCSR;
const size_t offsetof_rsb_ptr; const size_t offsetof_rsb_ptr;

View file

@ -14,6 +14,9 @@ namespace Dynarmic::Backend::X64 {
constexpr size_t SpillCount = 64; constexpr size_t SpillCount = 64;
struct alignas(16) StackLayout { struct alignas(16) StackLayout {
s64 cycles_remaining;
s64 cycles_to_run;
std::array<std::array<u64, 2>, SpillCount> spill; std::array<std::array<u64, 2>, SpillCount> spill;
u32 save_host_MXCSR; u32 save_host_MXCSR;