From 180941068f3c073e6634f07917b3a59e3db3f784 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 14 Feb 2026 18:52:53 +0000 Subject: [PATCH] [dynarmic] remove dead-code interpreter Signed-off-by: lizzie --- docs/dynarmic/Design.md | 9 ----- docs/dynarmic/README.md | 5 --- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 7 ---- src/core/arm/dynarmic/arm_dynarmic_32.h | 1 - src/core/arm/dynarmic/arm_dynarmic_64.cpp | 7 ---- src/core/arm/dynarmic/arm_dynarmic_64.h | 1 - src/core/hle/service/jit/jit_context.cpp | 6 --- .../dynarmic/backend/arm64/emit_arm64_a32.cpp | 4 -- .../dynarmic/backend/arm64/emit_arm64_a64.cpp | 6 +-- .../backend/riscv64/emit_riscv64_a32.cpp | 6 +-- .../src/dynarmic/backend/x64/a32_emit_x64.cpp | 13 ------ .../src/dynarmic/backend/x64/a64_emit_x64.cpp | 10 ----- .../A32/translate/impl/a32_translate_impl.cpp | 7 +--- .../A32/translate/impl/a32_translate_impl.h | 3 +- .../A32/translate/impl/load_store.cpp | 8 ++-- .../translate/impl/status_register_access.cpp | 8 ++-- .../src/dynarmic/frontend/A64/decoder/a64.h | 8 ++-- .../frontend/A64/translate/a64_translate.cpp | 19 ++------- .../frontend/A64/translate/impl/impl.cpp | 7 +--- .../frontend/A64/translate/impl/impl.h | 4 +- .../translate/impl/simd_three_same_extra.cpp | 11 +++-- .../impl/simd_vector_x_indexed_element.cpp | 6 +-- .../frontend/A64/translate/impl/system.cpp | 4 +- .../src/dynarmic/interface/A32/config.h | 5 +-- .../src/dynarmic/interface/A64/config.h | 5 +-- src/dynarmic/src/dynarmic/ir/basic_block.cpp | 3 -- src/dynarmic/src/dynarmic/ir/opt_passes.cpp | 40 ------------------- src/dynarmic/src/dynarmic/ir/terminal.h | 14 +------ src/dynarmic/tests/A32/fuzz_arm.cpp | 6 --- src/dynarmic/tests/A32/testenv.h | 10 +---- src/dynarmic/tests/A64/fibonacci.cpp | 5 --- src/dynarmic/tests/A64/fuzz_with_unicorn.cpp | 2 - src/dynarmic/tests/A64/testenv.h | 8 ---- src/dynarmic/tests/print_info.cpp | 5 +-- src/dynarmic/tests/test_generator.cpp | 4 -- 35 files changed, 39 insertions(+), 228 deletions(-) diff --git a/docs/dynarmic/Design.md b/docs/dynarmic/Design.md index 8c6c1929b2..020cfd65bd 100644 --- a/docs/dynarmic/Design.md +++ b/docs/dynarmic/Design.md @@ -286,15 +286,6 @@ Exclusive OR (i.e.: XOR) Memory access. -### Terminal: Interpret - -```c++ -SetTerm(IR::Term::Interpret{next}) -``` - -This terminal instruction calls the interpreter, starting at `next`. -The interpreter must interpret exactly one instruction. - ### Terminal: ReturnToDispatch ```c++ diff --git a/docs/dynarmic/README.md b/docs/dynarmic/README.md index a97d36680d..bfba7c9cb0 100644 --- a/docs/dynarmic/README.md +++ b/docs/dynarmic/README.md @@ -117,11 +117,6 @@ public: MemoryWrite32(vaddr + 4, u32(value >> 32)); } - void InterpreterFallback(u32 pc, size_t num_instructions) override { - // This is never called in practice. - std::terminate(); - } - void CallSVC(u32 swi) override { // Do something. } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 2d8cfb6ed6..912a15475b 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -88,13 +88,6 @@ bool DynarmicCallbacks32::MemoryWriteExclusive64(u32 vaddr, u64 value, u64 expec m_memory.WriteExclusive64(vaddr, value, expected); } -void DynarmicCallbacks32::InterpreterFallback(u32 pc, std::size_t num_instructions) { - m_parent.LogBacktrace(m_process); - LOG_ERROR(Core_ARM, - "Unimplemented instruction @ {:#X} for {} instructions (instr = {:08X})", pc, - num_instructions, m_memory.Read32(pc)); -} - void DynarmicCallbacks32::ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) { switch (exception) { case Dynarmic::A32::Exception::NoExecuteFault: diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index e19a2deee2..5e40d5d82a 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -43,7 +43,6 @@ public: bool MemoryWriteExclusive16(u32 vaddr, u16 value, u16 expected) override; bool MemoryWriteExclusive32(u32 vaddr, u32 value, u32 expected) override; bool MemoryWriteExclusive64(u32 vaddr, u64 value, u64 expected) override; - void InterpreterFallback(u32 pc, std::size_t num_instructions) override; void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override; void CallSVC(u32 swi) override; void AddTicks(u64 ticks) override; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index f13221be8f..55584d0e38 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -102,13 +102,6 @@ bool DynarmicCallbacks64::MemoryWriteExclusive128(u64 vaddr, Dynarmic::A64::Vect m_memory.WriteExclusive128(vaddr, value, expected); } -void DynarmicCallbacks64::InterpreterFallback(u64 pc, std::size_t num_instructions) { - m_parent.LogBacktrace(m_process); - LOG_ERROR(Core_ARM, "Unimplemented instruction @ {:#X} for {} instructions (instr = {:08X})", pc, - num_instructions, m_memory.Read32(pc)); - ReturnException(pc, PrefetchAbort); -} - void DynarmicCallbacks64::InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op, u64 value) { switch (op) { case Dynarmic::A64::InstructionCacheOperation::InvalidateByVAToPoU: { diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index c8406e544b..a756c63615 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -52,7 +52,6 @@ public: bool MemoryWriteExclusive32(u64 vaddr, std::uint32_t value, std::uint32_t expected) override; bool MemoryWriteExclusive64(u64 vaddr, std::uint64_t value, std::uint64_t expected) override; bool MemoryWriteExclusive128(u64 vaddr, Dynarmic::A64::Vector value, Dynarmic::A64::Vector expected) override; - void InterpreterFallback(u64 pc, std::size_t num_instructions) override; void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op, u64 value) override; void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override; void CallSVC(u32 svc) override; diff --git a/src/core/hle/service/jit/jit_context.cpp b/src/core/hle/service/jit/jit_context.cpp index 447a28e9e7..327825ee83 100644 --- a/src/core/hle/service/jit/jit_context.cpp +++ b/src/core/hle/service/jit/jit_context.cpp @@ -116,7 +116,6 @@ public: void CallSVC(u32 swi) override; void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override; - void InterpreterFallback(u64 pc, size_t num_instructions) override; void AddTicks(u64 ticks) override {} u64 GetTicksRemaining() override { @@ -432,11 +431,6 @@ void DynarmicCallbacks64::ExceptionRaised(u64 pc, Dynarmic::A64::Exception excep parent.jit->HaltExecution(); } -void DynarmicCallbacks64::InterpreterFallback(u64 pc, size_t num_instructions) { - LOG_CRITICAL(Service_JIT, "Unimplemented instruction PC @ {:08x}", pc); - parent.jit->HaltExecution(); -} - JITContext::JITContext(Core::Memory::Memory& memory) : impl{std::make_unique(memory)} {} diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a32.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a32.cpp index 2868d3b830..a65efb3c59 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a32.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a32.cpp @@ -36,10 +36,6 @@ oaknut::Label EmitA32Cond(oaknut::CodeGenerator& code, EmitContext&, IR::Cond co void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::Terminal terminal, IR::LocationDescriptor initial_location, bool is_single_step); -void EmitA32Terminal(oaknut::CodeGenerator&, EmitContext&, IR::Term::Interpret, IR::LocationDescriptor, bool) { - UNREACHABLE(); -} - void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) { EmitRelocation(code, ctx, LinkTarget::ReturnToDispatcher); } diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a64.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a64.cpp index ee83c4af91..da4364c1b5 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a64.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a64.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. @@ -35,10 +35,6 @@ oaknut::Label EmitA64Cond(oaknut::CodeGenerator& code, EmitContext&, IR::Cond co void EmitA64Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::Terminal terminal, IR::LocationDescriptor initial_location, bool is_single_step); -void EmitA64Terminal(oaknut::CodeGenerator&, EmitContext&, IR::Term::Interpret, IR::LocationDescriptor, bool) { - UNREACHABLE(); -} - void EmitA64Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) { EmitRelocation(code, ctx, LinkTarget::ReturnToDispatcher); } diff --git a/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64_a32.cpp b/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64_a32.cpp index e617ff53b4..572f197955 100644 --- a/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64_a32.cpp +++ b/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64_a32.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. @@ -114,10 +114,6 @@ void EmitA32Cond(biscuit::Assembler& as, EmitContext&, IR::Cond cond, biscuit::L void EmitA32Terminal(biscuit::Assembler& as, EmitContext& ctx, IR::Term::Terminal terminal, IR::LocationDescriptor initial_location, bool is_single_step); -void EmitA32Terminal(biscuit::Assembler&, EmitContext&, IR::Term::Interpret, IR::LocationDescriptor, bool) { - UNREACHABLE(); -} - void EmitA32Terminal(biscuit::Assembler& as, EmitContext& ctx, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) { EmitRelocation(as, ctx, LinkTarget::ReturnFromRunCode); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp index a4c62e129b..d7d1c96232 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp @@ -1135,19 +1135,6 @@ void A32EmitX64::EmitSetUpperLocationDescriptor(IR::LocationDescriptor new_locat } namespace { -void EmitTerminalImpl(A32EmitX64& e, IR::Term::Interpret terminal, IR::LocationDescriptor initial_location, bool) { - ASSERT(A32::LocationDescriptor{terminal.next}.TFlag() == A32::LocationDescriptor{initial_location}.TFlag() && "Unimplemented"); - ASSERT(A32::LocationDescriptor{terminal.next}.EFlag() == A32::LocationDescriptor{initial_location}.EFlag() && "Unimplemented"); - ASSERT(terminal.num_instructions == 1 && "Unimplemented"); - - e.code.mov(e.code.ABI_PARAM2.cvt32(), A32::LocationDescriptor{terminal.next}.PC()); - e.code.mov(e.code.ABI_PARAM3.cvt32(), 1); - e.code.mov(MJitStateReg(A32::Reg::PC), e.code.ABI_PARAM2.cvt32()); - e.code.SwitchMxcsrOnExit(); - Devirtualize<&A32::UserCallbacks::InterpreterFallback>(e.conf.callbacks).EmitCall(e.code); - e.code.ReturnFromRunCode(true); // TODO: Check cycles -} - void EmitTerminalImpl(A32EmitX64& e, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) { e.code.ReturnFromRunCode(); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp index 03d0e13562..42ee281d00 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp @@ -619,16 +619,6 @@ std::string A64EmitX64::LocationDescriptorToFriendlyName(const IR::LocationDescr } namespace { -void EmitTerminalImpl(A64EmitX64& e, IR::Term::Interpret terminal, IR::LocationDescriptor, bool) { - e.code.SwitchMxcsrOnExit(); - Devirtualize<&A64::UserCallbacks::InterpreterFallback>(e.conf.callbacks).EmitCall(e.code, [&](RegList param) { - e.code.mov(param[0], A64::LocationDescriptor{terminal.next}.PC()); - e.code.mov(qword[e.code.ABI_JIT_PTR + offsetof(A64JitState, pc)], param[0]); - e.code.mov(param[1].cvt32(), terminal.num_instructions); - }); - e.code.ReturnFromRunCode(true); // TODO: Check cycles -} - void EmitTerminalImpl(A64EmitX64& e, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) { e.code.ReturnFromRunCode(); } diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.cpp index 35bc117308..7b21e7cce1 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.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. @@ -35,11 +35,6 @@ bool TranslatorVisitor::VFPConditionPassed(Cond cond) { return ArmConditionPassed(cond); } -bool TranslatorVisitor::InterpretThisInstruction() { - ir.SetTerm(IR::Term::Interpret(ir.current_location)); - return false; -} - bool TranslatorVisitor::UnpredictableInstruction() { return RaiseException(Exception::UnpredictableInstruction); } 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 0a3cab3c12..a03b2e666b 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 @@ -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. @@ -39,7 +39,6 @@ struct TranslatorVisitor final { bool ThumbConditionPassed(); bool VFPConditionPassed(Cond cond); - bool InterpretThisInstruction(); bool UnpredictableInstruction(); bool UndefinedInstruction(); bool DecodeError(); diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/load_store.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/load_store.cpp index 4dcae5db3d..49c5d65b3a 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/load_store.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/load_store.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. @@ -871,11 +871,11 @@ bool TranslatorVisitor::arm_LDMIB(Cond cond, bool W, Reg n, RegList list) { } bool TranslatorVisitor::arm_LDM_usr() { - return InterpretThisInstruction(); + UNREACHABLE(); } bool TranslatorVisitor::arm_LDM_eret() { - return InterpretThisInstruction(); + UNREACHABLE(); } static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, RegList list, IR::U32 start_address, IR::U32 writeback_address) { @@ -956,7 +956,7 @@ bool TranslatorVisitor::arm_STMIB(Cond cond, bool W, Reg n, RegList list) { } bool TranslatorVisitor::arm_STM_usr() { - return InterpretThisInstruction(); + UNREACHABLE(); } } // namespace Dynarmic::A32 diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/status_register_access.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/status_register_access.cpp index 15ebd8bc69..8dfc64d6d7 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/status_register_access.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/impl/status_register_access.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. @@ -15,7 +15,7 @@ namespace Dynarmic::A32 { // CPS {, #} // CPS # bool TranslatorVisitor::arm_CPS() { - return InterpretThisInstruction(); + UNREACHABLE(); } // MRS , @@ -107,7 +107,7 @@ bool TranslatorVisitor::arm_MSR_reg(Cond cond, unsigned mask, Reg n) { // RFE{} {!} bool TranslatorVisitor::arm_RFE() { - return InterpretThisInstruction(); + UNREACHABLE(); } // SETEND @@ -118,7 +118,7 @@ bool TranslatorVisitor::arm_SETEND(bool E) { // SRS{} SP{!}, # bool TranslatorVisitor::arm_SRS() { - return InterpretThisInstruction(); + UNREACHABLE(); } } // namespace Dynarmic::A32 diff --git a/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h b/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h index 7e6cdc3935..68422ed40d 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h +++ b/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.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. @@ -68,14 +68,16 @@ constexpr DecodeTable GetDecodeTable() { return table; } +/// In practice it must always suceed, otherwise something else unrelated would have gone awry template -std::optional>> Decode(u32 instruction) { +std::reference_wrapper> Decode(u32 instruction) { alignas(64) static const auto table = GetDecodeTable(); const auto& subtable = table[detail::ToFastLookupIndex(instruction)]; auto iter = std::find_if(subtable.begin(), subtable.end(), [instruction](const auto& matcher) { return matcher.Matches(instruction); }); - return iter != subtable.end() ? std::optional>>(*iter) : std::nullopt; + DEBUG_ASSERT(iter != subtable.end()); + return std::reference_wrapper>(*iter); } template 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 e8d815518c..3583ebd549 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp @@ -23,16 +23,8 @@ void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFu bool should_continue = true; do { const u64 pc = visitor.ir.current_location->PC(); - - if (const auto instruction = memory_read_code(pc)) { - if (auto decoder = Decode(*instruction)) { - should_continue = decoder->get().call(visitor, *instruction); - } else { - should_continue = visitor.InterpretThisInstruction(); - } - } else { - should_continue = visitor.RaiseException(Exception::NoExecuteFault); - } + auto decoder = Decode(*instruction); + should_continue = decoder.get().call(visitor, *instruction); visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4); block.CycleCount()++; @@ -49,11 +41,8 @@ bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, TranslatorVisitor visitor{block, descriptor, {}}; bool should_continue = true; - if (auto decoder = Decode(instruction)) { - should_continue = decoder->get().call(visitor, instruction); - } else { - should_continue = visitor.InterpretThisInstruction(); - } + auto const decoder = Decode(instruction); + should_continue = decoder.get().call(visitor, instruction); visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4); block.CycleCount()++; diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.cpp b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.cpp index 0fb82766e9..de63f560bc 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.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,11 +16,6 @@ namespace Dynarmic::A64 { -bool TranslatorVisitor::InterpretThisInstruction() { - ir.SetTerm(IR::Term::Interpret(*ir.current_location)); - return false; -} - bool TranslatorVisitor::UnpredictableInstruction() { return RaiseException(Exception::UnpredictableInstruction); } 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 86bc534d5e..c8afef3283 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.h +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.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) 2018 MerryMage * SPDX-License-Identifier: 0BSD @@ -24,7 +27,6 @@ struct TranslatorVisitor final { A64::IREmitter ir; TranslationOptions options; - bool InterpretThisInstruction(); bool UnpredictableInstruction(); bool DecodeError(); bool ReservedValue(); diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_same_extra.cpp b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_same_extra.cpp index d18f4b10cb..91ade93f4b 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_same_extra.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_same_extra.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 @@ -63,9 +66,7 @@ bool TranslatorVisitor::FCMLA_vec(bool Q, Imm<2> size, Vec Vm, Imm<2> rot, Vec V const size_t esize = 8U << size.ZeroExtend(); // TODO: Currently we don't support half-precision floating point - if (esize == 16) { - return InterpretThisInstruction(); - } + ASSERT(esize != 16); const size_t datasize = Q ? 128 : 64; const size_t num_elements = datasize / esize; @@ -134,9 +135,7 @@ bool TranslatorVisitor::FCADD_vec(bool Q, Imm<2> size, Vec Vm, Imm<1> rot, Vec V const size_t esize = 8U << size.ZeroExtend(); // TODO: Currently we don't support half-precision floating point - if (esize == 16) { - return InterpretThisInstruction(); - } + ASSERT(esize != 16); const size_t datasize = Q ? 128 : 64; const size_t num_elements = datasize / esize; diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp index 1956c53acc..12ff153dd8 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_vector_x_indexed_element.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. @@ -223,9 +223,7 @@ bool TranslatorVisitor::FCMLA_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4 const size_t esize = 8U << size.ZeroExtend(); // TODO: We don't support the half-precision floating point variant yet. - if (esize == 16) { - return InterpretThisInstruction(); - } + ASSERT(esize != 16); const size_t index = [=] { if (size == 0b01) { 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 7c4b8a1ac6..c60fdc3ae0 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/system.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/system.cpp @@ -118,7 +118,7 @@ bool TranslatorVisitor::MSR_reg(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, I default: break; } - return InterpretThisInstruction(); + UNREACHABLE(); } bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt) { @@ -158,7 +158,7 @@ bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3 X(64, Rt, ir.GetTPIDRRO()); return true; } - return InterpretThisInstruction(); + UNREACHABLE(); } } // namespace Dynarmic::A64 diff --git a/src/dynarmic/src/dynarmic/interface/A32/config.h b/src/dynarmic/src/dynarmic/interface/A32/config.h index ee449d519d..5a97fb69f3 100644 --- a/src/dynarmic/src/dynarmic/interface/A32/config.h +++ b/src/dynarmic/src/dynarmic/interface/A32/config.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. @@ -103,9 +103,6 @@ struct UserCallbacks : public TranslateCallbacks { // A conservative implementation that always returns false is safe. virtual bool IsReadOnlyMemory(VAddr /*vaddr*/) { return false; } - /// The interpreter must execute exactly num_instructions starting from PC. - virtual void InterpreterFallback(VAddr pc, size_t num_instructions) = 0; - // This callback is called whenever a SVC instruction is executed. virtual void CallSVC(std::uint32_t swi) = 0; diff --git a/src/dynarmic/src/dynarmic/interface/A64/config.h b/src/dynarmic/src/dynarmic/interface/A64/config.h index e4416e9b19..83c1593fd8 100644 --- a/src/dynarmic/src/dynarmic/interface/A64/config.h +++ b/src/dynarmic/src/dynarmic/interface/A64/config.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. @@ -118,9 +118,6 @@ struct UserCallbacks { // A conservative implementation that always returns false is safe. virtual bool IsReadOnlyMemory(VAddr /*vaddr*/) { return false; } - /// The interpreter must execute exactly num_instructions starting from PC. - virtual void InterpreterFallback(VAddr pc, size_t num_instructions) = 0; - // This callback is called whenever a SVC instruction is executed. virtual void CallSVC(std::uint32_t swi) = 0; diff --git a/src/dynarmic/src/dynarmic/ir/basic_block.cpp b/src/dynarmic/src/dynarmic/ir/basic_block.cpp index d210bafd35..ac0f03d76a 100644 --- a/src/dynarmic/src/dynarmic/ir/basic_block.cpp +++ b/src/dynarmic/src/dynarmic/ir/basic_block.cpp @@ -77,9 +77,6 @@ static std::string TerminalToString(const Terminal& terminal_variant) noexcept { std::string operator()(const Term::Invalid&) const { return ""; } - std::string operator()(const Term::Interpret& terminal) const { - return fmt::format("Interpret{{{}}}", terminal.next); - } std::string operator()(const Term::ReturnToDispatch&) const { return "ReturnToDispatch{}"; } diff --git a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp index ee68a0bcfc..702d429638 100644 --- a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp +++ b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp @@ -638,43 +638,6 @@ static void A64GetSetElimination(IR::Block& block) { } } -static void A64MergeInterpretBlocksPass(IR::Block& block, A64::UserCallbacks* cb) { - const auto is_interpret_instruction = [cb](A64::LocationDescriptor location) { - const auto instruction = cb->MemoryReadCode(location.PC()); - if (!instruction) - return false; - - IR::Block new_block{location}; - A64::TranslateSingleInstruction(new_block, location, *instruction); - - if (!new_block.Instructions().empty()) - return false; - - const IR::Terminal terminal = new_block.GetTerminal(); - if (auto term = boost::get(&terminal)) { - return term->next == location; - } - - return false; - }; - - IR::Terminal terminal = block.GetTerminal(); - auto term = boost::get(&terminal); - if (!term) - return; - - A64::LocationDescriptor location{term->next}; - size_t num_instructions = 1; - - while (is_interpret_instruction(location.AdvancePC(static_cast(num_instructions * 4)))) { - num_instructions++; - } - - term->num_instructions = num_instructions; - block.ReplaceTerminal(terminal); - block.CycleCount() += num_instructions - 1; -} - using Op = Dynarmic::IR::Opcode; static IR::Value Value(bool is_32_bit, u64 value) { @@ -1504,9 +1467,6 @@ void Optimize(IR::Block& block, const A64::UserConfig& conf, const Optimization: Optimization::ConstantPropagation(block); Optimization::DeadCodeElimination(block); } - if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) { - Optimization::A64MergeInterpretBlocksPass(block, conf.callbacks); - } Optimization::IdentityRemovalPass(block); if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { Optimization::VerificationPass(block); diff --git a/src/dynarmic/src/dynarmic/ir/terminal.h b/src/dynarmic/src/dynarmic/ir/terminal.h index 130dfc6574..187648b45c 100644 --- a/src/dynarmic/src/dynarmic/ir/terminal.h +++ b/src/dynarmic/src/dynarmic/ir/terminal.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. @@ -19,17 +19,6 @@ namespace Term { struct Invalid {}; -/** - * This terminal instruction calls the interpreter, starting at `next`. - * The interpreter must interpret exactly `num_instructions` instructions. - */ -struct Interpret { - explicit Interpret(const LocationDescriptor& next_) - : next(next_) {} - LocationDescriptor next; ///< Location at which interpretation starts. - size_t num_instructions = 1; -}; - /** * This terminal instruction returns control to the dispatcher. * The dispatcher will use the current cpu state to determine what comes next. @@ -83,7 +72,6 @@ struct CheckHalt; /// A Terminal is the terminal instruction in a MicroBlock. using Terminal = boost::variant< Invalid, - Interpret, ReturnToDispatch, LinkBlock, LinkBlockFast, diff --git a/src/dynarmic/tests/A32/fuzz_arm.cpp b/src/dynarmic/tests/A32/fuzz_arm.cpp index b0693415bb..fd17b3bd01 100644 --- a/src/dynarmic/tests/A32/fuzz_arm.cpp +++ b/src/dynarmic/tests/A32/fuzz_arm.cpp @@ -59,8 +59,6 @@ bool AnyLocationDescriptorForTerminalHas(IR::Terminal terminal, Fn fn) { return fn(t.next); } else if constexpr (std::is_same_v) { return false; - } else if constexpr (std::is_same_v) { - return fn(t.next); } else if constexpr (std::is_same_v) { return false; } else if constexpr (std::is_same_v) { @@ -85,10 +83,6 @@ bool ShouldTestInst(u32 instruction, u32 pc, bool is_thumb, bool is_last_inst, A return false; } - if (auto terminal = block.GetTerminal(); boost::get(&terminal)) { - return false; - } - if (AnyLocationDescriptorForTerminalHas(block.GetTerminal(), [&](IR::LocationDescriptor ld) { return A32::LocationDescriptor{ld}.PC() <= pc; })) { return false; } diff --git a/src/dynarmic/tests/A32/testenv.h b/src/dynarmic/tests/A32/testenv.h index 3d0ebd4168..6f303a58e9 100644 --- a/src/dynarmic/tests/A32/testenv.h +++ b/src/dynarmic/tests/A32/testenv.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. @@ -97,10 +97,6 @@ public: MemoryWrite32(vaddr + 4, static_cast(value >> 32)); } - void InterpreterFallback(u32 pc, size_t num_instructions) override { - UNREACHABLE(); //ASSERT(false && "InterpreterFallback({:08x} && {}) code = {:08x}", pc, num_instructions, *MemoryReadCode(pc)); - } - void CallSVC(std::uint32_t swi) override { UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi); } @@ -190,10 +186,6 @@ public: return true; } - void InterpreterFallback(std::uint32_t pc, size_t num_instructions) override { - UNREACHABLE(); //ASSERT(false && "InterpreterFallback({:016x} && {})", pc, num_instructions); - } - void CallSVC(std::uint32_t swi) override { UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi); } diff --git a/src/dynarmic/tests/A64/fibonacci.cpp b/src/dynarmic/tests/A64/fibonacci.cpp index 9a10f52614..d706118cd2 100644 --- a/src/dynarmic/tests/A64/fibonacci.cpp +++ b/src/dynarmic/tests/A64/fibonacci.cpp @@ -69,11 +69,6 @@ public: MemoryWrite64(vaddr + 8, value[1]); } - void InterpreterFallback(u64, size_t) override { - // This is never called in practice. - std::terminate(); - } - void CallSVC(u32) override { // Do something. } diff --git a/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp b/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp index 332806fbfb..2cdf288eab 100644 --- a/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp +++ b/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp @@ -43,8 +43,6 @@ static bool ShouldTestInst(u32 instruction, u64 pc, bool is_last_inst) { bool should_continue = A64::TranslateSingleInstruction(block, location, instruction); if (!should_continue && !is_last_inst) return false; - if (auto terminal = block.GetTerminal(); boost::get(&terminal)) - return false; for (const auto& ir_inst : block.instructions) { switch (ir_inst.GetOpcode()) { case IR::Opcode::A64ExceptionRaised: diff --git a/src/dynarmic/tests/A64/testenv.h b/src/dynarmic/tests/A64/testenv.h index 67b0f97a65..2b8733a177 100644 --- a/src/dynarmic/tests/A64/testenv.h +++ b/src/dynarmic/tests/A64/testenv.h @@ -105,10 +105,6 @@ public: return true; } - void InterpreterFallback(u64 pc, size_t num_instructions) override { - UNREACHABLE(); // ASSERT(false&& "InterpreterFallback({:016x} && {})", pc, num_instructions); - } - void CallSVC(std::uint32_t swi) override { UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi); } @@ -208,10 +204,6 @@ public: return true; } - void InterpreterFallback(u64 pc, size_t num_instructions) override { - ASSERT(ignore_invalid_insn && "InterpreterFallback"); - } - void CallSVC(std::uint32_t swi) override { UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi); } diff --git a/src/dynarmic/tests/print_info.cpp b/src/dynarmic/tests/print_info.cpp index b597f0e60e..cc2c915b8b 100644 --- a/src/dynarmic/tests/print_info.cpp +++ b/src/dynarmic/tests/print_info.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. @@ -153,9 +153,6 @@ public: MemoryWrite32(vaddr + 4, static_cast(value >> 32)); } - void InterpreterFallback(u32 pc, size_t num_instructions) override { - fmt::print("> InterpreterFallback({:08x}, {}) code = {:08x}\n", pc, num_instructions, *MemoryReadCode(pc)); - } void CallSVC(std::uint32_t swi) override { fmt::print("> CallSVC({})\n", swi); } diff --git a/src/dynarmic/tests/test_generator.cpp b/src/dynarmic/tests/test_generator.cpp index 09d24596d3..4435e762ae 100644 --- a/src/dynarmic/tests/test_generator.cpp +++ b/src/dynarmic/tests/test_generator.cpp @@ -50,10 +50,6 @@ namespace { using namespace Dynarmic; bool ShouldTestInst(IR::Block& block) { - if (auto terminal = block.GetTerminal(); boost::get(&terminal)) { - return false; - } - for (const auto& ir_inst : block.instructions) { switch (ir_inst.GetOpcode()) { // A32