a64_emit_x64: EmitVAddrLookup: Use bzhi instruction when silently_mirror_page_table is active and BMI2 is available
This commit is contained in:
parent
809dfe9c54
commit
b32fc5ab0f
1 changed files with 14 additions and 3 deletions
|
@ -790,19 +790,30 @@ Xbyak::RegExp EmitVAddrLookup(BlockOfCode& code, A64EmitContext& ctx, size_t bit
|
||||||
|
|
||||||
EmitDetectMisaignedVAddr(code, ctx, bitsize, abort, vaddr, tmp);
|
EmitDetectMisaignedVAddr(code, ctx, bitsize, abort, vaddr, tmp);
|
||||||
|
|
||||||
code.mov(tmp, vaddr);
|
|
||||||
if (unused_top_bits == 0) {
|
if (unused_top_bits == 0) {
|
||||||
|
code.mov(tmp, vaddr);
|
||||||
code.shr(tmp, int(page_bits));
|
code.shr(tmp, int(page_bits));
|
||||||
} else if (ctx.conf.silently_mirror_page_table) {
|
} else if (ctx.conf.silently_mirror_page_table) {
|
||||||
if (valid_page_index_bits >= 32) {
|
if (valid_page_index_bits >= 32) {
|
||||||
|
if (code.HasBMI2()) {
|
||||||
|
const Xbyak::Reg64 bit_count = ctx.reg_alloc.ScratchGpr();
|
||||||
|
code.mov(bit_count, unused_top_bits);
|
||||||
|
code.bzhi(tmp, vaddr, bit_count);
|
||||||
|
code.shr(tmp, int(page_bits));
|
||||||
|
ctx.reg_alloc.Release(bit_count);
|
||||||
|
} else {
|
||||||
|
code.mov(tmp, vaddr);
|
||||||
code.shl(tmp, int(unused_top_bits));
|
code.shl(tmp, int(unused_top_bits));
|
||||||
code.shr(tmp, int(unused_top_bits + page_bits));
|
code.shr(tmp, int(unused_top_bits + page_bits));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
code.mov(tmp, vaddr);
|
||||||
code.shr(tmp, int(page_bits));
|
code.shr(tmp, int(page_bits));
|
||||||
code.and_(tmp, u32((1 << valid_page_index_bits) - 1));
|
code.and_(tmp, u32((1 << valid_page_index_bits) - 1));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ASSERT(valid_page_index_bits < 32);
|
ASSERT(valid_page_index_bits < 32);
|
||||||
|
code.mov(tmp, vaddr);
|
||||||
code.shr(tmp, int(page_bits));
|
code.shr(tmp, int(page_bits));
|
||||||
code.test(tmp, u32(-(1 << valid_page_index_bits)));
|
code.test(tmp, u32(-(1 << valid_page_index_bits)));
|
||||||
code.jnz(abort, code.T_NEAR);
|
code.jnz(abort, code.T_NEAR);
|
||||||
|
|
Loading…
Reference in a new issue