core/memory + arm/dynarmic: Use a global offset within our arm page table.

This saves us two x64 instructions per load/store instruction.

TODO: Clean up our memory code. We can use this optimization here as well.
This commit is contained in:
Markus Wick 2019-12-31 00:11:45 +01:00
parent 028b2718ed
commit 0986caa8d8
3 changed files with 18 additions and 10 deletions

2
externals/dynarmic vendored

@ -1 +1 @@
Subproject commit 087a74417abfb0a8ae3bc1463d0d476a9bf94e53 Subproject commit f6ae9e1c3311b747b7b91fd903c62bf40b3b9c88

View File

@ -141,6 +141,7 @@ std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit(Common::PageTable& pag
config.page_table = reinterpret_cast<void**>(page_table.pointers.data()); config.page_table = reinterpret_cast<void**>(page_table.pointers.data());
config.page_table_address_space_bits = address_space_bits; config.page_table_address_space_bits = address_space_bits;
config.silently_mirror_page_table = false; config.silently_mirror_page_table = false;
config.absolute_offset_page_table = true;
// Multi-process state // Multi-process state
config.processor_id = core_index; config.processor_id = core_index;

View File

@ -146,7 +146,7 @@ struct Memory::Impl {
u8* GetPointer(const VAddr vaddr) { u8* GetPointer(const VAddr vaddr) {
u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
if (page_pointer != nullptr) { if (page_pointer != nullptr) {
return page_pointer + (vaddr & PAGE_MASK); return page_pointer + vaddr;
} }
if (current_page_table->attributes[vaddr >> PAGE_BITS] == if (current_page_table->attributes[vaddr >> PAGE_BITS] ==
@ -229,7 +229,8 @@ struct Memory::Impl {
case Common::PageType::Memory: { case Common::PageType::Memory: {
DEBUG_ASSERT(page_table.pointers[page_index]); DEBUG_ASSERT(page_table.pointers[page_index]);
const u8* const src_ptr = page_table.pointers[page_index] + page_offset; const u8* const src_ptr =
page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
std::memcpy(dest_buffer, src_ptr, copy_amount); std::memcpy(dest_buffer, src_ptr, copy_amount);
break; break;
} }
@ -276,7 +277,8 @@ struct Memory::Impl {
case Common::PageType::Memory: { case Common::PageType::Memory: {
DEBUG_ASSERT(page_table.pointers[page_index]); DEBUG_ASSERT(page_table.pointers[page_index]);
u8* const dest_ptr = page_table.pointers[page_index] + page_offset; u8* const dest_ptr =
page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
std::memcpy(dest_ptr, src_buffer, copy_amount); std::memcpy(dest_ptr, src_buffer, copy_amount);
break; break;
} }
@ -322,7 +324,8 @@ struct Memory::Impl {
case Common::PageType::Memory: { case Common::PageType::Memory: {
DEBUG_ASSERT(page_table.pointers[page_index]); DEBUG_ASSERT(page_table.pointers[page_index]);
u8* dest_ptr = page_table.pointers[page_index] + page_offset; u8* dest_ptr =
page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
std::memset(dest_ptr, 0, copy_amount); std::memset(dest_ptr, 0, copy_amount);
break; break;
} }
@ -368,7 +371,8 @@ struct Memory::Impl {
} }
case Common::PageType::Memory: { case Common::PageType::Memory: {
DEBUG_ASSERT(page_table.pointers[page_index]); DEBUG_ASSERT(page_table.pointers[page_index]);
const u8* src_ptr = page_table.pointers[page_index] + page_offset; const u8* src_ptr =
page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
WriteBlock(process, dest_addr, src_ptr, copy_amount); WriteBlock(process, dest_addr, src_ptr, copy_amount);
break; break;
} }
@ -446,7 +450,8 @@ struct Memory::Impl {
page_type = Common::PageType::Unmapped; page_type = Common::PageType::Unmapped;
} else { } else {
page_type = Common::PageType::Memory; page_type = Common::PageType::Memory;
current_page_table->pointers[vaddr >> PAGE_BITS] = pointer; current_page_table->pointers[vaddr >> PAGE_BITS] =
pointer - (vaddr & ~PAGE_MASK);
} }
break; break;
} }
@ -493,7 +498,9 @@ struct Memory::Impl {
memory); memory);
} else { } else {
while (base != end) { while (base != end) {
page_table.pointers[base] = memory; page_table.pointers[base] = memory - (base << PAGE_BITS);
ASSERT_MSG(page_table.pointers[base],
"memory mapping base yield a nullptr within the table");
base += 1; base += 1;
memory += PAGE_SIZE; memory += PAGE_SIZE;
@ -518,7 +525,7 @@ struct Memory::Impl {
if (page_pointer != nullptr) { if (page_pointer != nullptr) {
// NOTE: Avoid adding any extra logic to this fast-path block // NOTE: Avoid adding any extra logic to this fast-path block
T value; T value;
std::memcpy(&value, &page_pointer[vaddr & PAGE_MASK], sizeof(T)); std::memcpy(&value, &page_pointer[vaddr], sizeof(T));
return value; return value;
} }
@ -559,7 +566,7 @@ struct Memory::Impl {
u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
if (page_pointer != nullptr) { if (page_pointer != nullptr) {
// NOTE: Avoid adding any extra logic to this fast-path block // NOTE: Avoid adding any extra logic to this fast-path block
std::memcpy(&page_pointer[vaddr & PAGE_MASK], &data, sizeof(T)); std::memcpy(&page_pointer[vaddr], &data, sizeof(T));
return; return;
} }