From 6d4333c78efcfb4e56f1c4652ed98e7f84239ca7 Mon Sep 17 00:00:00 2001 From: emuplz <3116769+emuplz@users.noreply.github.com> Date: Thu, 12 Nov 2020 16:15:33 +0000 Subject: [PATCH] fixed data + instruction cache callbacks (w/ tests) --- src/backend/x64/a64_emit_x64.cpp | 4 ++-- tests/A64/a64.cpp | 28 ++++++++++++++++++++++++++++ tests/A64/testenv.h | 2 +- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/backend/x64/a64_emit_x64.cpp b/src/backend/x64/a64_emit_x64.cpp index c834ee87..20514599 100644 --- a/src/backend/x64/a64_emit_x64.cpp +++ b/src/backend/x64/a64_emit_x64.cpp @@ -647,13 +647,13 @@ void A64EmitX64::EmitA64ExceptionRaised(A64EmitContext& ctx, IR::Inst* inst) { void A64EmitX64::EmitA64DataCacheOperationRaised(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - ctx.reg_alloc.HostCall(nullptr, args[0], args[1]); + ctx.reg_alloc.HostCall(nullptr, {}, args[0], args[1]); Devirtualize<&A64::UserCallbacks::DataCacheOperationRaised>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64InstructionCacheOperationRaised(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - ctx.reg_alloc.HostCall(nullptr, args[0], args[1]); + ctx.reg_alloc.HostCall(nullptr, {}, args[0], args[1]); Devirtualize<&A64::UserCallbacks::InstructionCacheOperationRaised>(conf.callbacks).EmitCall(code); } diff --git a/tests/A64/a64.cpp b/tests/A64/a64.cpp index 1cdb7628..524be36e 100644 --- a/tests/A64/a64.cpp +++ b/tests/A64/a64.cpp @@ -634,3 +634,31 @@ TEST_CASE("A64: Optimization failure when folding ADD", "[a64]") { REQUIRE(jit.GetPstate() == 0x20000000); REQUIRE(jit.GetVector(30) == Vector{0xf7f6f5f4, 0}); } + +TEST_CASE("A64: Cache Maintenance Instructions", "[a64]") { + class CacheMaintenanceTestEnv final : public A64TestEnv { + void InstructionCacheOperationRaised(A64::InstructionCacheOperation op, VAddr value) override { + REQUIRE(op == A64::InstructionCacheOperation::InvalidateByVAToPoU); + REQUIRE(value == 0xcafed00d); + } + void DataCacheOperationRaised(A64::DataCacheOperation op, VAddr value) override { + REQUIRE(op == A64::DataCacheOperation::InvalidateByVAToPoC); + REQUIRE(value == 0xcafebabe); + } + }; + + CacheMaintenanceTestEnv env; + A64::UserConfig conf{&env}; + conf.hook_data_cache_operations = true; + A64::Jit jit{conf}; + + jit.SetRegister(0, 0xcafed00d); + jit.SetRegister(1, 0xcafebabe); + + env.code_mem.emplace_back(0xd50b7520); // ic ivau, x0 + env.code_mem.emplace_back(0xd5087621); // dc ivac, x1 + env.code_mem.emplace_back(0x14000000); // B . + + env.ticks_left = 3; + jit.Run(); +} diff --git a/tests/A64/testenv.h b/tests/A64/testenv.h index 6f416888..0eaf68ed 100644 --- a/tests/A64/testenv.h +++ b/tests/A64/testenv.h @@ -15,7 +15,7 @@ using Vector = Dynarmic::A64::Vector; -class A64TestEnv final : public Dynarmic::A64::UserCallbacks { +class A64TestEnv : public Dynarmic::A64::UserCallbacks { public: u64 ticks_left = 0;