From 4e87268295a4ca7258fe4a82828a93d455d6c0ec Mon Sep 17 00:00:00 2001 From: lizzie Date: Mon, 27 Apr 2026 23:42:29 +0000 Subject: [PATCH] suboptimal cgen for windows --- .../src/dynarmic/common/spin_lock_x64.cpp | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp b/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp index 3320c9a128..b41884c579 100644 --- a/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp +++ b/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp @@ -27,6 +27,7 @@ namespace Dynarmic { /// @arg waitpkg Whetever or not the "UMWAIT" instruction can be used void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Address ptr, Xbyak::Reg32 tmp, bool waitpkg) { // TODO: this is because we lack regalloc - so better to be safe :( + // TODO: really involve regalloc when we require a 64 bit disp temporal... aside from the one we got handed of course if (waitpkg) { Xbyak::Label start, loop; code.jmp(start, code.T_NEAR); @@ -56,7 +57,18 @@ void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Address ptr, Xbyak::Reg code.pop(Xbyak::util::eax); code.L(start); code.mov(tmp, 1); - /*code.lock();*/ code.xchg(ptr, tmp); + if (ptr.is64bitDisp()) { + // if tmp is on eax, use ebx, otherwise use eax! + auto const other_tmp = tmp == Xbyak::util::eax + ? Xbyak::util::ebx + : Xbyak::util::eax; + code.push(other_tmp); + code.mov(other_tmp, ptr.getDisp()); + /*code.lock();*/ code.xchg(other_tmp, tmp); + code.pop(other_tmp); + } else { + /*code.lock();*/ code.xchg(ptr, tmp); + } code.test(tmp, tmp); code.jnz(loop, code.T_NEAR); } else { @@ -66,7 +78,18 @@ void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Address ptr, Xbyak::Reg code.pause(); code.L(start); code.mov(tmp, 1); - /*code.lock();*/ code.xchg(ptr, tmp); + if (ptr.is64bitDisp()) { + // if tmp is on eax, use ebx, otherwise use eax! + auto const other_tmp = tmp == Xbyak::util::eax + ? Xbyak::util::ebx + : Xbyak::util::eax; + code.push(other_tmp); + code.mov(other_tmp, ptr.getDisp()); + /*code.lock();*/ code.xchg(other_tmp, tmp); + code.pop(other_tmp); + } else { + /*code.lock();*/ code.xchg(ptr, tmp); + } code.test(tmp, tmp); code.jnz(loop, code.T_NEAR); }