Change Config to make fastmem_pointer of zero valid.

This changes Dynarmic::A32/A64::Config to store fastmem_pointer in
a std::optional<uintptr_t>, allowing the user to pass a zero base
address for the guest memory, which can be used to effectively
implement a shared address space between the host and the guest.
This commit is contained in:
Ash 2024-01-28 14:35:15 +03:00 committed by Merry
parent f884bc0dfc
commit 732a657694
9 changed files with 16 additions and 16 deletions

View file

@ -233,7 +233,7 @@ void A32AddressSpace::EmitPrelude() {
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
}
if (conf.fastmem_pointer) {
code.MOV(Xfastmem, mcl::bit_cast<u64>(conf.fastmem_pointer));
code.MOV(Xfastmem, *conf.fastmem_pointer);
}
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
@ -272,7 +272,7 @@ void A32AddressSpace::EmitPrelude() {
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
}
if (conf.fastmem_pointer) {
code.MOV(Xfastmem, mcl::bit_cast<u64>(conf.fastmem_pointer));
code.MOV(Xfastmem, *conf.fastmem_pointer);
}
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
@ -388,7 +388,7 @@ EmitConfig A32AddressSpace::GetEmitConfig() {
.detect_misaligned_access_via_page_table = conf.detect_misaligned_access_via_page_table,
.only_detect_misalignment_via_page_table_on_page_boundary = conf.only_detect_misalignment_via_page_table_on_page_boundary,
.fastmem_pointer = mcl::bit_cast<u64>(conf.fastmem_pointer),
.fastmem_pointer = conf.fastmem_pointer,
.recompile_on_fastmem_failure = conf.recompile_on_fastmem_failure,
.fastmem_address_space_bits = 32,
.silently_mirror_fastmem = true,

View file

@ -411,7 +411,7 @@ void A64AddressSpace::EmitPrelude() {
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
}
if (conf.fastmem_pointer) {
code.MOV(Xfastmem, mcl::bit_cast<u64>(conf.fastmem_pointer));
code.MOV(Xfastmem, *conf.fastmem_pointer);
}
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
@ -449,7 +449,7 @@ void A64AddressSpace::EmitPrelude() {
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
}
if (conf.fastmem_pointer) {
code.MOV(Xfastmem, mcl::bit_cast<u64>(conf.fastmem_pointer));
code.MOV(Xfastmem, *conf.fastmem_pointer);
}
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
@ -564,7 +564,7 @@ EmitConfig A64AddressSpace::GetEmitConfig() {
.detect_misaligned_access_via_page_table = conf.detect_misaligned_access_via_page_table,
.only_detect_misalignment_via_page_table_on_page_boundary = conf.only_detect_misalignment_via_page_table_on_page_boundary,
.fastmem_pointer = mcl::bit_cast<u64>(conf.fastmem_pointer),
.fastmem_pointer = conf.fastmem_pointer,
.recompile_on_fastmem_failure = conf.recompile_on_fastmem_failure,
.fastmem_address_space_bits = conf.fastmem_address_space_bits,
.silently_mirror_fastmem = conf.silently_mirror_fastmem,

View file

@ -132,7 +132,7 @@ struct EmitConfig {
bool only_detect_misalignment_via_page_table_on_page_boundary;
// Fastmem
u64 fastmem_pointer;
std::optional<u64> fastmem_pointer;
bool recompile_on_fastmem_failure;
size_t fastmem_address_space_bits;
bool silently_mirror_fastmem;

View file

@ -47,7 +47,7 @@ static std::function<void(BlockOfCode&)> GenRCP(const A32::UserConfig& conf) {
code.mov(code.r14, mcl::bit_cast<u64>(conf.page_table));
}
if (conf.fastmem_pointer) {
code.mov(code.r13, mcl::bit_cast<u64>(conf.fastmem_pointer));
code.mov(code.r13, *conf.fastmem_pointer);
}
};
}

View file

@ -43,7 +43,7 @@ static std::function<void(BlockOfCode&)> GenRCP(const A64::UserConfig& conf) {
code.mov(code.r14, mcl::bit_cast<u64>(conf.page_table));
}
if (conf.fastmem_pointer) {
code.mov(code.r13, mcl::bit_cast<u64>(conf.fastmem_pointer));
code.mov(code.r13, *conf.fastmem_pointer);
}
};
}

View file

@ -182,7 +182,7 @@ struct UserConfig {
// This should point to the beginning of a 4GB address space which is in arranged just like
// what you wish for emulated memory to be. If the host page faults on an address, the JIT
// will fallback to calling the MemoryRead*/MemoryWrite* callbacks.
void* fastmem_pointer = nullptr;
std::optional<uintptr_t> fastmem_pointer = std::nullopt;
/// Determines if instructions that pagefault should cause recompilation of that block
/// with fastmem disabled.
/// Recompiled code will use the page_table if this is available, otherwise memory

View file

@ -241,7 +241,7 @@ struct UserConfig {
/// address space which is in arranged just like what you wish for emulated memory to
/// be. If the host page faults on an address, the JIT will fallback to calling the
/// MemoryRead*/MemoryWrite* callbacks.
void* fastmem_pointer = nullptr;
std::optional<uintptr_t> fastmem_pointer = std::nullopt;
/// Determines if instructions that pagefault should cause recompilation of that block
/// with fastmem disabled.
/// Recompiled code will use the page_table if this is available, otherwise memory
@ -249,13 +249,13 @@ struct UserConfig {
bool recompile_on_fastmem_failure = true;
/// Declares how many valid address bits are there in virtual addresses.
/// Determines the size of fastmem arena. Valid values are between 12 and 64 inclusive.
/// This is only used if fastmem_pointer is not nullptr.
/// This is only used if fastmem_pointer is set.
size_t fastmem_address_space_bits = 36;
/// Determines what happens if the guest accesses an entry that is off the end of the
/// fastmem arena. If true, Dynarmic will silently mirror fastmem's address space. If
/// false, accessing memory outside of fastmem bounds will result in a call to the
/// relevant memory callback.
/// This is only used if fastmem_pointer is not nullptr.
/// This is only used if fastmem_pointer is set.
bool silently_mirror_fastmem = true;
/// Determines if we should use the above fastmem_pointer for exclusive reads and

View file

@ -540,7 +540,7 @@ TEST_CASE("arm: Memory access (fastmem)", "[arm][A32]") {
A32FastmemTestEnv env{backing_memory};
Dynarmic::A32::UserConfig config{&env};
config.fastmem_pointer = backing_memory;
config.fastmem_pointer = reinterpret_cast<uintptr_t>(backing_memory);
config.recompile_on_fastmem_failure = false;
config.processor_id = 0;

File diff suppressed because one or more lines are too long