Browse Source
[dynarmic] restore proper backtraces for A64 (#3794)
trivial changes, fixes hard crashes
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3794
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
pull/3798/head
lizzie
2 days ago
committed by
crueter
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
3 changed files with
19 additions and
8 deletions
-
src/core/arm/nce/interpreter_visitor.cpp
-
src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h
-
src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp
|
|
|
@ -773,7 +773,11 @@ std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, m |
|
|
|
bool was_executed = false; |
|
|
|
|
|
|
|
auto decoder = Dynarmic::A64::Decode<VisitorBase>(instruction); |
|
|
|
was_executed = decoder.get().call(visitor, instruction); |
|
|
|
if (decoder) { |
|
|
|
was_executed = decoder->get().call(visitor, instruction); |
|
|
|
} else { |
|
|
|
was_executed = false; |
|
|
|
} |
|
|
|
return was_executed ? std::optional<u64>(pc + 4) : std::nullopt; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -70,14 +70,15 @@ constexpr DecodeTable<V> GetDecodeTable() { |
|
|
|
|
|
|
|
/// In practice it must always suceed, otherwise something else unrelated would have gone awry |
|
|
|
template<typename V> |
|
|
|
std::reference_wrapper<const Matcher<V>> Decode(u32 instruction) { |
|
|
|
std::optional<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); |
|
|
|
}); |
|
|
|
DEBUG_ASSERT(iter != subtable.end()); |
|
|
|
return std::reference_wrapper<const Matcher<V>>(*iter); |
|
|
|
return iter != subtable.end() |
|
|
|
? std::optional{ std::reference_wrapper<const Matcher<V>>(*iter) } |
|
|
|
: std::nullopt; |
|
|
|
} |
|
|
|
|
|
|
|
template<typename V> |
|
|
|
|
|
|
|
@ -25,7 +25,11 @@ void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFu |
|
|
|
const u64 pc = visitor.ir.current_location->PC(); |
|
|
|
if (const auto instruction = memory_read_code(pc)) { |
|
|
|
auto decoder = Decode<TranslatorVisitor>(*instruction); |
|
|
|
should_continue = decoder.get().call(visitor, *instruction); |
|
|
|
if (decoder) { |
|
|
|
should_continue = decoder->get().call(visitor, *instruction); |
|
|
|
} else { |
|
|
|
should_continue = visitor.RaiseException(Exception::UnallocatedEncoding); |
|
|
|
} |
|
|
|
} else { |
|
|
|
should_continue = visitor.RaiseException(Exception::NoExecuteFault); |
|
|
|
} |
|
|
|
@ -45,13 +49,15 @@ bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, |
|
|
|
|
|
|
|
bool should_continue = true; |
|
|
|
auto const decoder = Decode<TranslatorVisitor>(instruction); |
|
|
|
should_continue = decoder.get().call(visitor, instruction); |
|
|
|
if (decoder) { |
|
|
|
should_continue = decoder->get().call(visitor, instruction); |
|
|
|
} else { |
|
|
|
should_continue = false; |
|
|
|
} |
|
|
|
|
|
|
|
visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4); |
|
|
|
block.CycleCount()++; |
|
|
|
|
|
|
|
block.SetEndLocation(*visitor.ir.current_location); |
|
|
|
|
|
|
|
return should_continue; |
|
|
|
} |
|
|
|
|
|
|
|
|