[dynarmic] remove dead-code interpreter
Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
8e373eb714
commit
180941068f
|
|
@ -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++
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<JITContextImpl>(memory)} {}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<effect> <iflags>{, #<mode>}
|
||||
// CPS #<mode>
|
||||
bool TranslatorVisitor::arm_CPS() {
|
||||
return InterpretThisInstruction();
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// MRS<c> <Rd>, <spec_reg>
|
||||
|
|
@ -107,7 +107,7 @@ bool TranslatorVisitor::arm_MSR_reg(Cond cond, unsigned mask, Reg n) {
|
|||
|
||||
// RFE{<amode>} <Rn>{!}
|
||||
bool TranslatorVisitor::arm_RFE() {
|
||||
return InterpretThisInstruction();
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// SETEND <endian_specifier>
|
||||
|
|
@ -118,7 +118,7 @@ bool TranslatorVisitor::arm_SETEND(bool E) {
|
|||
|
||||
// SRS{<amode>} SP{!}, #<mode>
|
||||
bool TranslatorVisitor::arm_SRS() {
|
||||
return InterpretThisInstruction();
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
||||
|
|
|
|||
|
|
@ -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<V> GetDecodeTable() {
|
|||
return table;
|
||||
}
|
||||
|
||||
/// In practice it must always suceed, otherwise something else unrelated would have gone awry
|
||||
template<typename V>
|
||||
std::optional<std::reference_wrapper<const Matcher<V>>> Decode(u32 instruction) {
|
||||
std::reference_wrapper<const Matcher<V>> Decode(u32 instruction) {
|
||||
alignas(64) static const auto table = GetDecodeTable<V>();
|
||||
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<std::reference_wrapper<const Matcher<V>>>(*iter) : std::nullopt;
|
||||
DEBUG_ASSERT(iter != subtable.end());
|
||||
return std::reference_wrapper<const Matcher<V>>(*iter);
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
|
|
|
|||
|
|
@ -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<TranslatorVisitor>(*instruction)) {
|
||||
should_continue = decoder->get().call(visitor, *instruction);
|
||||
} else {
|
||||
should_continue = visitor.InterpretThisInstruction();
|
||||
}
|
||||
} else {
|
||||
should_continue = visitor.RaiseException(Exception::NoExecuteFault);
|
||||
}
|
||||
auto decoder = Decode<TranslatorVisitor>(*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<TranslatorVisitor>(instruction)) {
|
||||
should_continue = decoder->get().call(visitor, instruction);
|
||||
} else {
|
||||
should_continue = visitor.InterpretThisInstruction();
|
||||
}
|
||||
auto const decoder = Decode<TranslatorVisitor>(instruction);
|
||||
should_continue = decoder.get().call(visitor, instruction);
|
||||
|
||||
visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4);
|
||||
block.CycleCount()++;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -77,9 +77,6 @@ static std::string TerminalToString(const Terminal& terminal_variant) noexcept {
|
|||
std::string operator()(const Term::Invalid&) const {
|
||||
return "<invalid terminal>";
|
||||
}
|
||||
std::string operator()(const Term::Interpret& terminal) const {
|
||||
return fmt::format("Interpret{{{}}}", terminal.next);
|
||||
}
|
||||
std::string operator()(const Term::ReturnToDispatch&) const {
|
||||
return "ReturnToDispatch{}";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<IR::Term::Interpret>(&terminal)) {
|
||||
return term->next == location;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
IR::Terminal terminal = block.GetTerminal();
|
||||
auto term = boost::get<IR::Term::Interpret>(&terminal);
|
||||
if (!term)
|
||||
return;
|
||||
|
||||
A64::LocationDescriptor location{term->next};
|
||||
size_t num_instructions = 1;
|
||||
|
||||
while (is_interpret_instruction(location.AdvancePC(static_cast<int>(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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -59,8 +59,6 @@ bool AnyLocationDescriptorForTerminalHas(IR::Terminal terminal, Fn fn) {
|
|||
return fn(t.next);
|
||||
} else if constexpr (std::is_same_v<T, IR::Term::PopRSBHint>) {
|
||||
return false;
|
||||
} else if constexpr (std::is_same_v<T, IR::Term::Interpret>) {
|
||||
return fn(t.next);
|
||||
} else if constexpr (std::is_same_v<T, IR::Term::FastDispatchHint>) {
|
||||
return false;
|
||||
} else if constexpr (std::is_same_v<T, IR::Term::If>) {
|
||||
|
|
@ -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<IR::Term::Interpret>(&terminal)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AnyLocationDescriptorForTerminalHas(block.GetTerminal(), [&](IR::LocationDescriptor ld) { return A32::LocationDescriptor{ld}.PC() <= pc; })) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<u32>(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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<IR::Term::Interpret>(&terminal))
|
||||
return false;
|
||||
for (const auto& ir_inst : block.instructions) {
|
||||
switch (ir_inst.GetOpcode()) {
|
||||
case IR::Opcode::A64ExceptionRaised:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<u32>(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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,10 +50,6 @@ namespace {
|
|||
using namespace Dynarmic;
|
||||
|
||||
bool ShouldTestInst(IR::Block& block) {
|
||||
if (auto terminal = block.GetTerminal(); boost::get<IR::Term::Interpret>(&terminal)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& ir_inst : block.instructions) {
|
||||
switch (ir_inst.GetOpcode()) {
|
||||
// A32
|
||||
|
|
|
|||
Loading…
Reference in New Issue