KVM: x86 emulator: convert group 3 instructions to direct decode
Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
cc0793968a
commit
3329ece161
|
@ -1663,37 +1663,49 @@ static int em_grp2(struct x86_emulate_ctxt *ctxt)
|
||||||
return X86EMUL_CONTINUE;
|
return X86EMUL_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int em_grp3(struct x86_emulate_ctxt *ctxt)
|
static int em_not(struct x86_emulate_ctxt *ctxt)
|
||||||
|
{
|
||||||
|
ctxt->dst.val = ~ctxt->dst.val;
|
||||||
|
return X86EMUL_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int em_neg(struct x86_emulate_ctxt *ctxt)
|
||||||
|
{
|
||||||
|
emulate_1op(ctxt, "neg");
|
||||||
|
return X86EMUL_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int em_mul_ex(struct x86_emulate_ctxt *ctxt)
|
||||||
|
{
|
||||||
|
u8 ex = 0;
|
||||||
|
|
||||||
|
emulate_1op_rax_rdx(ctxt, "mul", ex);
|
||||||
|
return X86EMUL_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int em_imul_ex(struct x86_emulate_ctxt *ctxt)
|
||||||
|
{
|
||||||
|
u8 ex = 0;
|
||||||
|
|
||||||
|
emulate_1op_rax_rdx(ctxt, "imul", ex);
|
||||||
|
return X86EMUL_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int em_div_ex(struct x86_emulate_ctxt *ctxt)
|
||||||
{
|
{
|
||||||
u8 de = 0;
|
u8 de = 0;
|
||||||
|
|
||||||
switch (ctxt->modrm_reg) {
|
emulate_1op_rax_rdx(ctxt, "div", de);
|
||||||
case 0 ... 1: /* test */
|
if (de)
|
||||||
emulate_2op_SrcV(ctxt, "test");
|
return emulate_de(ctxt);
|
||||||
/* Disable writeback. */
|
return X86EMUL_CONTINUE;
|
||||||
ctxt->dst.type = OP_NONE;
|
}
|
||||||
break;
|
|
||||||
case 2: /* not */
|
static int em_idiv_ex(struct x86_emulate_ctxt *ctxt)
|
||||||
ctxt->dst.val = ~ctxt->dst.val;
|
{
|
||||||
break;
|
u8 de = 0;
|
||||||
case 3: /* neg */
|
|
||||||
emulate_1op(ctxt, "neg");
|
emulate_1op_rax_rdx(ctxt, "idiv", de);
|
||||||
break;
|
|
||||||
case 4: /* mul */
|
|
||||||
emulate_1op_rax_rdx(ctxt, "mul", de);
|
|
||||||
break;
|
|
||||||
case 5: /* imul */
|
|
||||||
emulate_1op_rax_rdx(ctxt, "imul", de);
|
|
||||||
break;
|
|
||||||
case 6: /* div */
|
|
||||||
emulate_1op_rax_rdx(ctxt, "div", de);
|
|
||||||
break;
|
|
||||||
case 7: /* idiv */
|
|
||||||
emulate_1op_rax_rdx(ctxt, "idiv", de);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return X86EMUL_UNHANDLEABLE;
|
|
||||||
}
|
|
||||||
if (de)
|
if (de)
|
||||||
return emulate_de(ctxt);
|
return emulate_de(ctxt);
|
||||||
return X86EMUL_CONTINUE;
|
return X86EMUL_CONTINUE;
|
||||||
|
@ -2989,9 +3001,14 @@ static struct opcode group1A[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct opcode group3[] = {
|
static struct opcode group3[] = {
|
||||||
D(DstMem | SrcImm | ModRM), D(DstMem | SrcImm | ModRM),
|
I(DstMem | SrcImm | ModRM, em_test),
|
||||||
D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
|
I(DstMem | SrcImm | ModRM, em_test),
|
||||||
X4(D(SrcMem | ModRM)),
|
I(DstMem | SrcNone | ModRM | Lock, em_not),
|
||||||
|
I(DstMem | SrcNone | ModRM | Lock, em_neg),
|
||||||
|
I(SrcMem | ModRM, em_mul_ex),
|
||||||
|
I(SrcMem | ModRM, em_imul_ex),
|
||||||
|
I(SrcMem | ModRM, em_div_ex),
|
||||||
|
I(SrcMem | ModRM, em_idiv_ex),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct opcode group4[] = {
|
static struct opcode group4[] = {
|
||||||
|
@ -3917,9 +3934,6 @@ special_insn:
|
||||||
/* complement carry flag from eflags reg */
|
/* complement carry flag from eflags reg */
|
||||||
ctxt->eflags ^= EFLG_CF;
|
ctxt->eflags ^= EFLG_CF;
|
||||||
break;
|
break;
|
||||||
case 0xf6 ... 0xf7: /* Grp3 */
|
|
||||||
rc = em_grp3(ctxt);
|
|
||||||
break;
|
|
||||||
case 0xf8: /* clc */
|
case 0xf8: /* clc */
|
||||||
ctxt->eflags &= ~EFLG_CF;
|
ctxt->eflags &= ~EFLG_CF;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue