From c87986b276155e6f484b5a1fe2f96fc391592a8d Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 12 Feb 2026 01:32:55 +0100 Subject: [PATCH] [dynarmic] reuse IR::Block memory instead of creating new block each time (#3501) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3501 Reviewed-by: DraVee Reviewed-by: CamilleLaVey Co-authored-by: lizzie Co-committed-by: lizzie --- .../backend/arm64/a32_address_space.cpp | 8 +++--- .../backend/arm64/a32_address_space.h | 5 +++- .../backend/arm64/a64_address_space.cpp | 9 +++---- .../backend/arm64/a64_address_space.h | 5 +++- .../dynarmic/backend/arm64/address_space.cpp | 16 ++++++------ .../dynarmic/backend/arm64/address_space.h | 5 ++-- .../backend/riscv64/a32_address_space.cpp | 10 ++++---- .../backend/riscv64/a32_address_space.h | 5 +++- .../dynarmic/backend/x64/a32_interface.cpp | 25 +++++++++++-------- .../dynarmic/backend/x64/a64_interface.cpp | 22 ++++++++-------- .../frontend/A32/translate/a32_translate.cpp | 11 +++++--- .../frontend/A32/translate/a32_translate.h | 4 +-- .../frontend/A32/translate/translate_arm.cpp | 11 ++------ .../A32/translate/translate_thumb.cpp | 12 +++------ .../frontend/A64/translate/a64_translate.cpp | 10 ++------ .../frontend/A64/translate/a64_translate.h | 4 +-- src/dynarmic/src/dynarmic/ir/basic_block.h | 12 +++++++++ 17 files changed, 93 insertions(+), 81 deletions(-) diff --git a/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.cpp b/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.cpp index db2d536f68..274e553cd8 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -164,10 +164,10 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf) EmitPrelude(); } -IR::Block A32AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const { - IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions}); +void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const { + ir_block.Reset(descriptor); + A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions}); Optimization::Optimize(ir_block, conf, {}); - return ir_block; } void A32AddressSpace::InvalidateCacheRanges(const boost::icl::interval_set& ranges) { diff --git a/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.h b/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.h index 3b9e9fb2f6..e7a8d01e17 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.h +++ b/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2022 MerryMage * SPDX-License-Identifier: 0BSD @@ -17,7 +20,7 @@ class A32AddressSpace final : public AddressSpace { public: explicit A32AddressSpace(const A32::UserConfig& conf); - IR::Block GenerateIR(IR::LocationDescriptor) const override; + void GenerateIR(IR::Block& ir_block, IR::LocationDescriptor) const override; void InvalidateCacheRanges(const boost::icl::interval_set& ranges); diff --git a/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp b/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp index 1b1242a7e7..a5a8306a6d 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -330,12 +330,11 @@ A64AddressSpace::A64AddressSpace(const A64::UserConfig& conf) EmitPrelude(); } -IR::Block A64AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const { +void A64AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const { + ir_block.Reset(descriptor); const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); }; - IR::Block ir_block = A64::Translate(A64::LocationDescriptor{descriptor}, get_code, - {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct}); + A64::Translate(ir_block, A64::LocationDescriptor{descriptor}, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct}); Optimization::Optimize(ir_block, conf, {}); - return ir_block; } void A64AddressSpace::InvalidateCacheRanges(const boost::icl::interval_set& ranges) { diff --git a/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.h b/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.h index 86eae4dd39..512894fdce 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.h +++ b/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2022 MerryMage * SPDX-License-Identifier: 0BSD @@ -17,7 +20,7 @@ class A64AddressSpace final : public AddressSpace { public: explicit A64AddressSpace(const A64::UserConfig& conf); - IR::Block GenerateIR(IR::LocationDescriptor) const override; + void GenerateIR(IR::Block& ir_block, IR::LocationDescriptor) const override; void InvalidateCacheRanges(const boost::icl::interval_set& ranges); diff --git a/src/dynarmic/src/dynarmic/backend/arm64/address_space.cpp b/src/dynarmic/src/dynarmic/backend/arm64/address_space.cpp index 67be731b18..6b59871b0a 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/address_space.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -20,14 +20,17 @@ #include "dynarmic/common/fp/fpcr.h" #include "dynarmic/common/llvm_disassemble.h" #include "dynarmic/interface/exclusive_monitor.h" +#include "dynarmic/ir/location_descriptor.h" namespace Dynarmic::Backend::Arm64 { AddressSpace::AddressSpace(size_t code_cache_size) - : code_cache_size(code_cache_size) - , mem(code_cache_size) - , code(mem.ptr(), mem.ptr()) - , fastmem_manager(exception_handler) { + : ir_block{IR::LocationDescriptor{0}} + , code_cache_size(code_cache_size) + , mem(code_cache_size) + , code(mem.ptr(), mem.ptr()) + , fastmem_manager(exception_handler) +{ ASSERT(code_cache_size <= 128 * 1024 * 1024 && "code_cache_size > 128 MiB not currently supported"); exception_handler.Register(mem, code_cache_size); @@ -67,8 +70,7 @@ CodePtr AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) { if (CodePtr block_entry = Get(descriptor)) { return block_entry; } - - IR::Block ir_block = GenerateIR(descriptor); + GenerateIR(ir_block, descriptor); const EmittedBlockInfo block_info = Emit(std::move(ir_block)); return block_info.entry_point; } diff --git a/src/dynarmic/src/dynarmic/backend/arm64/address_space.h b/src/dynarmic/src/dynarmic/backend/arm64/address_space.h index d7d8cf38b6..9fe9595c65 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/address_space.h +++ b/src/dynarmic/src/dynarmic/backend/arm64/address_space.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -29,7 +29,7 @@ public: explicit AddressSpace(size_t code_cache_size); virtual ~AddressSpace(); - virtual IR::Block GenerateIR(IR::LocationDescriptor) const = 0; + virtual void GenerateIR(IR::Block& ir_block, IR::LocationDescriptor) const = 0; CodePtr Get(IR::LocationDescriptor descriptor); @@ -68,6 +68,7 @@ protected: FakeCall FastmemCallback(u64 host_pc); + IR::Block ir_block; const size_t code_cache_size; oaknut::CodeBlock mem; oaknut::CodeGenerator code; diff --git a/src/dynarmic/src/dynarmic/backend/riscv64/a32_address_space.cpp b/src/dynarmic/src/dynarmic/backend/riscv64/a32_address_space.cpp index 8cde0049d8..05f43774b6 100644 --- a/src/dynarmic/src/dynarmic/backend/riscv64/a32_address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/riscv64/a32_address_space.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -26,10 +26,9 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf) EmitPrelude(); } -IR::Block A32AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const { - IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions}); +void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const { + A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions}); Optimization::Optimize(ir_block, conf, {}); - return ir_block; } CodePtr A32AddressSpace::Get(IR::LocationDescriptor descriptor) { @@ -44,7 +43,8 @@ CodePtr A32AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) { return block_entry; } - IR::Block ir_block = GenerateIR(descriptor); + IR::Block ir_block{descriptor}; + GenerateIR(ir_block, descriptor); const EmittedBlockInfo block_info = Emit(std::move(ir_block)); block_infos.insert_or_assign(descriptor.Value(), block_info); diff --git a/src/dynarmic/src/dynarmic/backend/riscv64/a32_address_space.h b/src/dynarmic/src/dynarmic/backend/riscv64/a32_address_space.h index e583dae61f..24148b192c 100644 --- a/src/dynarmic/src/dynarmic/backend/riscv64/a32_address_space.h +++ b/src/dynarmic/src/dynarmic/backend/riscv64/a32_address_space.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2024 MerryMage * SPDX-License-Identifier: 0BSD @@ -23,7 +26,7 @@ class A32AddressSpace final { public: explicit A32AddressSpace(const A32::UserConfig& conf); - IR::Block GenerateIR(IR::LocationDescriptor) const; + void GenerateIR(IR::Block& ir_block, IR::LocationDescriptor) const; CodePtr Get(IR::LocationDescriptor descriptor); diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp b/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp index fbfdf24521..d56e3729ee 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -25,6 +25,7 @@ #include "dynarmic/backend/x64/devirtualize.h" #include "dynarmic/backend/x64/jitstate_info.h" #include "dynarmic/common/atomic.h" +#include "dynarmic/frontend/A32/a32_location_descriptor.h" #include "dynarmic/frontend/A32/translate/a32_translate.h" #include "dynarmic/interface/A32/a32.h" #include "dynarmic/ir/basic_block.h" @@ -63,12 +64,14 @@ static Optimization::PolyfillOptions GenPolyfillOptions(const BlockOfCode& code) } struct Jit::Impl { - Impl(Jit* jit, A32::UserConfig conf) - : block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf)) - , emitter(block_of_code, conf, jit) - , polyfill_options(GenPolyfillOptions(block_of_code)) - , conf(std::move(conf)) - , jit_interface(jit) {} + Impl(Jit* jit, A32::UserConfig conf) noexcept + : ir_block{LocationDescriptor(0, PSR(0), FPSCR(0), false)} + , conf(std::move(conf)) + , block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf)) + , emitter(block_of_code, conf, jit) + , polyfill_options(GenPolyfillOptions(block_of_code)) + , jit_interface(jit) + {} ~Impl() = default; @@ -212,7 +215,8 @@ private: } block_of_code.EnsureMemoryCommitted(MINIMUM_REMAINING_CODESIZE); - IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions}); + ir_block.Reset(descriptor); + A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions}); Optimization::Optimize(ir_block, conf, polyfill_options); return emitter.Emit(ir_block); } @@ -239,13 +243,12 @@ private: } } + IR::Block ir_block; + const A32::UserConfig conf; A32JitState jit_state; BlockOfCode block_of_code; A32EmitX64 emitter; Optimization::PolyfillOptions polyfill_options; - - const A32::UserConfig conf; - Jit* jit_interface; // Requests made during execution to invalidate the cache are queued up here. diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp index 0fe738e212..d0dc736b73 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -12,6 +12,7 @@ #include #include "dynarmic/common/assert.h" +#include "dynarmic/common/fp/fpcr.h" #include "dynarmic/common/llvm_disassemble.h" #include #include @@ -61,10 +62,12 @@ static Optimization::PolyfillOptions GenPolyfillOptions(const BlockOfCode& code) struct Jit::Impl final { public: Impl(Jit* jit, UserConfig conf) - : conf(conf) - , block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf)) - , emitter(block_of_code, conf, jit) - , polyfill_options(GenPolyfillOptions(block_of_code)) { + : ir_block{LocationDescriptor(0, FP::FPCR(0), false)} + , conf(conf) + , block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf)) + , emitter(block_of_code, conf, jit) + , polyfill_options(GenPolyfillOptions(block_of_code)) + { ASSERT(conf.page_table_address_space_bits >= 12 && conf.page_table_address_space_bits <= 64); } @@ -268,8 +271,8 @@ private: // JIT Compile 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, conf.wall_clock_cntpct}); + ir_block.Reset(current_location); + A64::Translate(ir_block, A64::LocationDescriptor{current_location}, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct}); Optimization::Optimize(ir_block, conf, polyfill_options); return emitter.Emit(ir_block).entrypoint; } @@ -296,14 +299,13 @@ private: } } - bool is_executing = false; - + IR::Block ir_block; const UserConfig conf; A64JitState jit_state; BlockOfCode block_of_code; A64EmitX64 emitter; Optimization::PolyfillOptions polyfill_options; - + bool is_executing = false; bool invalidate_entire_cache = false; boost::icl::interval_set invalid_cache_ranges; std::mutex invalidation_mutex; diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.cpp index 2e69927ace..c3b90717a1 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2016 MerryMage * SPDX-License-Identifier: 0BSD @@ -10,11 +13,11 @@ namespace Dynarmic::A32 { -IR::Block TranslateArm(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options); -IR::Block TranslateThumb(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options); +void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options); +void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options); -IR::Block Translate(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) { - return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(descriptor, tcb, options); +void Translate(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) { + return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(block, descriptor, tcb, options); } bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction); diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.h b/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.h index df0b86e9ff..33e641fcaf 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.h +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -41,7 +41,7 @@ struct TranslationOptions { * @param options Configures how certain instructions are translated. * @return A translated basic block in the intermediate representation. */ -IR::Block Translate(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options); +void Translate(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options); /** * This function translates a single provided instruction into our intermediate representation. diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp index 614c1d2792..5cc9ef3893 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -22,12 +22,9 @@ namespace Dynarmic::A32 { -IR::Block TranslateArm(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) { +void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) { const bool single_step = descriptor.SingleStepping(); - - IR::Block block{descriptor}; TranslatorVisitor visitor{block, descriptor, options}; - bool should_continue = true; do { const u32 arm_pc = visitor.ir.current_location.PC(); @@ -76,12 +73,8 @@ IR::Block TranslateArm(LocationDescriptor descriptor, TranslateCallbacks* tcb, c } } } - ASSERT(block.HasTerminal() && "Terminal has not been set"); - block.SetEndLocation(visitor.ir.current_location); - - return block; } bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descriptor, u32 arm_instruction) { diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp index 23935ba601..e0333e487d 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -24,6 +24,7 @@ #include "dynarmic/frontend/A32/translate/translate_callbacks.h" #include "dynarmic/frontend/imm.h" #include "dynarmic/interface/A32/config.h" +#include "dynarmic/ir/basic_block.h" namespace Dynarmic::A32 { namespace { @@ -103,12 +104,9 @@ inline bool MaybeVFPOrASIMDInstruction(u32 thumb_instruction) noexcept { } // namespace -IR::Block TranslateThumb(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) { +void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) { const bool single_step = descriptor.SingleStepping(); - - IR::Block block{descriptor}; TranslatorVisitor visitor{block, descriptor, options}; - bool should_continue = true; do { const u32 arm_pc = visitor.ir.current_location.PC(); @@ -175,12 +173,8 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, TranslateCallbacks* tcb, } } } - ASSERT(block.HasTerminal() && "Terminal has not been set"); - block.SetEndLocation(visitor.ir.current_location); - - return block; } bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descriptor, u32 thumb_instruction) { diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp index 8a907acad6..e8d815518c 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -16,10 +16,8 @@ namespace Dynarmic::A64 { -IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options) { +void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options) { const bool single_step = descriptor.SingleStepping(); - - IR::Block block{descriptor}; TranslatorVisitor visitor{block, descriptor, std::move(options)}; bool should_continue = true; @@ -43,12 +41,8 @@ IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory if (single_step && should_continue) { visitor.ir.SetTerm(IR::Term::LinkBlock{*visitor.ir.current_location}); } - ASSERT(block.HasTerminal() && "Terminal has not been set"); - block.SetEndLocation(*visitor.ir.current_location); - - return block; } bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction) { diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.h b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.h index be55fb3970..125979f8b7 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.h +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -47,7 +47,7 @@ struct TranslationOptions { * @param options Configures how certain instructions are translated. * @return A translated basic block in the intermediate representation. */ -IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options); +void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options); /** * This function translates a single provided instruction into our intermediate representation. diff --git a/src/dynarmic/src/dynarmic/ir/basic_block.h b/src/dynarmic/src/dynarmic/ir/basic_block.h index 4fb28592e7..24115be1ec 100644 --- a/src/dynarmic/src/dynarmic/ir/basic_block.h +++ b/src/dynarmic/src/dynarmic/ir/basic_block.h @@ -140,6 +140,18 @@ public: return cycle_count; } + inline void Reset(LocationDescriptor location_) noexcept { + inlined_inst.clear(); + pooled_inst.clear(); + cond_failed.reset(); + location = location_; + terminal = Term::Invalid{}; + cond_failed_cycle_count = 0; + cycle_count = 0; + instruction_list_type tmp{}; + instructions.swap(tmp); + } + /// "Hot cache" for small blocks so we don't call global allocator boost::container::static_vector inlined_inst; /// List of instructions in this block.