From 60633c08af30f5f42cc381eade560932eabe402d Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 26 Sep 2026 16:50:55 +0000 Subject: [PATCH] 2026-09-26 16:50:55 Signed-off-by: lizzie --- .../backend/arm64/a32_address_space.cpp | 2 +- .../backend/arm64/a64_address_space.cpp | 3 +-- .../backend/loongarch64/a32_address_space.cpp | 2 +- .../backend/riscv64/a32_address_space.cpp | 2 +- .../dynarmic/backend/x64/a32_interface.cpp | 2 +- .../dynarmic/backend/x64/a64_interface.cpp | 3 +-- .../frontend/A32/translate/a32_translate.cpp | 9 ++++---- .../frontend/A32/translate/a32_translate.h | 19 +++------------ .../impl/a32_exception_generating.cpp | 5 +++- .../A32/translate/impl/a32_translate_impl.h | 9 +++++--- .../frontend/A32/translate/impl/hint.cpp | 17 ++++++++------ .../frontend/A32/translate/impl/thumb16.cpp | 10 ++++---- .../A32/translate/impl/thumb32_load_byte.cpp | 7 ++++-- .../frontend/A32/translate/translate_arm.cpp | 6 +++-- .../A32/translate/translate_thumb.cpp | 6 +++-- .../frontend/A64/translate/a64_translate.cpp | 7 +++--- .../frontend/A64/translate/a64_translate.h | 23 +++---------------- .../frontend/A64/translate/impl/impl.h | 9 +++++--- .../translate/impl/load_store_exclusive.cpp | 5 +++- .../frontend/A64/translate/impl/system.cpp | 12 +++++----- src/dynarmic/tests/A32/fuzz_thumb.cpp | 2 +- src/dynarmic/tests/A64/fuzz_with_unicorn.cpp | 2 +- 22 files changed, 77 insertions(+), 85 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 0cf9bb9fae..f06274acc6 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.cpp @@ -201,7 +201,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf) 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}); + A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf); Optimization::Optimize(ir_block, conf, {}); } 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 492242fa73..ff7f1b313f 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp @@ -366,8 +366,7 @@ A64AddressSpace::A64AddressSpace(const A64::UserConfig& conf) 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); }; - A64::Translate(ir_block, A64::LocationDescriptor{descriptor}, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct}); + A64::Translate(ir_block, A64::LocationDescriptor{descriptor}, conf); Optimization::Optimize(ir_block, conf, {}); } diff --git a/src/dynarmic/src/dynarmic/backend/loongarch64/a32_address_space.cpp b/src/dynarmic/src/dynarmic/backend/loongarch64/a32_address_space.cpp index f1a7d55d2c..b8ae04ed5d 100644 --- a/src/dynarmic/src/dynarmic/backend/loongarch64/a32_address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/loongarch64/a32_address_space.cpp @@ -21,7 +21,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf) } 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}); + A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf); Optimization::Optimize(ir_block, conf, {.sha256 = true}); } 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 490398931c..99aa45984d 100644 --- a/src/dynarmic/src/dynarmic/backend/riscv64/a32_address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/riscv64/a32_address_space.cpp @@ -27,7 +27,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf) } 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}); + A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf); Optimization::Optimize(ir_block, conf, {}); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp b/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp index 72627b9e1a..1faa882021 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp @@ -202,7 +202,7 @@ private: // LocationDescriptor ctor() does important ops (like tflags) do not skip auto const arch_descriptor = A32::LocationDescriptor{descriptor}; ir_block.Reset(arch_descriptor); - A32::Translate(ir_block, arch_descriptor, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions}); + A32::Translate(ir_block, arch_descriptor, conf); Optimization::Optimize(ir_block, conf, polyfill_options); return emitter.Emit(ir_block); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp index bb072129e7..163614df8a 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp @@ -254,11 +254,10 @@ private: block_of_code.EnsureMemoryCommitted(MINIMUM_REMAINING_CODESIZE); // JIT Compile - const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); }; // LocationDescriptor ctor() does important ops (like tflags) do not skip auto const arch_descriptor = A64::LocationDescriptor{descriptor}; ir_block.Reset(arch_descriptor); - A64::Translate(ir_block, arch_descriptor, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct}); + A64::Translate(ir_block, arch_descriptor, conf); Optimization::Optimize(ir_block, conf, polyfill_options); return emitter.Emit(ir_block).entrypoint; } 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 c3b90717a1..fa12472a2c 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.cpp @@ -9,15 +9,16 @@ #include "dynarmic/frontend/A32/translate/a32_translate.h" #include "dynarmic/frontend/A32/a32_location_descriptor.h" +#include "dynarmic/interface/A32/config.h" #include "dynarmic/ir/basic_block.h" namespace Dynarmic::A32 { -void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options); -void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options); +void TranslateArm(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf); +void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf); -void Translate(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) { - return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(block, descriptor, tcb, options); +void Translate(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf) { + return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(block, descriptor, conf); } 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 d39e80a54f..173b216210 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.h +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.h @@ -10,6 +10,7 @@ #include "common/common_types.h" #include "dynarmic/interface/A32/arch_version.h" +#include "dynarmic/interface/A32/config.h" namespace Dynarmic::IR { class Block; @@ -20,28 +21,14 @@ namespace Dynarmic::A32 { class LocationDescriptor; struct TranslateCallbacks; -struct TranslationOptions { - ArchVersion arch_version; - - /// This changes what IR we emit when we translate an unpredictable instruction. - /// If this is false, the ExceptionRaised IR instruction is emitted. - /// If this is true, we define some behaviour for some instructions. - bool define_unpredictable_behaviour = false; - - /// This changes what IR we emit when we translate a hint instruction. - /// If this is false, we treat the instruction as a NOP. - /// If this is true, we emit an ExceptionRaised instruction. - bool hook_hint_instructions = true; -}; - /** * This function translates instructions in memory into our intermediate representation. * @param descriptor The starting location of the basic block. Includes information like PC, Thumb state, &c. * @param tcb The callbacks we should use to read emulated memory. - * @param options Configures how certain instructions are translated. + * @param conf Configures how certain instructions are translated. * @return A translated basic block in the intermediate representation. */ -void Translate(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options); +void Translate(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf); /** * This function translates a single provided instruction into our intermediate representation. diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_exception_generating.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_exception_generating.cpp index c9616b0871..33501cb0e0 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_exception_generating.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_exception_generating.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,7 +13,7 @@ namespace Dynarmic::A32 { // BKPT # bool TranslatorVisitor::arm_BKPT(Cond cond, Imm<12> /*imm12*/, Imm<4> /*imm4*/) { - if (cond != Cond::AL && !options.define_unpredictable_behaviour) { + if (cond != Cond::AL && !conf.define_unpredictable_behaviour) { return UnpredictableInstruction(); } // UNPREDICTABLE: The instruction executes conditionally. diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.h b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.h index dd88b79237..9ac7dd1f77 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.h +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.h @@ -9,6 +9,7 @@ #pragma once #include "common/assert.h" +#include "dynarmic/interface/A32/config.h" #include "dynarmic/mcl/bit.hpp" #include "dynarmic/frontend/A32/a32_ir_emitter.h" @@ -25,12 +26,14 @@ enum class Exception; struct TranslatorVisitor final { using instruction_return_type = bool; - explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, const TranslationOptions& options) - : ir(block, descriptor, options.arch_version), options(options) {} + explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf) + : ir(block, descriptor, conf.arch_version) + , conf(conf) + {} A32::IREmitter ir; ConditionalState cond_state = ConditionalState::None; - TranslationOptions options; + A32::UserConfig const& conf; size_t current_instruction_size; diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/hint.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/hint.cpp index 0ec6aeff9a..65253fbb0f 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/hint.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/hint.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) 2019 MerryMage * SPDX-License-Identifier: 0BSD @@ -9,7 +12,7 @@ namespace Dynarmic::A32 { bool TranslatorVisitor::arm_PLD_imm(bool /*add*/, bool R, Reg /*n*/, Imm<12> /*imm12*/) { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } @@ -18,7 +21,7 @@ bool TranslatorVisitor::arm_PLD_imm(bool /*add*/, bool R, Reg /*n*/, Imm<12> /*i } bool TranslatorVisitor::arm_PLD_reg(bool /*add*/, bool R, Reg /*n*/, Imm<5> /*imm5*/, ShiftType /*shift*/, Reg /*m*/) { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } @@ -27,7 +30,7 @@ bool TranslatorVisitor::arm_PLD_reg(bool /*add*/, bool R, Reg /*n*/, Imm<5> /*im } bool TranslatorVisitor::arm_SEV() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } @@ -35,7 +38,7 @@ bool TranslatorVisitor::arm_SEV() { } bool TranslatorVisitor::arm_SEVL() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } @@ -43,7 +46,7 @@ bool TranslatorVisitor::arm_SEVL() { } bool TranslatorVisitor::arm_WFE() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } @@ -51,7 +54,7 @@ bool TranslatorVisitor::arm_WFE() { } bool TranslatorVisitor::arm_WFI() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } @@ -59,7 +62,7 @@ bool TranslatorVisitor::arm_WFI() { } bool TranslatorVisitor::arm_YIELD() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/thumb16.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/thumb16.cpp index 082cd30db2..629cf26c62 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/thumb16.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/thumb16.cpp @@ -642,7 +642,7 @@ bool TranslatorVisitor::thumb16_SUB_sp(Imm<7> imm7) { // SEV bool TranslatorVisitor::thumb16_SEV() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } return RaiseException(Exception::SendEvent); @@ -650,7 +650,7 @@ bool TranslatorVisitor::thumb16_SEV() { // SEVL bool TranslatorVisitor::thumb16_SEVL() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } return RaiseException(Exception::SendEventLocal); @@ -658,7 +658,7 @@ bool TranslatorVisitor::thumb16_SEVL() { // WFE bool TranslatorVisitor::thumb16_WFE() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } return RaiseException(Exception::WaitForEvent); @@ -666,7 +666,7 @@ bool TranslatorVisitor::thumb16_WFE() { // WFI bool TranslatorVisitor::thumb16_WFI() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } return RaiseException(Exception::WaitForInterrupt); @@ -674,7 +674,7 @@ bool TranslatorVisitor::thumb16_WFI() { // YIELD bool TranslatorVisitor::thumb16_YIELD() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } return RaiseException(Exception::Yield); diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/thumb32_load_byte.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/thumb32_load_byte.cpp index d309d42d66..f3f1f93b22 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/thumb32_load_byte.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/thumb32_load_byte.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) 2021 MerryMage * SPDX-License-Identifier: 0BSD @@ -8,7 +11,7 @@ namespace Dynarmic::A32 { static bool PLDHandler(TranslatorVisitor& v, bool W) { - if (!v.options.hook_hint_instructions) { + if (!v.conf.hook_hint_instructions) { return true; } @@ -18,7 +21,7 @@ static bool PLDHandler(TranslatorVisitor& v, bool W) { } static bool PLIHandler(TranslatorVisitor& v) { - if (!v.options.hook_hint_instructions) { + if (!v.conf.hook_hint_instructions) { return true; } 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 6c89a4af36..e6c4a8040e 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp @@ -22,10 +22,12 @@ namespace Dynarmic::A32 { -void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) { +void TranslateArm(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf) { const bool single_step = descriptor.SingleStepping(); - TranslatorVisitor visitor{block, descriptor, options}; + TranslatorVisitor visitor{block, descriptor, conf}; bool should_continue = true; + + auto tcb = conf.callbacks; do { const u32 arm_pc = visitor.ir.current_location.PC(); u64 ticks_for_instruction = 1; 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 2a2fbea63f..f98f7ed9c1 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp @@ -103,10 +103,12 @@ inline bool MaybeVFPOrASIMDInstruction(u32 thumb_instruction) noexcept { } // namespace -void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) { +void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf) { const bool single_step = descriptor.SingleStepping(); - TranslatorVisitor visitor{block, descriptor, options}; + TranslatorVisitor visitor{block, descriptor, conf}; bool should_continue = true; + + auto tcb = conf.callbacks; do { const u32 arm_pc = visitor.ir.current_location.PC(); u64 ticks_for_instruction = 1; 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 7840c63d79..eaada1d042 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp @@ -11,19 +11,20 @@ #include "dynarmic/frontend/A64/a64_location_descriptor.h" #include "dynarmic/frontend/A64/decoder/a64.h" #include "dynarmic/frontend/A64/translate/impl/impl.h" +#include "dynarmic/interface/A64/config.h" #include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/terminal.h" namespace Dynarmic::A64 { -void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options) { +void Translate(IR::Block& block, LocationDescriptor descriptor, A64::UserConfig const& conf) { const bool single_step = descriptor.SingleStepping(); - TranslatorVisitor visitor{block, descriptor, std::move(options)}; + TranslatorVisitor visitor{block, descriptor, conf}; bool should_continue = true; do { const u64 pc = visitor.ir.current_location->PC(); - if (const auto instruction = memory_read_code(pc)) { + if (const auto instruction = conf.callbacks->MemoryReadCode(pc)) { if (auto decoder = Decode(visitor, *instruction)) { should_continue = *decoder; } else { 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 61033eb530..7a988c6cba 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.h +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.h @@ -11,6 +11,7 @@ #include #include "common/common_types.h" +#include "dynarmic/interface/A64/config.h" namespace Dynarmic { @@ -22,32 +23,14 @@ namespace A64 { class LocationDescriptor; -using MemoryReadCodeFuncType = std::function(u64 vaddr)>; - -struct TranslationOptions { - /// This changes what IR we emit when we translate an unpredictable instruction. - /// If this is false, the ExceptionRaised IR instruction is emitted. - /// If this is true, we define some behaviour for some instructions. - bool define_unpredictable_behaviour = false; - - /// This tells the translator a wall clock will be used, thus allowing it - /// to avoid writting certain unnecessary code only needed for cycle timers. - bool wall_clock_cntpct = false; - - /// This changes what IR we emit when we translate a hint instruction. - /// If this is false, we treat the instruction as a NOP. - /// If this is true, we emit an ExceptionRaised instruction. - bool hook_hint_instructions = true; -}; - /** * This function translates instructions in memory into our intermediate representation. * @param descriptor The starting location of the basic block. Includes information like PC, FPCR state, &c. * @param memory_read_code The function we should use to read emulated memory. - * @param options Configures how certain instructions are translated. + * @param conf Configures how certain instructions are translated. * @return A translated basic block in the intermediate representation. */ -void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options); +void Translate(IR::Block& block, LocationDescriptor descriptor, A64::UserConfig const& conf); /** * This function translates a single provided instruction into our intermediate representation. diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.h b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.h index c8afef3283..0916c7044c 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.h +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.h @@ -15,17 +15,20 @@ #include "dynarmic/frontend/A64/a64_types.h" #include "dynarmic/frontend/A64/translate/a64_translate.h" #include "dynarmic/frontend/imm.h" +#include "dynarmic/interface/A64/config.h" namespace Dynarmic::A64 { struct TranslatorVisitor final { using instruction_return_type = bool; - explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, TranslationOptions options) - : ir(block, descriptor), options(std::move(options)) {} + explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, A64::UserConfig const& conf) + : ir(block, descriptor) + , conf(conf) + {} A64::IREmitter ir; - TranslationOptions options; + A64::UserConfig const& conf; bool UnpredictableInstruction(); bool DecodeError(); diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_exclusive.cpp b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_exclusive.cpp index 0e67e11b4b..708366722a 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_exclusive.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_exclusive.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) 2018 MerryMage * SPDX-License-Identifier: 0BSD @@ -25,7 +28,7 @@ static bool ExclusiveSharedDecodeAndOperation(TranslatorVisitor& v, bool pair, s if (memop == IR::MemOp::LOAD && pair && Rt == *Rt2) { return v.UnpredictableInstruction(); } else if (memop == IR::MemOp::STORE && (*Rs == Rt || (pair && *Rs == *Rt2))) { - if (!v.options.define_unpredictable_behaviour) { + if (!v.conf.define_unpredictable_behaviour) { return v.UnpredictableInstruction(); } // UNPREDICTABLE: The Constraint_NONE case is executed. diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/system.cpp b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/system.cpp index c60fdc3ae0..26769394cd 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/system.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/system.cpp @@ -42,35 +42,35 @@ bool TranslatorVisitor::NOP() { } bool TranslatorVisitor::YIELD() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } return RaiseException(Exception::Yield); } bool TranslatorVisitor::WFE() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } return RaiseException(Exception::WaitForEvent); } bool TranslatorVisitor::WFI() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } return RaiseException(Exception::WaitForInterrupt); } bool TranslatorVisitor::SEV() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } return RaiseException(Exception::SendEvent); } bool TranslatorVisitor::SEVL() { - if (!options.hook_hint_instructions) { + if (!conf.hook_hint_instructions) { return true; } return RaiseException(Exception::SendEventLocal); @@ -129,7 +129,7 @@ bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3 return true; case SystemRegisterEncoding::CNTPCT_EL0: // HACK: Ensure that this is the first instruction in the block it's emitted in, so the cycle count is most up-to-date. - if (!ir.block.instructions.empty() && !options.wall_clock_cntpct) { + if (!ir.block.instructions.empty() && !conf.wall_clock_cntpct) { ir.block.CycleCount()--; ir.SetTerm(IR::Term::LinkBlock{*ir.current_location}); return false; diff --git a/src/dynarmic/tests/A32/fuzz_thumb.cpp b/src/dynarmic/tests/A32/fuzz_thumb.cpp index a29b877f3e..1f5457016b 100644 --- a/src/dynarmic/tests/A32/fuzz_thumb.cpp +++ b/src/dynarmic/tests/A32/fuzz_thumb.cpp @@ -180,7 +180,7 @@ static void RunInstance(size_t run_number, ThumbTestEnv& test_env, A32::UserConf while (num_insts < instructions_to_execute_count) { A32::LocationDescriptor descriptor = {u32(num_insts * 4), cpsr, A32::FPSCR{}}; ir_block.Reset(descriptor); - A32::Translate(ir_block, descriptor, &test_env, {}); + A32::Translate(ir_block, descriptor, config); Optimization::Optimize(ir_block, config, {}); printf("\n\nIR:\n%s", IR::DumpBlock(ir_block).c_str()); printf("\n\nx86_64:\n"); diff --git a/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp b/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp index ea5b5302f8..1e1e37d888 100644 --- a/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp +++ b/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp @@ -268,7 +268,7 @@ static void RunTestInstance(Dynarmic::A64::Jit& jit, A64Unicorn& uni, A64TestEnv // const auto get_code = [&jit_env](u64 vaddr) { return jit_env.MemoryReadCode(vaddr); }; // const A64::LocationDescriptor location{instructions_start, FP::FPCR{fpcr}}; // IR::Block ir_block{location}; - // A64::Translate(ir_block, location, get_code, {}); + // A64::Translate(ir_block, location, config); // fmt::print("IR:\n{}\n", IR::DumpBlock(ir_block)); // Optimization::Optimize(ir_block, conf, {}); // fmt::print("Optimized IR:\n{}\n", IR::DumpBlock(ir_block));