mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-23 07:44:18 +00:00
[dynarmic] fix MWAIT push/pop not being handled properly on xbyak (#3875)
push %edx is not what i wanted, nor what anybody wants, xbyak silently accepting this before was not intended now that xbyak is updated this is an issue the issue was simply: a) ptr being overwritten (if it happened to be EDX/EBX/EAX) due to changed WAITPKG logic (oops) b) xbyak not reporting wrong r32 pop/push on older versions thus missing it and now it throws an exception Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3875 Reviewed-by: crueter <crueter@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
This commit is contained in:
parent
838cc926f6
commit
417ed904f0
|
|
@ -23,16 +23,14 @@ static const auto default_cg_mode = nullptr; //Allow RWE
|
||||||
namespace Dynarmic {
|
namespace Dynarmic {
|
||||||
|
|
||||||
void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 tmp, bool waitpkg) {
|
void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 tmp, bool waitpkg) {
|
||||||
// TODO: this is because we lack regalloc - so better to be safe :(
|
|
||||||
if (waitpkg) {
|
|
||||||
code.push(Xbyak::util::eax);
|
|
||||||
code.push(Xbyak::util::ebx);
|
|
||||||
code.push(Xbyak::util::edx);
|
|
||||||
}
|
|
||||||
Xbyak::Label start, loop;
|
Xbyak::Label start, loop;
|
||||||
code.jmp(start, code.T_NEAR);
|
code.jmp(start, code.T_NEAR);
|
||||||
code.L(loop);
|
code.L(loop);
|
||||||
if (waitpkg) {
|
if (waitpkg) {
|
||||||
|
// TODO: this is because we lack regalloc - so better to be safe :(
|
||||||
|
code.push(Xbyak::util::rax);
|
||||||
|
code.push(Xbyak::util::rbx);
|
||||||
|
code.push(Xbyak::util::rdx);
|
||||||
// TODO: This clobbers EAX and EDX did we tell the regalloc?
|
// TODO: This clobbers EAX and EDX did we tell the regalloc?
|
||||||
// ARM ptr for address-monitoring
|
// ARM ptr for address-monitoring
|
||||||
code.umonitor(ptr);
|
code.umonitor(ptr);
|
||||||
|
|
@ -49,6 +47,9 @@ void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32
|
||||||
code.umwait(Xbyak::util::ebx);
|
code.umwait(Xbyak::util::ebx);
|
||||||
// CF == 1 if we hit the OS-timeout in IA32_UMWAIT_CONTROL without a write
|
// CF == 1 if we hit the OS-timeout in IA32_UMWAIT_CONTROL without a write
|
||||||
// CF == 0 if we exited the wait for any other reason
|
// CF == 0 if we exited the wait for any other reason
|
||||||
|
code.pop(Xbyak::util::rdx);
|
||||||
|
code.pop(Xbyak::util::rbx);
|
||||||
|
code.pop(Xbyak::util::rax);
|
||||||
} else {
|
} else {
|
||||||
code.pause();
|
code.pause();
|
||||||
}
|
}
|
||||||
|
|
@ -57,11 +58,6 @@ void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32
|
||||||
/*code.lock();*/ code.xchg(code.dword[ptr], tmp);
|
/*code.lock();*/ code.xchg(code.dword[ptr], tmp);
|
||||||
code.test(tmp, tmp);
|
code.test(tmp, tmp);
|
||||||
code.jnz(loop, code.T_NEAR);
|
code.jnz(loop, code.T_NEAR);
|
||||||
if (waitpkg) {
|
|
||||||
code.pop(Xbyak::util::edx);
|
|
||||||
code.pop(Xbyak::util::ebx);
|
|
||||||
code.pop(Xbyak::util::eax);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSpinLockUnlock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 tmp) {
|
void EmitSpinLockUnlock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 tmp) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue