diff options
author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2011-11-22 01:17:48 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-12-27 04:17:25 -0500 |
commit | ce7faab24fbfb0b5207636ee4795e924bcf97e8a (patch) | |
tree | dee7b7ccc95d06cedf4dfd5943e50b8358d44721 /arch/x86/kvm/emulate.c | |
parent | d7841a4b1b6e8509881e1ec21c024c82ccf565a6 (diff) |
KVM: x86 emulator: Use opcode::execute for BT family
BT : 0F A3
BTS: 0F AB
BTR: 0F B3
BTC: 0F BB
Group 8: 0F BA
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 77 |
1 files changed, 38 insertions, 39 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8ba4ea8cac72..7a9ce6dbd1ce 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2813,6 +2813,35 @@ static int em_sti(struct x86_emulate_ctxt *ctxt) | |||
2813 | return X86EMUL_CONTINUE; | 2813 | return X86EMUL_CONTINUE; |
2814 | } | 2814 | } |
2815 | 2815 | ||
2816 | static int em_bt(struct x86_emulate_ctxt *ctxt) | ||
2817 | { | ||
2818 | /* Disable writeback. */ | ||
2819 | ctxt->dst.type = OP_NONE; | ||
2820 | /* only subword offset */ | ||
2821 | ctxt->src.val &= (ctxt->dst.bytes << 3) - 1; | ||
2822 | |||
2823 | emulate_2op_SrcV_nobyte(ctxt, "bt"); | ||
2824 | return X86EMUL_CONTINUE; | ||
2825 | } | ||
2826 | |||
2827 | static int em_bts(struct x86_emulate_ctxt *ctxt) | ||
2828 | { | ||
2829 | emulate_2op_SrcV_nobyte(ctxt, "bts"); | ||
2830 | return X86EMUL_CONTINUE; | ||
2831 | } | ||
2832 | |||
2833 | static int em_btr(struct x86_emulate_ctxt *ctxt) | ||
2834 | { | ||
2835 | emulate_2op_SrcV_nobyte(ctxt, "btr"); | ||
2836 | return X86EMUL_CONTINUE; | ||
2837 | } | ||
2838 | |||
2839 | static int em_btc(struct x86_emulate_ctxt *ctxt) | ||
2840 | { | ||
2841 | emulate_2op_SrcV_nobyte(ctxt, "btc"); | ||
2842 | return X86EMUL_CONTINUE; | ||
2843 | } | ||
2844 | |||
2816 | static bool valid_cr(int nr) | 2845 | static bool valid_cr(int nr) |
2817 | { | 2846 | { |
2818 | switch (nr) { | 2847 | switch (nr) { |
@@ -3117,10 +3146,10 @@ static struct group_dual group7 = { { | |||
3117 | 3146 | ||
3118 | static struct opcode group8[] = { | 3147 | static struct opcode group8[] = { |
3119 | N, N, N, N, | 3148 | N, N, N, N, |
3120 | D(DstMem | SrcImmByte | ModRM), | 3149 | I(DstMem | SrcImmByte | ModRM, em_bt), |
3121 | D(DstMem | SrcImmByte | ModRM | Lock | PageTable), | 3150 | I(DstMem | SrcImmByte | ModRM | Lock | PageTable, em_bts), |
3122 | D(DstMem | SrcImmByte | ModRM | Lock), | 3151 | I(DstMem | SrcImmByte | ModRM | Lock, em_btr), |
3123 | D(DstMem | SrcImmByte | ModRM | Lock | PageTable), | 3152 | I(DstMem | SrcImmByte | ModRM | Lock | PageTable, em_btc), |
3124 | }; | 3153 | }; |
3125 | 3154 | ||
3126 | static struct group_dual group9 = { { | 3155 | static struct group_dual group9 = { { |
@@ -3299,26 +3328,27 @@ static struct opcode twobyte_table[256] = { | |||
3299 | X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), | 3328 | X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), |
3300 | /* 0xA0 - 0xA7 */ | 3329 | /* 0xA0 - 0xA7 */ |
3301 | I(Stack | Src2FS, em_push_sreg), I(Stack | Src2FS, em_pop_sreg), | 3330 | I(Stack | Src2FS, em_push_sreg), I(Stack | Src2FS, em_pop_sreg), |
3302 | DI(ImplicitOps, cpuid), D(DstMem | SrcReg | ModRM | BitOp), | 3331 | DI(ImplicitOps, cpuid), I(DstMem | SrcReg | ModRM | BitOp, em_bt), |
3303 | D(DstMem | SrcReg | Src2ImmByte | ModRM), | 3332 | D(DstMem | SrcReg | Src2ImmByte | ModRM), |
3304 | D(DstMem | SrcReg | Src2CL | ModRM), N, N, | 3333 | D(DstMem | SrcReg | Src2CL | ModRM), N, N, |
3305 | /* 0xA8 - 0xAF */ | 3334 | /* 0xA8 - 0xAF */ |
3306 | I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg), | 3335 | I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg), |
3307 | DI(ImplicitOps, rsm), | 3336 | DI(ImplicitOps, rsm), |
3308 | D(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable), | 3337 | I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts), |
3309 | D(DstMem | SrcReg | Src2ImmByte | ModRM), | 3338 | D(DstMem | SrcReg | Src2ImmByte | ModRM), |
3310 | D(DstMem | SrcReg | Src2CL | ModRM), | 3339 | D(DstMem | SrcReg | Src2CL | ModRM), |
3311 | D(ModRM), I(DstReg | SrcMem | ModRM, em_imul), | 3340 | D(ModRM), I(DstReg | SrcMem | ModRM, em_imul), |
3312 | /* 0xB0 - 0xB7 */ | 3341 | /* 0xB0 - 0xB7 */ |
3313 | D2bv(DstMem | SrcReg | ModRM | Lock | PageTable), | 3342 | D2bv(DstMem | SrcReg | ModRM | Lock | PageTable), |
3314 | I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg), | 3343 | I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg), |
3315 | D(DstMem | SrcReg | ModRM | BitOp | Lock), | 3344 | I(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr), |
3316 | I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg), | 3345 | I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg), |
3317 | I(DstReg | SrcMemFAddr | ModRM | Src2GS, em_lseg), | 3346 | I(DstReg | SrcMemFAddr | ModRM | Src2GS, em_lseg), |
3318 | D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), | 3347 | D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), |
3319 | /* 0xB8 - 0xBF */ | 3348 | /* 0xB8 - 0xBF */ |
3320 | N, N, | 3349 | N, N, |
3321 | G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable), | 3350 | G(BitOp, group8), |
3351 | I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc), | ||
3322 | D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), | 3352 | D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), |
3323 | D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), | 3353 | D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), |
3324 | /* 0xC0 - 0xCF */ | 3354 | /* 0xC0 - 0xCF */ |
@@ -4103,21 +4133,10 @@ twobyte_insn: | |||
4103 | case 0x90 ... 0x9f: /* setcc r/m8 */ | 4133 | case 0x90 ... 0x9f: /* setcc r/m8 */ |
4104 | ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags); | 4134 | ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags); |
4105 | break; | 4135 | break; |
4106 | case 0xa3: | ||
4107 | bt: /* bt */ | ||
4108 | ctxt->dst.type = OP_NONE; | ||
4109 | /* only subword offset */ | ||
4110 | ctxt->src.val &= (ctxt->dst.bytes << 3) - 1; | ||
4111 | emulate_2op_SrcV_nobyte(ctxt, "bt"); | ||
4112 | break; | ||
4113 | case 0xa4: /* shld imm8, r, r/m */ | 4136 | case 0xa4: /* shld imm8, r, r/m */ |
4114 | case 0xa5: /* shld cl, r, r/m */ | 4137 | case 0xa5: /* shld cl, r, r/m */ |
4115 | emulate_2op_cl(ctxt, "shld"); | 4138 | emulate_2op_cl(ctxt, "shld"); |
4116 | break; | 4139 | break; |
4117 | case 0xab: | ||
4118 | bts: /* bts */ | ||
4119 | emulate_2op_SrcV_nobyte(ctxt, "bts"); | ||
4120 | break; | ||
4121 | case 0xac: /* shrd imm8, r, r/m */ | 4140 | case 0xac: /* shrd imm8, r, r/m */ |
4122 | case 0xad: /* shrd cl, r, r/m */ | 4141 | case 0xad: /* shrd cl, r, r/m */ |
4123 | emulate_2op_cl(ctxt, "shrd"); | 4142 | emulate_2op_cl(ctxt, "shrd"); |
@@ -4141,31 +4160,11 @@ twobyte_insn: | |||
4141 | ctxt->dst.addr.reg = (unsigned long *)&ctxt->regs[VCPU_REGS_RAX]; | 4160 | ctxt->dst.addr.reg = (unsigned long *)&ctxt->regs[VCPU_REGS_RAX]; |
4142 | } | 4161 | } |
4143 | break; | 4162 | break; |
4144 | case 0xb3: | ||
4145 | btr: /* btr */ | ||
4146 | emulate_2op_SrcV_nobyte(ctxt, "btr"); | ||
4147 | break; | ||
4148 | case 0xb6 ... 0xb7: /* movzx */ | 4163 | case 0xb6 ... 0xb7: /* movzx */ |
4149 | ctxt->dst.bytes = ctxt->op_bytes; | 4164 | ctxt->dst.bytes = ctxt->op_bytes; |
4150 | ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val | 4165 | ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val |
4151 | : (u16) ctxt->src.val; | 4166 | : (u16) ctxt->src.val; |
4152 | break; | 4167 | break; |
4153 | case 0xba: /* Grp8 */ | ||
4154 | switch (ctxt->modrm_reg & 3) { | ||
4155 | case 0: | ||
4156 | goto bt; | ||
4157 | case 1: | ||
4158 | goto bts; | ||
4159 | case 2: | ||
4160 | goto btr; | ||
4161 | case 3: | ||
4162 | goto btc; | ||
4163 | } | ||
4164 | break; | ||
4165 | case 0xbb: | ||
4166 | btc: /* btc */ | ||
4167 | emulate_2op_SrcV_nobyte(ctxt, "btc"); | ||
4168 | break; | ||
4169 | case 0xbc: { /* bsf */ | 4168 | case 0xbc: { /* bsf */ |
4170 | u8 zf; | 4169 | u8 zf; |
4171 | __asm__ ("bsf %2, %0; setz %1" | 4170 | __asm__ ("bsf %2, %0; setz %1" |