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:
parent
f884bc0dfc
commit
732a657694
9 changed files with 16 additions and 16 deletions
|
@ -233,7 +233,7 @@ void A32AddressSpace::EmitPrelude() {
|
||||||
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
||||||
}
|
}
|
||||||
if (conf.fastmem_pointer) {
|
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)) {
|
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
||||||
|
@ -272,7 +272,7 @@ void A32AddressSpace::EmitPrelude() {
|
||||||
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
||||||
}
|
}
|
||||||
if (conf.fastmem_pointer) {
|
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)) {
|
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,
|
.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,
|
.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,
|
.recompile_on_fastmem_failure = conf.recompile_on_fastmem_failure,
|
||||||
.fastmem_address_space_bits = 32,
|
.fastmem_address_space_bits = 32,
|
||||||
.silently_mirror_fastmem = true,
|
.silently_mirror_fastmem = true,
|
||||||
|
|
|
@ -411,7 +411,7 @@ void A64AddressSpace::EmitPrelude() {
|
||||||
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
||||||
}
|
}
|
||||||
if (conf.fastmem_pointer) {
|
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)) {
|
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
||||||
|
@ -449,7 +449,7 @@ void A64AddressSpace::EmitPrelude() {
|
||||||
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
code.MOV(Xpagetable, mcl::bit_cast<u64>(conf.page_table));
|
||||||
}
|
}
|
||||||
if (conf.fastmem_pointer) {
|
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)) {
|
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,
|
.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,
|
.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,
|
.recompile_on_fastmem_failure = conf.recompile_on_fastmem_failure,
|
||||||
.fastmem_address_space_bits = conf.fastmem_address_space_bits,
|
.fastmem_address_space_bits = conf.fastmem_address_space_bits,
|
||||||
.silently_mirror_fastmem = conf.silently_mirror_fastmem,
|
.silently_mirror_fastmem = conf.silently_mirror_fastmem,
|
||||||
|
|
|
@ -132,7 +132,7 @@ struct EmitConfig {
|
||||||
bool only_detect_misalignment_via_page_table_on_page_boundary;
|
bool only_detect_misalignment_via_page_table_on_page_boundary;
|
||||||
|
|
||||||
// Fastmem
|
// Fastmem
|
||||||
u64 fastmem_pointer;
|
std::optional<u64> fastmem_pointer;
|
||||||
bool recompile_on_fastmem_failure;
|
bool recompile_on_fastmem_failure;
|
||||||
size_t fastmem_address_space_bits;
|
size_t fastmem_address_space_bits;
|
||||||
bool silently_mirror_fastmem;
|
bool silently_mirror_fastmem;
|
||||||
|
|
|
@ -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));
|
code.mov(code.r14, mcl::bit_cast<u64>(conf.page_table));
|
||||||
}
|
}
|
||||||
if (conf.fastmem_pointer) {
|
if (conf.fastmem_pointer) {
|
||||||
code.mov(code.r13, mcl::bit_cast<u64>(conf.fastmem_pointer));
|
code.mov(code.r13, *conf.fastmem_pointer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
code.mov(code.r14, mcl::bit_cast<u64>(conf.page_table));
|
||||||
}
|
}
|
||||||
if (conf.fastmem_pointer) {
|
if (conf.fastmem_pointer) {
|
||||||
code.mov(code.r13, mcl::bit_cast<u64>(conf.fastmem_pointer));
|
code.mov(code.r13, *conf.fastmem_pointer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ struct UserConfig {
|
||||||
// This should point to the beginning of a 4GB address space which is in arranged just like
|
// 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
|
// 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.
|
// 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
|
/// Determines if instructions that pagefault should cause recompilation of that block
|
||||||
/// with fastmem disabled.
|
/// with fastmem disabled.
|
||||||
/// Recompiled code will use the page_table if this is available, otherwise memory
|
/// Recompiled code will use the page_table if this is available, otherwise memory
|
||||||
|
|
|
@ -241,7 +241,7 @@ struct UserConfig {
|
||||||
/// address space which is in arranged just like what you wish for emulated memory to
|
/// 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
|
/// be. If the host page faults on an address, the JIT will fallback to calling the
|
||||||
/// MemoryRead*/MemoryWrite* callbacks.
|
/// 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
|
/// Determines if instructions that pagefault should cause recompilation of that block
|
||||||
/// with fastmem disabled.
|
/// with fastmem disabled.
|
||||||
/// Recompiled code will use the page_table if this is available, otherwise memory
|
/// 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;
|
bool recompile_on_fastmem_failure = true;
|
||||||
/// Declares how many valid address bits are there in virtual addresses.
|
/// 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.
|
/// 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;
|
size_t fastmem_address_space_bits = 36;
|
||||||
/// Determines what happens if the guest accesses an entry that is off the end of the
|
/// 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
|
/// 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
|
/// false, accessing memory outside of fastmem bounds will result in a call to the
|
||||||
/// relevant memory callback.
|
/// 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;
|
bool silently_mirror_fastmem = true;
|
||||||
|
|
||||||
/// Determines if we should use the above fastmem_pointer for exclusive reads and
|
/// Determines if we should use the above fastmem_pointer for exclusive reads and
|
||||||
|
|
|
@ -540,7 +540,7 @@ TEST_CASE("arm: Memory access (fastmem)", "[arm][A32]") {
|
||||||
|
|
||||||
A32FastmemTestEnv env{backing_memory};
|
A32FastmemTestEnv env{backing_memory};
|
||||||
Dynarmic::A32::UserConfig config{&env};
|
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.recompile_on_fastmem_failure = false;
|
||||||
config.processor_id = 0;
|
config.processor_id = 0;
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue