aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-09-13 03:45:39 -0400
committerAvi Kivity <avi@redhat.com>2011-09-25 12:52:46 -0400
commit3329ece161ad65ea31d825720e270f3a79ebba92 (patch)
tree336cda6a274297afb8424de8d1beb4f4b62cf4f9 /arch
parentcc0793968a602c9b40f7b99c401674750aa99e06 (diff)
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index af06539369b4..ed819bdf475d 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1663,37 +1663,49 @@ static int em_grp2(struct x86_emulate_ctxt *ctxt)
1663 return X86EMUL_CONTINUE; 1663 return X86EMUL_CONTINUE;
1664} 1664}
1665 1665
1666static int em_grp3(struct x86_emulate_ctxt *ctxt) 1666static int em_not(struct x86_emulate_ctxt *ctxt)
1667{
1668 ctxt->dst.val = ~ctxt->dst.val;
1669 return X86EMUL_CONTINUE;
1670}
1671
1672static int em_neg(struct x86_emulate_ctxt *ctxt)
1673{
1674 emulate_1op(ctxt, "neg");
1675 return X86EMUL_CONTINUE;
1676}
1677
1678static int em_mul_ex(struct x86_emulate_ctxt *ctxt)
1679{
1680 u8 ex = 0;
1681
1682 emulate_1op_rax_rdx(ctxt, "mul", ex);
1683 return X86EMUL_CONTINUE;
1684}
1685
1686static int em_imul_ex(struct x86_emulate_ctxt *ctxt)
1687{
1688 u8 ex = 0;
1689
1690 emulate_1op_rax_rdx(ctxt, "imul", ex);
1691 return X86EMUL_CONTINUE;
1692}
1693
1694static int em_div_ex(struct x86_emulate_ctxt *ctxt)
1667{ 1695{
1668 u8 de = 0; 1696 u8 de = 0;
1669 1697
1670 switch (ctxt->modrm_reg) { 1698 emulate_1op_rax_rdx(ctxt, "div", de);
1671 case 0 ... 1: /* test */ 1699 if (de)
1672 emulate_2op_SrcV(ctxt, "test"); 1700 return emulate_de(ctxt);
1673 /* Disable writeback. */ 1701 return X86EMUL_CONTINUE;
1674 ctxt->dst.type = OP_NONE; 1702}
1675 break; 1703
1676 case 2: /* not */ 1704static int em_idiv_ex(struct x86_emulate_ctxt *ctxt)
1677 ctxt->dst.val = ~ctxt->dst.val; 1705{
1678 break; 1706 u8 de = 0;
1679 case 3: /* neg */ 1707
1680 emulate_1op(ctxt, "neg"); 1708 emulate_1op_rax_rdx(ctxt, "idiv", de);
1681 break;
1682 case 4: /* mul */
1683 emulate_1op_rax_rdx(ctxt, "mul", de);
1684 break;
1685 case 5: /* imul */
1686 emulate_1op_rax_rdx(ctxt, "imul", de);
1687 break;
1688 case 6: /* div */
1689 emulate_1op_rax_rdx(ctxt, "div", de);
1690 break;
1691 case 7: /* idiv */
1692 emulate_1op_rax_rdx(ctxt, "idiv", de);
1693 break;
1694 default:
1695 return X86EMUL_UNHANDLEABLE;
1696 }
1697 if (de) 1709 if (de)
1698 return emulate_de(ctxt); 1710 return emulate_de(ctxt);
1699 return X86EMUL_CONTINUE; 1711 return X86EMUL_CONTINUE;
@@ -2989,9 +3001,14 @@ static struct opcode group1A[] = {
2989}; 3001};
2990 3002
2991static struct opcode group3[] = { 3003static struct opcode group3[] = {
2992 D(DstMem | SrcImm | ModRM), D(DstMem | SrcImm | ModRM), 3004 I(DstMem | SrcImm | ModRM, em_test),
2993 D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock), 3005 I(DstMem | SrcImm | ModRM, em_test),
2994 X4(D(SrcMem | ModRM)), 3006 I(DstMem | SrcNone | ModRM | Lock, em_not),
3007 I(DstMem | SrcNone | ModRM | Lock, em_neg),
3008 I(SrcMem | ModRM, em_mul_ex),
3009 I(SrcMem | ModRM, em_imul_ex),
3010 I(SrcMem | ModRM, em_div_ex),
3011 I(SrcMem | ModRM, em_idiv_ex),
2995}; 3012};
2996 3013
2997static struct opcode group4[] = { 3014static struct opcode group4[] = {
@@ -3917,9 +3934,6 @@ special_insn:
3917 /* complement carry flag from eflags reg */ 3934 /* complement carry flag from eflags reg */
3918 ctxt->eflags ^= EFLG_CF; 3935 ctxt->eflags ^= EFLG_CF;
3919 break; 3936 break;
3920 case 0xf6 ... 0xf7: /* Grp3 */
3921 rc = em_grp3(ctxt);
3922 break;
3923 case 0xf8: /* clc */ 3937 case 0xf8: /* clc */
3924 ctxt->eflags &= ~EFLG_CF; 3938 ctxt->eflags &= ~EFLG_CF;
3925 break; 3939 break;