diff --git a/src/backend/x64/a32_emit_x64.cpp b/src/backend/x64/a32_emit_x64.cpp index 1b8759c3..40de5207 100644 --- a/src/backend/x64/a32_emit_x64.cpp +++ b/src/backend/x64/a32_emit_x64.cpp @@ -787,16 +787,16 @@ void A32EmitX64::EmitA32CallSupervisor(A32EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.HostCall(nullptr); code.SwitchMxcsrOnExit(); - code.mov(code.ABI_PARAM2, qword[r15 + offsetof(A32JitState, cycles_to_run)]); - code.sub(code.ABI_PARAM2, qword[r15 + offsetof(A32JitState, cycles_remaining)]); + code.mov(code.ABI_PARAM2, qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)]); + code.sub(code.ABI_PARAM2, qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)]); Devirtualize<&A32::UserCallbacks::AddTicks>(conf.callbacks).EmitCall(code); ctx.reg_alloc.EndOfAllocScope(); auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(nullptr, {}, args[0]); Devirtualize<&A32::UserCallbacks::CallSVC>(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[r15 + offsetof(A32JitState, cycles_remaining)], code.ABI_RETURN); + code.mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)], code.ABI_RETURN); + code.mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], code.ABI_RETURN); code.SwitchMxcsrOnEntry(); } @@ -1538,7 +1538,7 @@ void A32EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc 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()); if (const auto next_bb = GetBasicBlock(terminal.next)) { diff --git a/src/backend/x64/a32_jitstate.h b/src/backend/x64/a32_jitstate.h index c83b14bb..2e681614 100644 --- a/src/backend/x64/a32_jitstate.h +++ b/src/backend/x64/a32_jitstate.h @@ -42,8 +42,6 @@ struct A32JitState { // For internal use (See: BlockOfCode::RunCode) u32 guest_MXCSR = 0x00001f80; u32 asimd_MXCSR = 0x00009fc0; - s64 cycles_to_run = 0; - s64 cycles_remaining = 0; bool halt_requested = false; // Exclusive state diff --git a/src/backend/x64/a64_emit_x64.cpp b/src/backend/x64/a64_emit_x64.cpp index 9c4eea3c..a7cef22e 100644 --- a/src/backend/x64/a64_emit_x64.cpp +++ b/src/backend/x64/a64_emit_x64.cpp @@ -1236,7 +1236,7 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc 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()); if (auto next_bb = GetBasicBlock(terminal.next)) { diff --git a/src/backend/x64/a64_jitstate.h b/src/backend/x64/a64_jitstate.h index 8bc9b64e..0ef9e93d 100644 --- a/src/backend/x64/a64_jitstate.h +++ b/src/backend/x64/a64_jitstate.h @@ -45,8 +45,6 @@ struct A64JitState { // For internal use (See: BlockOfCode::RunCode) u32 guest_MXCSR = 0x00001f80; u32 asimd_MXCSR = 0x00009fc0; - s64 cycles_to_run = 0; - s64 cycles_remaining = 0; bool halt_requested = false; // Exclusive state diff --git a/src/backend/x64/block_of_code.cpp b/src/backend/x64/block_of_code.cpp index f54d9a3a..0e294ff4 100644 --- a/src/backend/x64/block_of_code.cpp +++ b/src/backend/x64/block_of_code.cpp @@ -162,8 +162,8 @@ void BlockOfCode::GenRunCode(std::function rcp) { mov(rbx, ABI_PARAM2); // save temporarily in non-volatile register cb.GetTicksRemaining->EmitCall(*this); - mov(qword[r15 + jsi.offsetof_cycles_to_run], ABI_RETURN); - mov(qword[r15 + jsi.offsetof_cycles_remaining], ABI_RETURN); + mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)], ABI_RETURN); + mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], ABI_RETURN); rcp(*this); @@ -177,8 +177,8 @@ void BlockOfCode::GenRunCode(std::function rcp) { mov(r15, ABI_PARAM1); - mov(qword[r15 + jsi.offsetof_cycles_to_run], 1); - mov(qword[r15 + jsi.offsetof_cycles_remaining], 1); + mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)], 1); + mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 1); rcp(*this); @@ -194,7 +194,7 @@ void BlockOfCode::GenRunCode(std::function rcp) { align(); return_from_run_code[0] = getCurr(); - cmp(qword[r15 + jsi.offsetof_cycles_remaining], 0); + cmp(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 0); jng(return_to_caller); cb.LookupBlock->EmitCall(*this); jmp(ABI_RETURN); @@ -202,7 +202,7 @@ void BlockOfCode::GenRunCode(std::function rcp) { align(); return_from_run_code[MXCSR_ALREADY_EXITED] = getCurr(); - 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); SwitchMxcsrOnEntry(); cb.LookupBlock->EmitCall(*this); @@ -219,8 +219,8 @@ void BlockOfCode::GenRunCode(std::function rcp) { L(return_to_caller_mxcsr_already_exited); cb.AddTicks->EmitCall(*this, [this](RegList param) { - mov(param[0], qword[r15 + jsi.offsetof_cycles_to_run]); - sub(param[0], qword[r15 + jsi.offsetof_cycles_remaining]); + mov(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)]); + sub(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)]); }); ABI_PopCalleeSaveRegistersAndAdjustStack(*this, sizeof(StackLayout)); @@ -251,13 +251,13 @@ void BlockOfCode::LeaveStandardASIMD() { void BlockOfCode::UpdateTicks() { cb.AddTicks->EmitCall(*this, [this](RegList param) { - mov(param[0], qword[r15 + jsi.offsetof_cycles_to_run]); - sub(param[0], qword[r15 + jsi.offsetof_cycles_remaining]); + mov(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)]); + sub(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)]); }); cb.GetTicksRemaining->EmitCall(*this); - mov(qword[r15 + jsi.offsetof_cycles_to_run], ABI_RETURN); - mov(qword[r15 + jsi.offsetof_cycles_remaining], ABI_RETURN); + mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)], ABI_RETURN); + mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], ABI_RETURN); } void BlockOfCode::LookupBlock() { diff --git a/src/backend/x64/emit_x64.cpp b/src/backend/x64/emit_x64.cpp index 817de5f5..d843430a 100644 --- a/src/backend/x64/emit_x64.cpp +++ b/src/backend/x64/emit_x64.cpp @@ -11,6 +11,7 @@ #include "backend/x64/emit_x64.h" #include "backend/x64/nzcv_util.h" #include "backend/x64/perf_map.h" +#include "backend/x64/stack_layout.h" #include "common/assert.h" #include "common/bit_util.h" #include "common/common_types.h" @@ -181,8 +182,8 @@ void EmitX64::EmitNZCVFromPackedFlags(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitAddCycles(size_t cycles) { - ASSERT(cycles < std::numeric_limits::max()); - code.sub(qword[r15 + code.GetJitStateInfo().offsetof_cycles_remaining], static_cast(cycles)); + ASSERT(cycles < std::numeric_limits::max()); + code.sub(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], static_cast(cycles)); } Xbyak::Label EmitX64::EmitCond(IR::Cond cond) { diff --git a/src/backend/x64/jitstate_info.h b/src/backend/x64/jitstate_info.h index 711a218f..1e077055 100644 --- a/src/backend/x64/jitstate_info.h +++ b/src/backend/x64/jitstate_info.h @@ -12,9 +12,7 @@ namespace Dynarmic::Backend::X64 { struct JitStateInfo { template JitStateInfo(const JitStateType&) - : offsetof_cycles_remaining(offsetof(JitStateType, cycles_remaining)) - , offsetof_cycles_to_run(offsetof(JitStateType, cycles_to_run)) - , offsetof_guest_MXCSR(offsetof(JitStateType, guest_MXCSR)) + : offsetof_guest_MXCSR(offsetof(JitStateType, guest_MXCSR)) , offsetof_asimd_MXCSR(offsetof(JitStateType, asimd_MXCSR)) , offsetof_rsb_ptr(offsetof(JitStateType, rsb_ptr)) , rsb_ptr_mask(JitStateType::RSBPtrMask) @@ -25,8 +23,6 @@ struct JitStateInfo { , 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_asimd_MXCSR; const size_t offsetof_rsb_ptr; diff --git a/src/backend/x64/stack_layout.h b/src/backend/x64/stack_layout.h index f7d00401..b4db9de4 100644 --- a/src/backend/x64/stack_layout.h +++ b/src/backend/x64/stack_layout.h @@ -14,6 +14,9 @@ namespace Dynarmic::Backend::X64 { constexpr size_t SpillCount = 64; struct alignas(16) StackLayout { + s64 cycles_remaining; + s64 cycles_to_run; + std::array, SpillCount> spill; u32 save_host_MXCSR;