forked from luck/tmp_suning_uos_patched
KVM: emulate: do not initialize memopp
rip_relative is only set if decode_modrm runs, and if you have ModRM you will also have a memopp. We can then access memopp unconditionally. Note that rip_relative cannot be hoisted up to decode_modrm, or you break "mov $0, xyz(%rip)". Also, move typecast on "out of range value" of mem.ea to decode_modrm. Together, all these optimizations save about 50 cycles on each emulated instructions (4-6%). Signed-off-by: Bandan Das <bsd@redhat.com> [Fix immediate operands with rip-relative addressing. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
573e80fe04
commit
41061cdb98
@ -295,6 +295,11 @@ struct x86_emulate_ctxt {
|
||||
struct operand dst;
|
||||
int (*execute)(struct x86_emulate_ctxt *ctxt);
|
||||
int (*check_perm)(struct x86_emulate_ctxt *ctxt);
|
||||
/*
|
||||
* The following six fields are cleared together,
|
||||
* the rest are initialized unconditionally in x86_decode_insn
|
||||
* or elsewhere
|
||||
*/
|
||||
bool rip_relative;
|
||||
u8 rex_prefix;
|
||||
u8 lock_prefix;
|
||||
|
@ -1177,6 +1177,9 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
|
||||
}
|
||||
}
|
||||
op->addr.mem.ea = modrm_ea;
|
||||
if (ctxt->ad_bytes != 8)
|
||||
ctxt->memop.addr.mem.ea = (u32)ctxt->memop.addr.mem.ea;
|
||||
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
@ -4425,9 +4428,6 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
|
||||
|
||||
ctxt->memop.addr.mem.seg = ctxt->seg_override;
|
||||
|
||||
if (ctxt->memop.type == OP_MEM && ctxt->ad_bytes != 8)
|
||||
ctxt->memop.addr.mem.ea = (u32)ctxt->memop.addr.mem.ea;
|
||||
|
||||
/*
|
||||
* Decode and fetch the source operand: register, memory
|
||||
* or immediate.
|
||||
@ -4448,7 +4448,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
|
||||
rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask);
|
||||
|
||||
done:
|
||||
if (ctxt->memopp && ctxt->memopp->type == OP_MEM && ctxt->rip_relative)
|
||||
if (ctxt->rip_relative)
|
||||
ctxt->memopp->addr.mem.ea += ctxt->_eip;
|
||||
|
||||
return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user