aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAvi Kivity <avi.kivity@gmail.com>2013-01-19 12:51:51 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2013-01-23 19:15:35 -0500
commit007a3b547512d69f67ceb9641796d64552bd337e (patch)
treef0e1d3e4dd65117d08c3f385b3f5cf7411d39ea0 /arch
parent0bdea06892e33afddbdc5da6df305e9fe9c41365 (diff)
KVM: x86 emulator: convert shift/rotate instructions to fastop
SHL, SHR, ROL, ROR, RCL, RCR, SAR, SAL Reviewed-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi.kivity@gmail.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c72
1 files changed, 31 insertions, 41 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index a21773f22107..a94b1d76f799 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -478,6 +478,15 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
478 ON64(FOP2E(op##q, rax, rbx)) \ 478 ON64(FOP2E(op##q, rax, rbx)) \
479 FOP_END 479 FOP_END
480 480
481/* 2 operand, src is CL */
482#define FASTOP2CL(op) \
483 FOP_START(op) \
484 FOP2E(op##b, al, cl) \
485 FOP2E(op##w, ax, cl) \
486 FOP2E(op##l, eax, cl) \
487 ON64(FOP2E(op##q, rax, cl)) \
488 FOP_END
489
481#define FOP3E(op, dst, src, src2) \ 490#define FOP3E(op, dst, src, src2) \
482 FOP_ALIGN #op " %" #src2 ", %" #src ", %" #dst " \n\t" FOP_RET 491 FOP_ALIGN #op " %" #src2 ", %" #src ", %" #dst " \n\t" FOP_RET
483 492
@@ -2046,38 +2055,17 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
2046 return X86EMUL_CONTINUE; 2055 return X86EMUL_CONTINUE;
2047} 2056}
2048 2057
2049static int em_grp2(struct x86_emulate_ctxt *ctxt)
2050{
2051 switch (ctxt->modrm_reg) {
2052 case 0: /* rol */
2053 emulate_2op_SrcB(ctxt, "rol");
2054 break;
2055 case 1: /* ror */
2056 emulate_2op_SrcB(ctxt, "ror");
2057 break;
2058 case 2: /* rcl */
2059 emulate_2op_SrcB(ctxt, "rcl");
2060 break;
2061 case 3: /* rcr */
2062 emulate_2op_SrcB(ctxt, "rcr");
2063 break;
2064 case 4: /* sal/shl */
2065 case 6: /* sal/shl */
2066 emulate_2op_SrcB(ctxt, "sal");
2067 break;
2068 case 5: /* shr */
2069 emulate_2op_SrcB(ctxt, "shr");
2070 break;
2071 case 7: /* sar */
2072 emulate_2op_SrcB(ctxt, "sar");
2073 break;
2074 }
2075 return X86EMUL_CONTINUE;
2076}
2077
2078FASTOP1(not); 2058FASTOP1(not);
2079FASTOP1(neg); 2059FASTOP1(neg);
2080 2060
2061FASTOP2CL(rol);
2062FASTOP2CL(ror);
2063FASTOP2CL(rcl);
2064FASTOP2CL(rcr);
2065FASTOP2CL(shl);
2066FASTOP2CL(shr);
2067FASTOP2CL(sar);
2068
2081static int em_mul_ex(struct x86_emulate_ctxt *ctxt) 2069static int em_mul_ex(struct x86_emulate_ctxt *ctxt)
2082{ 2070{
2083 u8 ex = 0; 2071 u8 ex = 0;
@@ -3726,6 +3714,17 @@ static const struct opcode group1A[] = {
3726 I(DstMem | SrcNone | Mov | Stack, em_pop), N, N, N, N, N, N, N, 3714 I(DstMem | SrcNone | Mov | Stack, em_pop), N, N, N, N, N, N, N,
3727}; 3715};
3728 3716
3717static const struct opcode group2[] = {
3718 F(DstMem | ModRM, em_rol),
3719 F(DstMem | ModRM, em_ror),
3720 F(DstMem | ModRM, em_rcl),
3721 F(DstMem | ModRM, em_rcr),
3722 F(DstMem | ModRM, em_shl),
3723 F(DstMem | ModRM, em_shr),
3724 F(DstMem | ModRM, em_shl),
3725 F(DstMem | ModRM, em_sar),
3726};
3727
3729static const struct opcode group3[] = { 3728static const struct opcode group3[] = {
3730 F(DstMem | SrcImm | NoWrite, em_test), 3729 F(DstMem | SrcImm | NoWrite, em_test),
3731 F(DstMem | SrcImm | NoWrite, em_test), 3730 F(DstMem | SrcImm | NoWrite, em_test),
@@ -3949,7 +3948,7 @@ static const struct opcode opcode_table[256] = {
3949 /* 0xB8 - 0xBF */ 3948 /* 0xB8 - 0xBF */
3950 X8(I(DstReg | SrcImm64 | Mov, em_mov)), 3949 X8(I(DstReg | SrcImm64 | Mov, em_mov)),
3951 /* 0xC0 - 0xC7 */ 3950 /* 0xC0 - 0xC7 */
3952 D2bv(DstMem | SrcImmByte | ModRM), 3951 G(ByteOp | Src2ImmByte, group2), G(Src2ImmByte, group2),
3953 I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm), 3952 I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm),
3954 I(ImplicitOps | Stack, em_ret), 3953 I(ImplicitOps | Stack, em_ret),
3955 I(DstReg | SrcMemFAddr | ModRM | No64 | Src2ES, em_lseg), 3954 I(DstReg | SrcMemFAddr | ModRM | No64 | Src2ES, em_lseg),
@@ -3961,7 +3960,8 @@ static const struct opcode opcode_table[256] = {
3961 D(ImplicitOps), DI(SrcImmByte, intn), 3960 D(ImplicitOps), DI(SrcImmByte, intn),
3962 D(ImplicitOps | No64), II(ImplicitOps, em_iret, iret), 3961 D(ImplicitOps | No64), II(ImplicitOps, em_iret, iret),
3963 /* 0xD0 - 0xD7 */ 3962 /* 0xD0 - 0xD7 */
3964 D2bv(DstMem | SrcOne | ModRM), D2bv(DstMem | ModRM), 3963 G(Src2One | ByteOp, group2), G(Src2One, group2),
3964 G(Src2CL | ByteOp, group2), G(Src2CL, group2),
3965 N, I(DstAcc | SrcImmByte | No64, em_aad), N, N, 3965 N, I(DstAcc | SrcImmByte | No64, em_aad), N, N,
3966 /* 0xD8 - 0xDF */ 3966 /* 0xD8 - 0xDF */
3967 N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N, 3967 N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N,
@@ -4713,9 +4713,6 @@ special_insn:
4713 case 8: ctxt->dst.val = (s32)ctxt->dst.val; break; 4713 case 8: ctxt->dst.val = (s32)ctxt->dst.val; break;
4714 } 4714 }
4715 break; 4715 break;
4716 case 0xc0 ... 0xc1:
4717 rc = em_grp2(ctxt);
4718 break;
4719 case 0xcc: /* int3 */ 4716 case 0xcc: /* int3 */
4720 rc = emulate_int(ctxt, 3); 4717 rc = emulate_int(ctxt, 3);
4721 break; 4718 break;
@@ -4726,13 +4723,6 @@ special_insn:
4726 if (ctxt->eflags & EFLG_OF) 4723 if (ctxt->eflags & EFLG_OF)
4727 rc = emulate_int(ctxt, 4); 4724 rc = emulate_int(ctxt, 4);
4728 break; 4725 break;
4729 case 0xd0 ... 0xd1: /* Grp2 */
4730 rc = em_grp2(ctxt);
4731 break;
4732 case 0xd2 ... 0xd3: /* Grp2 */
4733 ctxt->src.val = reg_read(ctxt, VCPU_REGS_RCX);
4734 rc = em_grp2(ctxt);
4735 break;
4736 case 0xe9: /* jmp rel */ 4726 case 0xe9: /* jmp rel */
4737 case 0xeb: /* jmp rel short */ 4727 case 0xeb: /* jmp rel short */
4738 jmp_rel(ctxt, ctxt->src.val); 4728 jmp_rel(ctxt, ctxt->src.val);