mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 03:18:55 +02:00
[dynarmic] remove dead-code interpreter (#3547)
interpreter was never called in practice and doesn't do anything other than just crash Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3547 Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Reviewed-by: crueter <crueter@eden-emu.dev> Reviewed-by: DraVee <dravee@eden-emu.dev> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
732b7eb560
commit
f76dc401c3
36 changed files with 41 additions and 231 deletions
|
|
@ -286,15 +286,6 @@ Exclusive OR (i.e.: XOR)
|
||||||
|
|
||||||
Memory access.
|
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
|
### Terminal: ReturnToDispatch
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
|
|
|
||||||
|
|
@ -117,11 +117,6 @@ public:
|
||||||
MemoryWrite32(vaddr + 4, u32(value >> 32));
|
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 {
|
void CallSVC(u32 swi) override {
|
||||||
// Do something.
|
// Do something.
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,13 +88,6 @@ bool DynarmicCallbacks32::MemoryWriteExclusive64(u32 vaddr, u64 value, u64 expec
|
||||||
m_memory.WriteExclusive64(vaddr, value, expected);
|
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) {
|
void DynarmicCallbacks32::ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) {
|
||||||
switch (exception) {
|
switch (exception) {
|
||||||
case Dynarmic::A32::Exception::NoExecuteFault:
|
case Dynarmic::A32::Exception::NoExecuteFault:
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ public:
|
||||||
bool MemoryWriteExclusive16(u32 vaddr, u16 value, u16 expected) override;
|
bool MemoryWriteExclusive16(u32 vaddr, u16 value, u16 expected) override;
|
||||||
bool MemoryWriteExclusive32(u32 vaddr, u32 value, u32 expected) override;
|
bool MemoryWriteExclusive32(u32 vaddr, u32 value, u32 expected) override;
|
||||||
bool MemoryWriteExclusive64(u32 vaddr, u64 value, u64 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 ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override;
|
||||||
void CallSVC(u32 swi) override;
|
void CallSVC(u32 swi) override;
|
||||||
void AddTicks(u64 ticks) override;
|
void AddTicks(u64 ticks) override;
|
||||||
|
|
|
||||||
|
|
@ -102,13 +102,6 @@ bool DynarmicCallbacks64::MemoryWriteExclusive128(u64 vaddr, Dynarmic::A64::Vect
|
||||||
m_memory.WriteExclusive128(vaddr, value, expected);
|
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) {
|
void DynarmicCallbacks64::InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op, u64 value) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Dynarmic::A64::InstructionCacheOperation::InvalidateByVAToPoU: {
|
case Dynarmic::A64::InstructionCacheOperation::InvalidateByVAToPoU: {
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ public:
|
||||||
bool MemoryWriteExclusive32(u64 vaddr, std::uint32_t value, std::uint32_t expected) override;
|
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 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;
|
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 InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op, u64 value) override;
|
||||||
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override;
|
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override;
|
||||||
void CallSVC(u32 svc) override;
|
void CallSVC(u32 svc) override;
|
||||||
|
|
|
||||||
|
|
@ -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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
|
@ -772,12 +772,8 @@ std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, m
|
||||||
u32 instruction = memory.Read32(pc);
|
u32 instruction = memory.Read32(pc);
|
||||||
bool was_executed = false;
|
bool was_executed = false;
|
||||||
|
|
||||||
if (auto decoder = Dynarmic::A64::Decode<VisitorBase>(instruction)) {
|
auto decoder = Dynarmic::A64::Decode<VisitorBase>(instruction);
|
||||||
was_executed = decoder->get().call(visitor, instruction);
|
was_executed = decoder.get().call(visitor, instruction);
|
||||||
} else {
|
|
||||||
LOG_ERROR(Core_ARM, "Unallocated encoding: {:#x}", instruction);
|
|
||||||
}
|
|
||||||
|
|
||||||
return was_executed ? std::optional<u64>(pc + 4) : std::nullopt;
|
return was_executed ? std::optional<u64>(pc + 4) : std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,6 @@ public:
|
||||||
|
|
||||||
void CallSVC(u32 swi) override;
|
void CallSVC(u32 swi) override;
|
||||||
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override;
|
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override;
|
||||||
void InterpreterFallback(u64 pc, size_t num_instructions) override;
|
|
||||||
|
|
||||||
void AddTicks(u64 ticks) override {}
|
void AddTicks(u64 ticks) override {}
|
||||||
u64 GetTicksRemaining() override {
|
u64 GetTicksRemaining() override {
|
||||||
|
|
@ -432,11 +431,6 @@ void DynarmicCallbacks64::ExceptionRaised(u64 pc, Dynarmic::A64::Exception excep
|
||||||
parent.jit->HaltExecution();
|
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)
|
JITContext::JITContext(Core::Memory::Memory& memory)
|
||||||
: impl{std::make_unique<JITContextImpl>(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& 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) {
|
void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) {
|
||||||
EmitRelocation(code, ctx, LinkTarget::ReturnToDispatcher);
|
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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* 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& 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) {
|
void EmitA64Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) {
|
||||||
EmitRelocation(code, ctx, LinkTarget::ReturnToDispatcher);
|
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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* 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& 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) {
|
void EmitA32Terminal(biscuit::Assembler& as, EmitContext& ctx, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) {
|
||||||
EmitRelocation(as, ctx, LinkTarget::ReturnFromRunCode);
|
EmitRelocation(as, ctx, LinkTarget::ReturnFromRunCode);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1135,19 +1135,6 @@ void A32EmitX64::EmitSetUpperLocationDescriptor(IR::LocationDescriptor new_locat
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
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) {
|
void EmitTerminalImpl(A32EmitX64& e, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) {
|
||||||
e.code.ReturnFromRunCode();
|
e.code.ReturnFromRunCode();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -619,16 +619,6 @@ std::string A64EmitX64::LocationDescriptorToFriendlyName(const IR::LocationDescr
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
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) {
|
void EmitTerminalImpl(A64EmitX64& e, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) {
|
||||||
e.code.ReturnFromRunCode();
|
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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -35,11 +35,6 @@ bool TranslatorVisitor::VFPConditionPassed(Cond cond) {
|
||||||
return ArmConditionPassed(cond);
|
return ArmConditionPassed(cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::InterpretThisInstruction() {
|
|
||||||
ir.SetTerm(IR::Term::Interpret(ir.current_location));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TranslatorVisitor::UnpredictableInstruction() {
|
bool TranslatorVisitor::UnpredictableInstruction() {
|
||||||
return RaiseException(Exception::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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -39,7 +39,6 @@ struct TranslatorVisitor final {
|
||||||
bool ThumbConditionPassed();
|
bool ThumbConditionPassed();
|
||||||
bool VFPConditionPassed(Cond cond);
|
bool VFPConditionPassed(Cond cond);
|
||||||
|
|
||||||
bool InterpretThisInstruction();
|
|
||||||
bool UnpredictableInstruction();
|
bool UnpredictableInstruction();
|
||||||
bool UndefinedInstruction();
|
bool UndefinedInstruction();
|
||||||
bool DecodeError();
|
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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* 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() {
|
bool TranslatorVisitor::arm_LDM_usr() {
|
||||||
return InterpretThisInstruction();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::arm_LDM_eret() {
|
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) {
|
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() {
|
bool TranslatorVisitor::arm_STM_usr() {
|
||||||
return InterpretThisInstruction();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::A32
|
} // 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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -15,7 +15,7 @@ namespace Dynarmic::A32 {
|
||||||
// CPS<effect> <iflags>{, #<mode>}
|
// CPS<effect> <iflags>{, #<mode>}
|
||||||
// CPS #<mode>
|
// CPS #<mode>
|
||||||
bool TranslatorVisitor::arm_CPS() {
|
bool TranslatorVisitor::arm_CPS() {
|
||||||
return InterpretThisInstruction();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
// MRS<c> <Rd>, <spec_reg>
|
// MRS<c> <Rd>, <spec_reg>
|
||||||
|
|
@ -107,7 +107,7 @@ bool TranslatorVisitor::arm_MSR_reg(Cond cond, unsigned mask, Reg n) {
|
||||||
|
|
||||||
// RFE{<amode>} <Rn>{!}
|
// RFE{<amode>} <Rn>{!}
|
||||||
bool TranslatorVisitor::arm_RFE() {
|
bool TranslatorVisitor::arm_RFE() {
|
||||||
return InterpretThisInstruction();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
// SETEND <endian_specifier>
|
// SETEND <endian_specifier>
|
||||||
|
|
@ -118,7 +118,7 @@ bool TranslatorVisitor::arm_SETEND(bool E) {
|
||||||
|
|
||||||
// SRS{<amode>} SP{!}, #<mode>
|
// SRS{<amode>} SP{!}, #<mode>
|
||||||
bool TranslatorVisitor::arm_SRS() {
|
bool TranslatorVisitor::arm_SRS() {
|
||||||
return InterpretThisInstruction();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::A32
|
} // 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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -68,14 +68,16 @@ constexpr DecodeTable<V> GetDecodeTable() {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// In practice it must always suceed, otherwise something else unrelated would have gone awry
|
||||||
template<typename V>
|
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>();
|
alignas(64) static const auto table = GetDecodeTable<V>();
|
||||||
const auto& subtable = table[detail::ToFastLookupIndex(instruction)];
|
const auto& subtable = table[detail::ToFastLookupIndex(instruction)];
|
||||||
auto iter = std::find_if(subtable.begin(), subtable.end(), [instruction](const auto& matcher) {
|
auto iter = std::find_if(subtable.begin(), subtable.end(), [instruction](const auto& matcher) {
|
||||||
return matcher.Matches(instruction);
|
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>
|
template<typename V>
|
||||||
|
|
|
||||||
|
|
@ -23,17 +23,12 @@ void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFu
|
||||||
bool should_continue = true;
|
bool should_continue = true;
|
||||||
do {
|
do {
|
||||||
const u64 pc = visitor.ir.current_location->PC();
|
const u64 pc = visitor.ir.current_location->PC();
|
||||||
|
|
||||||
if (const auto instruction = memory_read_code(pc)) {
|
if (const auto instruction = memory_read_code(pc)) {
|
||||||
if (auto decoder = Decode<TranslatorVisitor>(*instruction)) {
|
auto decoder = Decode<TranslatorVisitor>(*instruction);
|
||||||
should_continue = decoder->get().call(visitor, *instruction);
|
should_continue = decoder.get().call(visitor, *instruction);
|
||||||
} else {
|
|
||||||
should_continue = visitor.InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
should_continue = visitor.RaiseException(Exception::NoExecuteFault);
|
should_continue = visitor.RaiseException(Exception::NoExecuteFault);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4);
|
visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4);
|
||||||
block.CycleCount()++;
|
block.CycleCount()++;
|
||||||
} while (should_continue && !single_step);
|
} while (should_continue && !single_step);
|
||||||
|
|
@ -49,11 +44,8 @@ bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor,
|
||||||
TranslatorVisitor visitor{block, descriptor, {}};
|
TranslatorVisitor visitor{block, descriptor, {}};
|
||||||
|
|
||||||
bool should_continue = true;
|
bool should_continue = true;
|
||||||
if (auto decoder = Decode<TranslatorVisitor>(instruction)) {
|
auto const decoder = Decode<TranslatorVisitor>(instruction);
|
||||||
should_continue = decoder->get().call(visitor, instruction);
|
should_continue = decoder.get().call(visitor, instruction);
|
||||||
} else {
|
|
||||||
should_continue = visitor.InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4);
|
visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4);
|
||||||
block.CycleCount()++;
|
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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -16,11 +16,6 @@
|
||||||
|
|
||||||
namespace Dynarmic::A64 {
|
namespace Dynarmic::A64 {
|
||||||
|
|
||||||
bool TranslatorVisitor::InterpretThisInstruction() {
|
|
||||||
ir.SetTerm(IR::Term::Interpret(*ir.current_location));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TranslatorVisitor::UnpredictableInstruction() {
|
bool TranslatorVisitor::UnpredictableInstruction() {
|
||||||
return RaiseException(Exception::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.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2018 MerryMage
|
* Copyright (c) 2018 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -24,7 +27,6 @@ struct TranslatorVisitor final {
|
||||||
A64::IREmitter ir;
|
A64::IREmitter ir;
|
||||||
TranslationOptions options;
|
TranslationOptions options;
|
||||||
|
|
||||||
bool InterpretThisInstruction();
|
|
||||||
bool UnpredictableInstruction();
|
bool UnpredictableInstruction();
|
||||||
bool DecodeError();
|
bool DecodeError();
|
||||||
bool ReservedValue();
|
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.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2018 MerryMage
|
* Copyright (c) 2018 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* 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();
|
const size_t esize = 8U << size.ZeroExtend();
|
||||||
|
|
||||||
// TODO: Currently we don't support half-precision floating point
|
// TODO: Currently we don't support half-precision floating point
|
||||||
if (esize == 16) {
|
ASSERT(esize != 16);
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t datasize = Q ? 128 : 64;
|
const size_t datasize = Q ? 128 : 64;
|
||||||
const size_t num_elements = datasize / esize;
|
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();
|
const size_t esize = 8U << size.ZeroExtend();
|
||||||
|
|
||||||
// TODO: Currently we don't support half-precision floating point
|
// TODO: Currently we don't support half-precision floating point
|
||||||
if (esize == 16) {
|
ASSERT(esize != 16);
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t datasize = Q ? 128 : 64;
|
const size_t datasize = Q ? 128 : 64;
|
||||||
const size_t num_elements = datasize / esize;
|
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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* 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();
|
const size_t esize = 8U << size.ZeroExtend();
|
||||||
|
|
||||||
// TODO: We don't support the half-precision floating point variant yet.
|
// TODO: We don't support the half-precision floating point variant yet.
|
||||||
if (esize == 16) {
|
ASSERT(esize != 16);
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t index = [=] {
|
const size_t index = [=] {
|
||||||
if (size == 0b01) {
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return InterpretThisInstruction();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt) {
|
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());
|
X(64, Rt, ir.GetTPIDRRO());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return InterpretThisInstruction();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::A64
|
} // 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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* 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.
|
// A conservative implementation that always returns false is safe.
|
||||||
virtual bool IsReadOnlyMemory(VAddr /*vaddr*/) { return false; }
|
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.
|
// This callback is called whenever a SVC instruction is executed.
|
||||||
virtual void CallSVC(std::uint32_t swi) = 0;
|
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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -118,9 +118,6 @@ struct UserCallbacks {
|
||||||
// A conservative implementation that always returns false is safe.
|
// A conservative implementation that always returns false is safe.
|
||||||
virtual bool IsReadOnlyMemory(VAddr /*vaddr*/) { return false; }
|
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.
|
// This callback is called whenever a SVC instruction is executed.
|
||||||
virtual void CallSVC(std::uint32_t swi) = 0;
|
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 {
|
std::string operator()(const Term::Invalid&) const {
|
||||||
return "<invalid terminal>";
|
return "<invalid terminal>";
|
||||||
}
|
}
|
||||||
std::string operator()(const Term::Interpret& terminal) const {
|
|
||||||
return fmt::format("Interpret{{{}}}", terminal.next);
|
|
||||||
}
|
|
||||||
std::string operator()(const Term::ReturnToDispatch&) const {
|
std::string operator()(const Term::ReturnToDispatch&) const {
|
||||||
return "ReturnToDispatch{}";
|
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;
|
using Op = Dynarmic::IR::Opcode;
|
||||||
|
|
||||||
static IR::Value Value(bool is_32_bit, u64 value) {
|
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::ConstantPropagation(block);
|
||||||
Optimization::DeadCodeElimination(block);
|
Optimization::DeadCodeElimination(block);
|
||||||
}
|
}
|
||||||
if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) {
|
|
||||||
Optimization::A64MergeInterpretBlocksPass(block, conf.callbacks);
|
|
||||||
}
|
|
||||||
Optimization::IdentityRemovalPass(block);
|
Optimization::IdentityRemovalPass(block);
|
||||||
if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
|
if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
|
||||||
Optimization::VerificationPass(block);
|
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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -19,17 +19,6 @@ namespace Term {
|
||||||
|
|
||||||
struct Invalid {};
|
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.
|
* This terminal instruction returns control to the dispatcher.
|
||||||
* The dispatcher will use the current cpu state to determine what comes next.
|
* 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.
|
/// A Terminal is the terminal instruction in a MicroBlock.
|
||||||
using Terminal = boost::variant<
|
using Terminal = boost::variant<
|
||||||
Invalid,
|
Invalid,
|
||||||
Interpret,
|
|
||||||
ReturnToDispatch,
|
ReturnToDispatch,
|
||||||
LinkBlock,
|
LinkBlock,
|
||||||
LinkBlockFast,
|
LinkBlockFast,
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,6 @@ bool AnyLocationDescriptorForTerminalHas(IR::Terminal terminal, Fn fn) {
|
||||||
return fn(t.next);
|
return fn(t.next);
|
||||||
} else if constexpr (std::is_same_v<T, IR::Term::PopRSBHint>) {
|
} else if constexpr (std::is_same_v<T, IR::Term::PopRSBHint>) {
|
||||||
return false;
|
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>) {
|
} else if constexpr (std::is_same_v<T, IR::Term::FastDispatchHint>) {
|
||||||
return false;
|
return false;
|
||||||
} else if constexpr (std::is_same_v<T, IR::Term::If>) {
|
} 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;
|
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; })) {
|
if (AnyLocationDescriptorForTerminalHas(block.GetTerminal(), [&](IR::LocationDescriptor ld) { return A32::LocationDescriptor{ld}.PC() <= pc; })) {
|
||||||
return false;
|
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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -97,10 +97,6 @@ public:
|
||||||
MemoryWrite32(vaddr + 4, static_cast<u32>(value >> 32));
|
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 {
|
void CallSVC(std::uint32_t swi) override {
|
||||||
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
|
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
|
||||||
}
|
}
|
||||||
|
|
@ -190,10 +186,6 @@ public:
|
||||||
return true;
|
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 {
|
void CallSVC(std::uint32_t swi) override {
|
||||||
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
|
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,11 +69,6 @@ public:
|
||||||
MemoryWrite64(vaddr + 8, value[1]);
|
MemoryWrite64(vaddr + 8, value[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterFallback(u64, size_t) override {
|
|
||||||
// This is never called in practice.
|
|
||||||
std::terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CallSVC(u32) override {
|
void CallSVC(u32) override {
|
||||||
// Do something.
|
// 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);
|
bool should_continue = A64::TranslateSingleInstruction(block, location, instruction);
|
||||||
if (!should_continue && !is_last_inst)
|
if (!should_continue && !is_last_inst)
|
||||||
return false;
|
return false;
|
||||||
if (auto terminal = block.GetTerminal(); boost::get<IR::Term::Interpret>(&terminal))
|
|
||||||
return false;
|
|
||||||
for (const auto& ir_inst : block.instructions) {
|
for (const auto& ir_inst : block.instructions) {
|
||||||
switch (ir_inst.GetOpcode()) {
|
switch (ir_inst.GetOpcode()) {
|
||||||
case IR::Opcode::A64ExceptionRaised:
|
case IR::Opcode::A64ExceptionRaised:
|
||||||
|
|
|
||||||
|
|
@ -105,10 +105,6 @@ public:
|
||||||
return true;
|
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 {
|
void CallSVC(std::uint32_t swi) override {
|
||||||
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
|
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
|
||||||
}
|
}
|
||||||
|
|
@ -208,10 +204,6 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterFallback(u64 pc, size_t num_instructions) override {
|
|
||||||
ASSERT(ignore_invalid_insn && "InterpreterFallback");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CallSVC(std::uint32_t swi) override {
|
void CallSVC(std::uint32_t swi) override {
|
||||||
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
|
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,9 +152,6 @@ public:
|
||||||
MemoryWrite32(vaddr + 4, static_cast<u32>(value >> 32));
|
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 {
|
void CallSVC(std::uint32_t swi) override {
|
||||||
fmt::print("> CallSVC({})\n", swi);
|
fmt::print("> CallSVC({})\n", swi);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,6 @@ namespace {
|
||||||
using namespace Dynarmic;
|
using namespace Dynarmic;
|
||||||
|
|
||||||
bool ShouldTestInst(IR::Block& block) {
|
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) {
|
for (const auto& ir_inst : block.instructions) {
|
||||||
switch (ir_inst.GetOpcode()) {
|
switch (ir_inst.GetOpcode()) {
|
||||||
// A32
|
// A32
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue