diff --git a/src/backend_x64/a64_emit_x64.cpp b/src/backend_x64/a64_emit_x64.cpp index ae88f850..188cf0f0 100644 --- a/src/backend_x64/a64_emit_x64.cpp +++ b/src/backend_x64/a64_emit_x64.cpp @@ -896,7 +896,7 @@ void A64EmitX64::EmitExclusiveWrite(A64EmitContext& ctx, IR::Inst* inst, size_t )); break; case 128: - code.sub(rsp, 8 + 16 + ABI_SHADOW_SPACE); + code.sub(rsp, 16 + ABI_SHADOW_SPACE); code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]); code.movaps(xword[code.ABI_PARAM3], xmm0); code.CallFunction(static_cast( @@ -906,7 +906,7 @@ void A64EmitX64::EmitExclusiveWrite(A64EmitContext& ctx, IR::Inst* inst, size_t }) ? 0 : 1; } )); - code.add(rsp, 8 + 16 + ABI_SHADOW_SPACE); + code.add(rsp, 16 + ABI_SHADOW_SPACE); break; default: UNREACHABLE(); diff --git a/tests/A64/a64.cpp b/tests/A64/a64.cpp index ccceed8e..9f71eb95 100644 --- a/tests/A64/a64.cpp +++ b/tests/A64/a64.cpp @@ -6,6 +6,8 @@ #include +#include + #include "testenv.h" TEST_CASE("A64: ADD", "[a64]") { @@ -274,3 +276,40 @@ TEST_CASE("A64: FABD", "[a64]") { REQUIRE(jit.GetVector(22) == Vector{0x56d3f0857fc90e2b, 0x6e4b0a4144873176}); } + +TEST_CASE("A64: 128-bit exclusive read/write", "[a64]") { + TestEnv env; + Dynarmic::A64::ExclusiveMonitor monitor{1}; + + Dynarmic::A64::UserConfig conf; + conf.callbacks = &env; + conf.processor_id = 0; + + SECTION("Local Monitor Only") { + conf.global_monitor = nullptr; + } + SECTION("Global Monitor") { + conf.global_monitor = &monitor; + } + + Dynarmic::A64::Jit jit{conf}; + + env.code_mem[0] = 0xc87f0861; // LDXP X1, X2, [X3] + env.code_mem[1] = 0xc8241865; // STXP W4, X5, X6, [X3] + env.code_mem[2] = 0x14000000; // B . + + jit.SetPC(0); + jit.SetRegister(3, 0x1234567812345678); + jit.SetRegister(4, 0xbaadbaadbaadbaad); + jit.SetRegister(5, 0xaf00d1e5badcafe0); + jit.SetRegister(6, 0xd0d0cacad0d0caca); + + env.ticks_left = 3; + jit.Run(); + + REQUIRE(jit.GetRegister(1) == 0x7f7e7d7c7b7a7978); + REQUIRE(jit.GetRegister(2) == 0x8786858483828180); + REQUIRE(jit.GetRegister(4) == 0); + REQUIRE(env.MemoryRead64(0x1234567812345678) == 0xaf00d1e5badcafe0); + REQUIRE(env.MemoryRead64(0x1234567812345680) == 0xd0d0cacad0d0caca); +}