diff options
author | Avi Kivity <avi@redhat.com> | 2011-09-13 03:45:39 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-09-25 12:52:46 -0400 |
commit | 3329ece161ad65ea31d825720e270f3a79ebba92 (patch) | |
tree | 336cda6a274297afb8424de8d1beb4f4b62cf4f9 /arch | |
parent | cc0793968a602c9b40f7b99c401674750aa99e06 (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.c | 82 |
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 | ||
1666 | static int em_grp3(struct x86_emulate_ctxt *ctxt) | 1666 | static int em_not(struct x86_emulate_ctxt *ctxt) |
1667 | { | ||
1668 | ctxt->dst.val = ~ctxt->dst.val; | ||
1669 | return X86EMUL_CONTINUE; | ||
1670 | } | ||
1671 | |||
1672 | static int em_neg(struct x86_emulate_ctxt *ctxt) | ||
1673 | { | ||
1674 | emulate_1op(ctxt, "neg"); | ||
1675 | return X86EMUL_CONTINUE; | ||
1676 | } | ||
1677 | |||
1678 | static 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 | |||
1686 | static 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 | |||
1694 | static 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 */ | 1704 | static 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 | ||
2991 | static struct opcode group3[] = { | 3003 | static 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 | ||
2997 | static struct opcode group4[] = { | 3014 | static 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; |