a64_emit_x64: Fix stack misalignment on Windows for 128-bit exclusive writes
Discovered by @Subv. Includes a test to ensure this codepath is exercised on Windows.
This commit is contained in:
parent
04b4c8b0cf
commit
edd795e991
2 changed files with 41 additions and 2 deletions
|
@ -896,7 +896,7 @@ void A64EmitX64::EmitExclusiveWrite(A64EmitContext& ctx, IR::Inst* inst, size_t
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
case 128:
|
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.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]);
|
||||||
code.movaps(xword[code.ABI_PARAM3], xmm0);
|
code.movaps(xword[code.ABI_PARAM3], xmm0);
|
||||||
code.CallFunction(static_cast<u32(*)(A64::UserConfig&, u64, A64::Vector&)>(
|
code.CallFunction(static_cast<u32(*)(A64::UserConfig&, u64, A64::Vector&)>(
|
||||||
|
@ -906,7 +906,7 @@ void A64EmitX64::EmitExclusiveWrite(A64EmitContext& ctx, IR::Inst* inst, size_t
|
||||||
}) ? 0 : 1;
|
}) ? 0 : 1;
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
code.add(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
code.add(rsp, 16 + ABI_SHADOW_SPACE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
#include <dynarmic/A64/exclusive_monitor.h>
|
||||||
|
|
||||||
#include "testenv.h"
|
#include "testenv.h"
|
||||||
|
|
||||||
TEST_CASE("A64: ADD", "[a64]") {
|
TEST_CASE("A64: ADD", "[a64]") {
|
||||||
|
@ -274,3 +276,40 @@ TEST_CASE("A64: FABD", "[a64]") {
|
||||||
|
|
||||||
REQUIRE(jit.GetVector(22) == Vector{0x56d3f0857fc90e2b, 0x6e4b0a4144873176});
|
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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue