backend/x64: Move cycles_remaining and cycles_to_run from JitState to stack
This commit is contained in:
parent
d6592c7142
commit
3b2c6afdc2
8 changed files with 25 additions and 29 deletions
|
@ -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)) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue