diff options
author | Avi Kivity <avi.kivity@gmail.com> | 2013-01-19 12:51:51 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2013-01-23 19:15:35 -0500 |
commit | 007a3b547512d69f67ceb9641796d64552bd337e (patch) | |
tree | f0e1d3e4dd65117d08c3f385b3f5cf7411d39ea0 /arch | |
parent | 0bdea06892e33afddbdc5da6df305e9fe9c41365 (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.c | 72 |
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 | ||
2049 | static 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 | |||
2078 | FASTOP1(not); | 2058 | FASTOP1(not); |
2079 | FASTOP1(neg); | 2059 | FASTOP1(neg); |
2080 | 2060 | ||
2061 | FASTOP2CL(rol); | ||
2062 | FASTOP2CL(ror); | ||
2063 | FASTOP2CL(rcl); | ||
2064 | FASTOP2CL(rcr); | ||
2065 | FASTOP2CL(shl); | ||
2066 | FASTOP2CL(shr); | ||
2067 | FASTOP2CL(sar); | ||
2068 | |||
2081 | static int em_mul_ex(struct x86_emulate_ctxt *ctxt) | 2069 | static 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 | ||
3717 | static 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 | |||
3729 | static const struct opcode group3[] = { | 3728 | static 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); |