From 6f106602ba6b28a07c1ab9588a04e6b53928a11a Mon Sep 17 00:00:00 2001 From: Merry Date: Wed, 20 Jul 2022 16:37:05 +0100 Subject: [PATCH] a32_get_set_elimination_pass: Add option to disable NZC -> NZ conversion --- src/dynarmic/backend/x64/a32_interface.cpp | 2 +- src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp | 4 ++-- src/dynarmic/ir/opt/passes.h | 6 +++++- tests/A32/fuzz_thumb.cpp | 2 +- tests/print_info.cpp | 4 ++-- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/dynarmic/backend/x64/a32_interface.cpp b/src/dynarmic/backend/x64/a32_interface.cpp index 9fdcaf5f..a33f26ea 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, {}); 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 6faa7997..24aa14ce 100644 --- a/src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp +++ b/src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp @@ -17,7 +17,7 @@ namespace Dynarmic::Optimization { -void A32GetSetElimination(IR::Block& block) { +void A32GetSetElimination(IR::Block& block, A32GetSetEliminationOptions opt) { using Iterator = IR::Block::iterator; struct RegisterInfo { IR::Value register_value; @@ -215,7 +215,7 @@ void A32GetSetElimination(IR::Block& block) { break; } case IR::Opcode::A32SetCpsrNZC: { - if (!inst->GetArg(1).IsImmediate() && inst->GetArg(1).GetInstRecursive()->GetOpcode() == IR::Opcode::A32GetCFlag) { + if (opt.convert_nzc_to_nz && !inst->GetArg(1).IsImmediate() && inst->GetArg(1).GetInstRecursive()->GetOpcode() == IR::Opcode::A32GetCFlag) { ir.SetInsertionPoint(inst); ir.SetCpsrNZ(IR::NZCV{inst->GetArg(0)}); inst->Invalidate(); diff --git a/src/dynarmic/ir/opt/passes.h b/src/dynarmic/ir/opt/passes.h index ad5d09df..c865ea04 100644 --- a/src/dynarmic/ir/opt/passes.h +++ b/src/dynarmic/ir/opt/passes.h @@ -26,9 +26,13 @@ struct PolyfillOptions { bool operator==(const PolyfillOptions&) const = default; }; +struct A32GetSetEliminationOptions { + bool convert_nzc_to_nz = false; +}; + void PolyfillPass(IR::Block& block, const PolyfillOptions& opt); void A32ConstantMemoryReads(IR::Block& block, A32::UserCallbacks* cb); -void A32GetSetElimination(IR::Block& block); +void A32GetSetElimination(IR::Block& block, A32GetSetEliminationOptions opt); void A64CallbackConfigPass(IR::Block& block, const A64::UserConfig& conf); void A64GetSetElimination(IR::Block& block); void A64MergeInterpretBlocksPass(IR::Block& block, A64::UserCallbacks* cb); diff --git a/tests/A32/fuzz_thumb.cpp b/tests/A32/fuzz_thumb.cpp index d412b97e..fef94abb 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