diff --git a/src/dynarmic/backend/arm64/address_space.cpp b/src/dynarmic/backend/arm64/address_space.cpp index 22767977..00f2fcd3 100644 --- a/src/dynarmic/backend/arm64/address_space.cpp +++ b/src/dynarmic/backend/arm64/address_space.cpp @@ -30,6 +30,15 @@ CodePtr AddressSpace::Get(IR::LocationDescriptor descriptor) { return nullptr; } +std::optional AddressSpace::ReverseGet(CodePtr host_pc) { + if (auto iter = reverse_block_entries.upper_bound(host_pc); iter != reverse_block_entries.begin()) { + // upper_bound locates the first value greater than host_pc, so we need to decrement + --iter; + return IR::LocationDescriptor{iter->second}; + } + return std::nullopt; +} + CodePtr AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) { if (CodePtr block_entry = Get(descriptor)) { return block_entry; @@ -40,11 +49,13 @@ CodePtr AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) { block_infos.insert_or_assign(descriptor.Value(), block_info); block_entries.insert_or_assign(descriptor.Value(), block_info.entry_point); + reverse_block_entries.insert_or_assign(block_info.entry_point, descriptor.Value()); return block_info.entry_point; } void AddressSpace::ClearCache() { block_entries.clear(); + reverse_block_entries.clear(); block_infos.clear(); block_references.clear(); code.set_ptr(prelude_info.end_of_prelude); diff --git a/src/dynarmic/backend/arm64/address_space.h b/src/dynarmic/backend/arm64/address_space.h index 4feda44a..65e7ec98 100644 --- a/src/dynarmic/backend/arm64/address_space.h +++ b/src/dynarmic/backend/arm64/address_space.h @@ -5,6 +5,9 @@ #pragma once +#include +#include + #include #include #include @@ -27,6 +30,9 @@ public: CodePtr Get(IR::LocationDescriptor descriptor); + // Returns "most likely" LocationDescriptor assocated with the emitted code at that location + std::optional ReverseGet(CodePtr host_pc); + CodePtr GetOrEmit(IR::LocationDescriptor descriptor); void ClearCache(); @@ -44,6 +50,7 @@ protected: oaknut::CodeGenerator code; tsl::robin_map block_entries; + std::map reverse_block_entries; tsl::robin_map block_infos; tsl::robin_map> block_references;