From 9350c8cefb4148b507acfefdc44a6795b88df9a1 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 19 Mar 2026 18:01:48 +0000 Subject: [PATCH 1/7] [dynarmic] exclude %rbp from regalloc Signed-off-by: lizzie --- src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp b/src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp index 5c5ed25131..2cfa14ae18 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp @@ -417,7 +417,8 @@ HostLoc RegAlloc::SelectARegister(std::bitset<32> desired_locations) const noexc // While R13 and R14 are technically available, we avoid allocating for them // at all costs, because theoretically skipping them is better than spilling // all over the place - i also fixes bugs with high reg pressure - } else if (i >= HostLoc::R13 && i <= HostLoc::R15) { + // %rbp must not be trashed, so skip it as well + } else if (i == HostLoc::RBP || (i >= HostLoc::R13 && i <= HostLoc::R15)) { // skip, do not touch // Intel recommends to reuse registers as soon as they're overwritable (DO NOT SPILL) } else if (loc_info.IsEmpty()) { From b8a46d1363892f80ed7a3221e9d3130f74d37325 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 19 Mar 2026 18:05:07 +0000 Subject: [PATCH 2/7] fx --- src/dynarmic/src/dynarmic/backend/x64/abi.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dynarmic/src/dynarmic/backend/x64/abi.cpp b/src/dynarmic/src/dynarmic/backend/x64/abi.cpp index 413af7b557..b7faaff911 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/abi.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/abi.cpp @@ -47,6 +47,8 @@ void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, const size_t num_xmms = (ABI_ALL_XMMS & regs).count(); const FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size); + code.push(rbp); + code.mov(rbp, rsp); for (size_t i = 0; i < regs.size(); ++i) if (regs[i] && HostLocIsGPR(HostLoc(i))) code.push(HostLocToReg64(HostLoc(i))); @@ -87,6 +89,7 @@ void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, for (int32_t i = regs.size() - 1; i >= 0; --i) if (regs[i] && HostLocIsGPR(HostLoc(i))) code.pop(HostLocToReg64(HostLoc(i))); + code.pop(rbp); } void ABI_PushCalleeSaveRegistersAndAdjustStack(BlockOfCode& code, const std::size_t frame_size) { From f262eb57ff76e51b849ee81499b2d9145d309e95 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 19 Mar 2026 22:01:23 +0000 Subject: [PATCH 3/7] ok fix for winshit --- src/dynarmic/src/dynarmic/backend/x64/abi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dynarmic/src/dynarmic/backend/x64/abi.cpp b/src/dynarmic/src/dynarmic/backend/x64/abi.cpp index b7faaff911..e3e54989a5 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/abi.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/abi.cpp @@ -43,7 +43,7 @@ static FrameInfo CalculateFrameInfo(const size_t num_gprs, const size_t num_xmms void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> const& regs) { using namespace Xbyak::util; - const size_t num_gprs = (ABI_ALL_GPRS & regs).count(); + const size_t num_gprs = (ABI_ALL_GPRS & regs).count() + 1; const size_t num_xmms = (ABI_ALL_XMMS & regs).count(); const FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size); @@ -70,7 +70,7 @@ void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> const& regs) { using namespace Xbyak::util; - const size_t num_gprs = (ABI_ALL_GPRS & regs).count(); + const size_t num_gprs = (ABI_ALL_GPRS & regs).count() + 1; const size_t num_xmms = (ABI_ALL_XMMS & regs).count(); const FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size); From 7ec24e3b1acd6e4879850020a5c38377803b49c8 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 19 Mar 2026 22:27:47 +0000 Subject: [PATCH 4/7] pot fix --- .../src/dynarmic/backend/x64/a64_emit_x64.cpp | 7 ++++++ src/dynarmic/src/dynarmic/backend/x64/abi.cpp | 7 ++---- .../backend/x64/exception_handler_windows.cpp | 24 +++++++++---------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp index ff82d8b05c..eab6fc038a 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp @@ -90,6 +90,10 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) noexcept { code.align(); const auto* const entrypoint = code.getCurr(); + code.push(rbp); + code.mov(rbp, rsp); + code.and_(rsp, -16); + DEBUG_ASSERT(block.GetCondition() == IR::Cond::AL); typedef void (EmitX64::*EmitHandlerFn)(EmitContext& context, IR::Inst* inst); constexpr EmitHandlerFn opcode_handlers[] = { @@ -248,6 +252,9 @@ void A64EmitX64::GenTerminalHandlers() { } code.and_(code.ABI_PARAM1.cvt32(), fast_dispatch_table_mask); code.lea(code.ABI_RETURN, code.ptr[code.ABI_PARAM2 + code.ABI_PARAM1]); + + code.mov(rsp, rbp); + code.pop(rbp); code.ret(); PerfMapRegister(fast_dispatch_table_lookup, code.getCurr(), "a64_fast_dispatch_table_lookup"); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/abi.cpp b/src/dynarmic/src/dynarmic/backend/x64/abi.cpp index e3e54989a5..413af7b557 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/abi.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/abi.cpp @@ -43,12 +43,10 @@ static FrameInfo CalculateFrameInfo(const size_t num_gprs, const size_t num_xmms void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> const& regs) { using namespace Xbyak::util; - const size_t num_gprs = (ABI_ALL_GPRS & regs).count() + 1; + const size_t num_gprs = (ABI_ALL_GPRS & regs).count(); const size_t num_xmms = (ABI_ALL_XMMS & regs).count(); const FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size); - code.push(rbp); - code.mov(rbp, rsp); for (size_t i = 0; i < regs.size(); ++i) if (regs[i] && HostLocIsGPR(HostLoc(i))) code.push(HostLocToReg64(HostLoc(i))); @@ -70,7 +68,7 @@ void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> const& regs) { using namespace Xbyak::util; - const size_t num_gprs = (ABI_ALL_GPRS & regs).count() + 1; + const size_t num_gprs = (ABI_ALL_GPRS & regs).count(); const size_t num_xmms = (ABI_ALL_XMMS & regs).count(); const FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size); @@ -89,7 +87,6 @@ void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, for (int32_t i = regs.size() - 1; i >= 0; --i) if (regs[i] && HostLocIsGPR(HostLoc(i))) code.pop(HostLocToReg64(HostLoc(i))); - code.pop(rbp); } void ABI_PushCalleeSaveRegistersAndAdjustStack(BlockOfCode& code, const std::size_t frame_size) { diff --git a/src/dynarmic/src/dynarmic/backend/x64/exception_handler_windows.cpp b/src/dynarmic/src/dynarmic/backend/x64/exception_handler_windows.cpp index 3ae553bccd..bae397ff2b 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/exception_handler_windows.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/exception_handler_windows.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -176,7 +176,7 @@ struct ExceptionHandler::Impl final { code.align(16); const u8* exception_handler_without_cb = code.getCurr(); - code.mov(code.eax, static_cast(ExceptionContinueSearch)); + code.mov(code.eax, u32(ExceptionContinueSearch)); code.ret(); code.align(16); @@ -192,20 +192,18 @@ struct ExceptionHandler::Impl final { code.lea(code.rsp, code.ptr[code.rsp - 8]); code.mov(code.ABI_PARAM1, std::bit_cast(&cb)); code.mov(code.ABI_PARAM2, code.ABI_PARAM3); - code.CallLambda( - [](const std::function& cb_, PCONTEXT ctx) { - FakeCall fc = cb_(ctx->Rip); - - ctx->Rsp -= sizeof(u64); - *std::bit_cast(ctx->Rsp) = fc.ret_rip; - ctx->Rip = fc.call_rip; - }); + code.CallLambda([](const std::function& cb_, PCONTEXT ctx) { + FakeCall fc = cb_(ctx->Rip); + ctx->Rsp -= sizeof(u64); + *std::bit_cast(ctx->Rsp) = fc.ret_rip; + ctx->Rip = fc.call_rip; + }); code.add(code.rsp, 8); - code.mov(code.eax, static_cast(ExceptionContinueExecution)); + code.mov(code.eax, u32(ExceptionContinueExecution)); code.ret(); - exception_handler_without_cb_offset = static_cast(exception_handler_without_cb - code.getCode()); - exception_handler_with_cb_offset = static_cast(exception_handler_with_cb - code.getCode()); + exception_handler_without_cb_offset = ULONG(exception_handler_without_cb - code.getCode()); + exception_handler_with_cb_offset = ULONG(exception_handler_with_cb - code.getCode()); code.align(16); UNWIND_INFO* unwind_info = static_cast(code.AllocateFromCodeSpace(sizeof(UNWIND_INFO))); From 88a2d2cecb734bea8d41365b7138eaf674506135 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 19 Mar 2026 22:50:39 +0000 Subject: [PATCH 5/7] tes1 --- .../src/dynarmic/backend/x64/a64_emit_x64.cpp | 11 +++++------ src/dynarmic/src/dynarmic/backend/x64/stack_layout.h | 4 +--- src/video_core/host_shaders/CMakeLists.txt | 6 +++--- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp index eab6fc038a..d4f9d9daaf 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp @@ -90,9 +90,8 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) noexcept { code.align(); const auto* const entrypoint = code.getCurr(); - code.push(rbp); - code.mov(rbp, rsp); - code.and_(rsp, -16); + // code.mov(code.qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer)], rbp); + // code.lea(rbp, code.ptr[rsp + ABI_SHADOW_SPACE - 8]); DEBUG_ASSERT(block.GetCondition() == IR::Cond::AL); typedef void (EmitX64::*EmitHandlerFn)(EmitContext& context, IR::Inst* inst); @@ -148,6 +147,9 @@ finish_this_inst: if (conf.enable_cycle_counting) { EmitAddCycles(block.CycleCount()); } + + //code.mov(rbp, code.qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer)]); + EmitTerminal(block.GetTerminal(), ctx.Location().SetSingleStepping(false), ctx.IsSingleStep()); code.int3(); @@ -252,9 +254,6 @@ void A64EmitX64::GenTerminalHandlers() { } code.and_(code.ABI_PARAM1.cvt32(), fast_dispatch_table_mask); code.lea(code.ABI_RETURN, code.ptr[code.ABI_PARAM2 + code.ABI_PARAM1]); - - code.mov(rsp, rbp); - code.pop(rbp); code.ret(); PerfMapRegister(fast_dispatch_table_lookup, code.getCurr(), "a64_fast_dispatch_table_lookup"); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h b/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h index 50737f12eb..13f3de21a1 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h +++ b/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h @@ -22,13 +22,11 @@ constexpr size_t SpillCount = 64; #endif struct alignas(16) StackLayout { + u64 abi_base_pointer; s64 cycles_remaining; s64 cycles_to_run; - std::array, SpillCount> spill; - u32 save_host_MXCSR; - bool check_bit; }; diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 668f939546..55084f0ff8 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt @@ -135,7 +135,7 @@ foreach(SOURCE_FILE IN ITEMS ${SHADER_FILES}) ${SOURCE_FILE} DEPENDS ${INPUT_FILE} - ${SHADER_DIR} + # ${SHADER_DIR} # HEADER_GENERATOR should be included here but msbuild seems to assume it's always modified ) set(SHADER_HEADERS ${SHADER_HEADERS} ${SOURCE_HEADER_FILE}) @@ -151,8 +151,8 @@ foreach(SOURCE_FILE IN ITEMS ${SHADER_FILES}) ${GLSLANGVALIDATOR} -V ${QUIET_FLAG} -I"${FIDELITYFX_INCLUDE_DIR}" ${GLSL_FLAGS} --variable-name ${SPIRV_VARIABLE_NAME} -o ${SPIRV_HEADER_FILE} ${SOURCE_FILE} --target-env ${SPIR_V_VERSION} MAIN_DEPENDENCY ${SOURCE_FILE} - DEPENDS - ${SHADER_DIR} + #DEPENDS + # ${SHADER_DIR} ) set(SHADER_HEADERS ${SHADER_HEADERS} ${SPIRV_HEADER_FILE}) endif() From 5368a54ed8131486d82f2f818d129873ddb0d278 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 19 Mar 2026 23:01:27 +0000 Subject: [PATCH 6/7] fix %rbp --- .../src/dynarmic/backend/x64/a32_emit_x64.cpp | 9 +++++---- .../src/dynarmic/backend/x64/a64_emit_x64.cpp | 17 +++++------------ .../src/dynarmic/backend/x64/stack_layout.h | 5 +++-- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp index f037919eb0..cd89b89156 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp @@ -115,6 +115,8 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) { // Start emitting. code.align(); const u8* const entrypoint = code.getCurr(); + code.mov(code.qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer)], rbp); + code.lea(rbp, code.ptr[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer) - 8]); EmitCondPrelude(ctx); @@ -147,15 +149,14 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) { reg_alloc.AssertNoMoreUses(); - if (conf.enable_cycle_counting) { + if (conf.enable_cycle_counting) EmitAddCycles(block.CycleCount()); - } + code.mov(rbp, code.qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer)]); EmitTerminal(block.GetTerminal(), ctx.Location().SetSingleStepping(false), ctx.IsSingleStep()); code.int3(); - for (auto& deferred_emit : ctx.deferred_emits) { + for (auto& deferred_emit : ctx.deferred_emits) deferred_emit(); - } code.int3(); const size_t size = size_t(code.getCurr() - entrypoint); diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp index d4f9d9daaf..f59026929e 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp @@ -89,9 +89,8 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) noexcept { // Start emitting. code.align(); const auto* const entrypoint = code.getCurr(); - - // code.mov(code.qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer)], rbp); - // code.lea(rbp, code.ptr[rsp + ABI_SHADOW_SPACE - 8]); + code.mov(code.qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer)], rbp); + code.lea(rbp, code.ptr[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer) - 8]); DEBUG_ASSERT(block.GetCondition() == IR::Cond::AL); typedef void (EmitX64::*EmitHandlerFn)(EmitContext& context, IR::Inst* inst); @@ -143,19 +142,13 @@ finish_this_inst: } reg_alloc.AssertNoMoreUses(); - - if (conf.enable_cycle_counting) { + if (conf.enable_cycle_counting) EmitAddCycles(block.CycleCount()); - } - - //code.mov(rbp, code.qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer)]); - + code.mov(rbp, code.qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer)]); EmitTerminal(block.GetTerminal(), ctx.Location().SetSingleStepping(false), ctx.IsSingleStep()); code.int3(); - - for (auto& deferred_emit : ctx.deferred_emits) { + for (auto& deferred_emit : ctx.deferred_emits) deferred_emit(); - } code.int3(); const size_t size = size_t(code.getCurr() - entrypoint); diff --git a/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h b/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h index 13f3de21a1..6e0efb5be0 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h +++ b/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h @@ -22,12 +22,13 @@ constexpr size_t SpillCount = 64; #endif struct alignas(16) StackLayout { - u64 abi_base_pointer; + // Needs alignment for VMOV and XMM spills + alignas(16) std::array, SpillCount> spill; s64 cycles_remaining; s64 cycles_to_run; - std::array, SpillCount> spill; u32 save_host_MXCSR; bool check_bit; + u64 abi_base_pointer; }; #ifdef _MSC_VER From 4707d8a26a077fd7cbb7012fa251fe8a33a983fb Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 20 Mar 2026 07:22:23 +0000 Subject: [PATCH 7/7] license --- src/dynarmic/src/dynarmic/backend/x64/stack_layout.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h b/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h index 6e0efb5be0..43a3fc7ab2 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h +++ b/src/dynarmic/src/dynarmic/backend/x64/stack_layout.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project.