From 0c5131347984a59bcf0293a3d7a1f19d94a23be6 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sun, 19 Apr 2020 15:54:46 +0100 Subject: [PATCH] A64: Add enable_optimizations configuration option Allow library users to disable optimizations for debugging reasons. --- include/dynarmic/A64/config.h | 8 ++++++++ src/backend/x64/a64_emit_x64.cpp | 27 +++++++++++++++++++++++++++ src/backend/x64/a64_emit_x64.h | 1 + src/backend/x64/a64_interface.cpp | 10 ++++++---- 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/include/dynarmic/A64/config.h b/include/dynarmic/A64/config.h index 8ca00632..b997f237 100644 --- a/include/dynarmic/A64/config.h +++ b/include/dynarmic/A64/config.h @@ -116,6 +116,14 @@ struct UserConfig { size_t processor_id = 0; ExclusiveMonitor* global_monitor = nullptr; + /// When set to false, this disables all optimizations than can't otherwise be disabled + /// by setting other configuration options. This includes: + /// - IR optimizations + /// - Block linking optimizations + /// - RSB optimizations + /// This is intended to be used for debugging. + bool enable_optimizations = true; + /// When set to true, UserCallbacks::DataCacheOperationRaised will be called when any /// data cache instruction is executed. Notably DC ZVA will not implicitly do anything. /// When set to false, UserCallbacks::DataCacheOperationRaised will never be called. diff --git a/src/backend/x64/a64_emit_x64.cpp b/src/backend/x64/a64_emit_x64.cpp index 1266ed31..e8d25949 100644 --- a/src/backend/x64/a64_emit_x64.cpp +++ b/src/backend/x64/a64_emit_x64.cpp @@ -350,6 +350,14 @@ void A64EmitX64::GenTerminalHandlers() { } } +void A64EmitX64::EmitPushRSB(EmitContext& ctx, IR::Inst* inst) { + if (!conf.enable_optimizations) { + return; + } + + EmitX64::EmitPushRSB(ctx, inst); +} + void A64EmitX64::EmitA64SetCheckBit(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); const Xbyak::Reg8 to_store = ctx.reg_alloc.UseGpr(args[0]).cvt8(); @@ -1156,6 +1164,13 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::ReturnToDispatch, IR::LocationDescri } void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDescriptor) { + if (!conf.enable_optimizations) { + code.mov(rax, A64::LocationDescriptor{terminal.next}.PC()); + code.mov(qword[r15 + offsetof(A64JitState, pc)], rax); + code.ReturnFromRunCode(); + return; + } + code.cmp(qword[r15 + offsetof(A64JitState, cycles_remaining)], 0); patch_information[terminal.next].jg.emplace_back(code.getCurr()); @@ -1170,6 +1185,13 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc } void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor) { + if (!conf.enable_optimizations) { + code.mov(rax, A64::LocationDescriptor{terminal.next}.PC()); + code.mov(qword[r15 + offsetof(A64JitState, pc)], rax); + code.ReturnFromRunCode(); + return; + } + patch_information[terminal.next].jmp.emplace_back(code.getCurr()); if (auto next_bb = GetBasicBlock(terminal.next)) { EmitPatchJmp(terminal.next, next_bb->entrypoint); @@ -1179,6 +1201,11 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::Location } void A64EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor) { + if (!conf.enable_optimizations) { + code.ReturnFromRunCode(); + return; + } + code.jmp(terminal_handler_pop_rsb_hint); } diff --git a/src/backend/x64/a64_emit_x64.h b/src/backend/x64/a64_emit_x64.h index 5c837aa2..13478eee 100644 --- a/src/backend/x64/a64_emit_x64.h +++ b/src/backend/x64/a64_emit_x64.h @@ -79,6 +79,7 @@ protected: void EmitExclusiveWrite(A64EmitContext& ctx, IR::Inst* inst, size_t bitsize); // Microinstruction emitters + void EmitPushRSB(EmitContext& ctx, IR::Inst* inst); #define OPCODE(...) #define A32OPC(...) #define A64OPC(name, type, ...) void EmitA64##name(A64EmitContext& ctx, IR::Inst* inst); diff --git a/src/backend/x64/a64_interface.cpp b/src/backend/x64/a64_interface.cpp index d53b5b13..09e60581 100644 --- a/src/backend/x64/a64_interface.cpp +++ b/src/backend/x64/a64_interface.cpp @@ -231,10 +231,12 @@ private: const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); }; IR::Block ir_block = A64::Translate(A64::LocationDescriptor{current_location}, get_code, {conf.define_unpredictable_behaviour}); Optimization::A64CallbackConfigPass(ir_block, conf); - Optimization::A64GetSetElimination(ir_block); - Optimization::ConstantPropagation(ir_block); - Optimization::DeadCodeElimination(ir_block); - Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks); + if (conf.enable_optimizations) { + Optimization::A64GetSetElimination(ir_block); + Optimization::ConstantPropagation(ir_block); + Optimization::DeadCodeElimination(ir_block); + Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks); + } // printf("%s\n", IR::DumpBlock(ir_block).c_str()); Optimization::VerificationPass(ir_block); return emitter.Emit(ir_block).entrypoint;