From da2b1c5724f3ad5abe245e50063498f560346b39 Mon Sep 17 00:00:00 2001 From: Merry Date: Wed, 20 Jul 2022 16:45:14 +0100 Subject: [PATCH] a32_get_set_elimination_pass: Convert NZ to NZC --- src/dynarmic/backend/x64/a32_interface.cpp | 2 +- src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp | 7 +++++++ src/dynarmic/ir/opt/passes.h | 1 + tests/A32/fuzz_thumb.cpp | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dynarmic/backend/x64/a32_interface.cpp b/src/dynarmic/backend/x64/a32_interface.cpp index a33f26ea..5e7fa8e8 100644 --- a/src/dynarmic/backend/x64/a32_interface.cpp +++ b/src/dynarmic/backend/x64/a32_interface.cpp @@ -174,7 +174,7 @@ private: IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions}); Optimization::PolyfillPass(ir_block, polyfill_options); if (conf.HasOptimization(OptimizationFlag::GetSetElimination) && !conf.check_halt_on_memory_access) { - Optimization::A32GetSetElimination(ir_block, {}); + Optimization::A32GetSetElimination(ir_block, {.convert_nz_to_nzc = true}); Optimization::DeadCodeElimination(ir_block); } if (conf.HasOptimization(OptimizationFlag::ConstProp)) { diff --git a/src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp b/src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp index 24aa14ce..becf118d 100644 --- a/src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp +++ b/src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp @@ -208,6 +208,13 @@ void A32GetSetElimination(IR::Block& block, A32GetSetEliminationOptions opt) { cpsr_info.nzc.last_set_instruction->SetArg(0, IR::Value::EmptyNZCVImmediateMarker()); } + if (opt.convert_nz_to_nzc && !cpsr_info.c.register_value.IsEmpty()) { + ir.SetInsertionPoint(inst); + ir.SetCpsrNZC(IR::NZCV{inst->GetArg(0)}, ir.GetCFlag()); + inst->Invalidate(); + break; + } + // cpsr_info.c remains valid cpsr_info.nzc = {}; cpsr_info.nzcv = {}; diff --git a/src/dynarmic/ir/opt/passes.h b/src/dynarmic/ir/opt/passes.h index c865ea04..08bfe4fe 100644 --- a/src/dynarmic/ir/opt/passes.h +++ b/src/dynarmic/ir/opt/passes.h @@ -28,6 +28,7 @@ struct PolyfillOptions { struct A32GetSetEliminationOptions { bool convert_nzc_to_nz = false; + bool convert_nz_to_nzc = false; }; void PolyfillPass(IR::Block& block, const PolyfillOptions& opt); diff --git a/tests/A32/fuzz_thumb.cpp b/tests/A32/fuzz_thumb.cpp index fef94abb..ff68f2f2 100644 --- a/tests/A32/fuzz_thumb.cpp +++ b/tests/A32/fuzz_thumb.cpp @@ -176,7 +176,7 @@ static void RunInstance(size_t run_number, ThumbTestEnv& test_env, A32Unicorn