Commit 3329ece1 authored by Avi Kivity's avatar Avi Kivity

KVM: x86 emulator: convert group 3 instructions to direct decode

Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent cc079396
...@@ -1663,37 +1663,49 @@ static int em_grp2(struct x86_emulate_ctxt *ctxt) ...@@ -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)
{ {
u8 de = 0;
switch (ctxt->modrm_reg) {
case 0 ... 1: /* test */
emulate_2op_SrcV(ctxt, "test");
/* Disable writeback. */
ctxt->dst.type = OP_NONE;
break;
case 2: /* not */
ctxt->dst.val = ~ctxt->dst.val; ctxt->dst.val = ~ctxt->dst.val;
break; return X86EMUL_CONTINUE;
case 3: /* neg */ }
static int em_neg(struct x86_emulate_ctxt *ctxt)
{
emulate_1op(ctxt, "neg"); emulate_1op(ctxt, "neg");
break; return X86EMUL_CONTINUE;
case 4: /* mul */ }
emulate_1op_rax_rdx(ctxt, "mul", de);
break; static int em_mul_ex(struct x86_emulate_ctxt *ctxt)
case 5: /* imul */ {
emulate_1op_rax_rdx(ctxt, "imul", de); u8 ex = 0;
break;
case 6: /* div */ 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;
emulate_1op_rax_rdx(ctxt, "div", de); emulate_1op_rax_rdx(ctxt, "div", de);
break; if (de)
case 7: /* idiv */ return emulate_de(ctxt);
return X86EMUL_CONTINUE;
}
static int em_idiv_ex(struct x86_emulate_ctxt *ctxt)
{
u8 de = 0;
emulate_1op_rax_rdx(ctxt, "idiv", de); 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[] = { ...@@ -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 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -3917,9 +3934,6 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
/* 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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment