aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarkus Wick <[email protected]>2021-06-05 12:20:21 +0200
committermerry <[email protected]>2021-06-06 17:25:51 +0100
commit0c12614d1a7a72d778609920dde96a4c63074ece (patch)
tree3c25c7f9a445f42f09749badba90a72199482c77
parent828959caedfac2d456a0c877fda4612e35fffc03 (diff)
downloaddynarmic-0c12614d1a7a72d778609920dde96a4c63074ece.tar.gz
dynarmic-0c12614d1a7a72d778609920dde96a4c63074ece.zip
A64/config.h: Split fastmem and page_table options.
We might want to allocate different sizes for each of them. e.g. for the unsafe fastmem approach without bounds checking. Or for using the full 48bit adress range (with mirrors) by allocating our real arena as close to 1<<47 as possible.
-rw-r--r--src/dynarmic/backend/x64/a64_emit_x64.cpp12
-rw-r--r--src/dynarmic/interface/A64/config.h14
-rw-r--r--tests/A64/a64.cpp4
3 files changed, 20 insertions, 10 deletions
diff --git a/src/dynarmic/backend/x64/a64_emit_x64.cpp b/src/dynarmic/backend/x64/a64_emit_x64.cpp
index d591b716..6690e68e 100644
--- a/src/dynarmic/backend/x64/a64_emit_x64.cpp
+++ b/src/dynarmic/backend/x64/a64_emit_x64.cpp
@@ -881,11 +881,11 @@ Xbyak::RegExp EmitVAddrLookup(BlockOfCode& code, A64EmitContext& ctx, size_t bit
}
Xbyak::RegExp EmitFastmemVAddr(BlockOfCode& code, A64EmitContext& ctx, Xbyak::Label& abort, Xbyak::Reg64 vaddr, bool& require_abort_handling) {
- const size_t unused_top_bits = 64 - ctx.conf.page_table_address_space_bits;
+ const size_t unused_top_bits = 64 - ctx.conf.fastmem_address_space_bits;
if (unused_top_bits == 0) {
return r13 + vaddr;
- } else if (ctx.conf.silently_mirror_page_table) {
+ } else if (ctx.conf.silently_mirror_fastmem) {
Xbyak::Reg64 tmp = ctx.reg_alloc.ScratchGpr();
if (unused_top_bits < 32) {
code.mov(tmp, vaddr);
@@ -895,19 +895,19 @@ Xbyak::RegExp EmitFastmemVAddr(BlockOfCode& code, A64EmitContext& ctx, Xbyak::La
code.mov(tmp.cvt32(), vaddr.cvt32());
} else {
code.mov(tmp.cvt32(), vaddr.cvt32());
- code.and_(tmp, u32((1 << ctx.conf.page_table_address_space_bits) - 1));
+ code.and_(tmp, u32((1 << ctx.conf.fastmem_address_space_bits) - 1));
}
return r13 + tmp;
} else {
- if (ctx.conf.page_table_address_space_bits < 32) {
- code.test(vaddr, u32(-(1 << ctx.conf.page_table_address_space_bits)));
+ if (ctx.conf.fastmem_address_space_bits < 32) {
+ code.test(vaddr, u32(-(1 << ctx.conf.fastmem_address_space_bits)));
code.jnz(abort, code.T_NEAR);
require_abort_handling = true;
} else {
// TODO: Consider having TEST as above but coalesce 64-bit constant in register allocator
Xbyak::Reg64 tmp = ctx.reg_alloc.ScratchGpr();
code.mov(tmp, vaddr);
- code.shr(tmp, int(ctx.conf.page_table_address_space_bits));
+ code.shr(tmp, int(ctx.conf.fastmem_address_space_bits));
code.jnz(abort, code.T_NEAR);
require_abort_handling = true;
}
diff --git a/src/dynarmic/interface/A64/config.h b/src/dynarmic/interface/A64/config.h
index baa08577..1d4a758c 100644
--- a/src/dynarmic/interface/A64/config.h
+++ b/src/dynarmic/interface/A64/config.h
@@ -202,7 +202,7 @@ struct UserConfig {
void** page_table = nullptr;
/// Declares how many valid address bits are there in virtual addresses.
/// Determines the size of page_table. Valid values are between 12 and 64 inclusive.
- /// This is only used if page_table or fastmem_pointer is not nullptr.
+ /// This is only used if page_table is not nullptr.
size_t page_table_address_space_bits = 36;
/// Masks out the first N bits in host pointers from the page table.
/// The intention behind this is to allow users of Dynarmic to pack attributes in the
@@ -213,7 +213,7 @@ struct UserConfig {
/// page table. If true, Dynarmic will silently mirror page_table's address space. If
/// false, accessing memory outside of page_table bounds will result in a call to the
/// relevant memory callback.
- /// This is only used if page_table or fastmem_pointer is not nullptr.
+ /// This is only used if page_table is not nullptr.
bool silently_mirror_page_table = true;
/// Determines if the pointer in the page_table shall be offseted locally or globally.
/// 'false' will access page_table[addr >> bits][addr & mask]
@@ -243,6 +243,16 @@ struct UserConfig {
/// Recompiled code will use the page_table if this is available, otherwise memory
/// accesses will hit the memory callbacks.
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.
+ 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.
+ bool silently_mirror_fastmem = true;
/// This option relates to translation. Generally when we run into an unpredictable
/// instruction the ExceptionRaised callback is called. If this is true, we define
diff --git a/tests/A64/a64.cpp b/tests/A64/a64.cpp
index 84c74a99..6a465cfa 100644
--- a/tests/A64/a64.cpp
+++ b/tests/A64/a64.cpp
@@ -852,9 +852,9 @@ TEST_CASE("A64: Memory access (fastmem)", "[a64]") {
A64FastmemTestEnv env{backing_memory};
Dynarmic::A64::UserConfig config{&env};
config.fastmem_pointer = backing_memory;
- config.page_table_address_space_bits = address_width;
+ config.fastmem_address_space_bits = address_width;
config.recompile_on_fastmem_failure = false;
- config.silently_mirror_page_table = true;
+ config.silently_mirror_fastmem = true;
config.processor_id = 0;
Dynarmic::A64::Jit jit{config};