A64/x64: Create a global_offset optimization for the page table.
Instead of looking up the page table like: table[addr >> 12][addr & 0xFFF] We can use a global offset on the table to query the memory like: table[addr >> 12][addr] This saves two instructions on *every* memory access within the recompiler. Thanks at skmp for the idea.
This commit is contained in:
parent
7be0038186
commit
93668c24be
2 changed files with 10 additions and 0 deletions
|
@ -163,6 +163,13 @@ struct UserConfig {
|
|||
/// relevant memory callback.
|
||||
/// 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]
|
||||
/// 'true' will access page_table[addr >> bits][addr]
|
||||
/// Note: page_table[addr >> bits] will still be checked to verify active pages.
|
||||
/// So there might be wrongly faulted pages which maps to nullptr.
|
||||
/// This can be avoided by carefully allocating the memory region.
|
||||
bool absolute_offset_page_table = false;
|
||||
|
||||
/// This option relates to translation. Generally when we run into an unpredictable
|
||||
/// instruction the ExceptionRaised callback is called. If this is true, we define
|
||||
|
|
|
@ -737,6 +737,9 @@ static Xbyak::RegExp EmitVAddrLookup(BlockOfCode& code, A64EmitContext& ctx, Xby
|
|||
code.mov(page_table, qword[page_table + tmp * sizeof(void*)]);
|
||||
code.test(page_table, page_table);
|
||||
code.jz(abort, code.T_NEAR);
|
||||
if (ctx.conf.absolute_offset_page_table) {
|
||||
return page_table + vaddr;
|
||||
}
|
||||
code.mov(tmp, vaddr);
|
||||
code.and_(tmp, static_cast<u32>(page_size - 1));
|
||||
return page_table + tmp;
|
||||
|
|
Loading…
Reference in a new issue