diff options
| author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2011-11-22 01:21:33 -0500 |
|---|---|---|
| committer | Avi Kivity <avi@redhat.com> | 2011-12-27 04:17:32 -0500 |
| commit | ff227392cd7b858b2b04732e02697122fd1b35b0 (patch) | |
| tree | 5a316d27bca25dbe99ecadc963b70341bf7af93e | |
| parent | e940b5c20f89282fe826c5e2237932ab280497cf (diff) | |
KVM: x86 emulator: Use opcode::execute for BSF/BSR
BSF: 0F BC
BSR: 0F BD
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
| -rw-r--r-- | arch/x86/kvm/emulate.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 799000d8bf8b..4cd3313b4131 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
| @@ -2921,6 +2921,40 @@ static int em_btc(struct x86_emulate_ctxt *ctxt) | |||
| 2921 | return X86EMUL_CONTINUE; | 2921 | return X86EMUL_CONTINUE; |
| 2922 | } | 2922 | } |
| 2923 | 2923 | ||
| 2924 | static int em_bsf(struct x86_emulate_ctxt *ctxt) | ||
| 2925 | { | ||
| 2926 | u8 zf; | ||
| 2927 | |||
| 2928 | __asm__ ("bsf %2, %0; setz %1" | ||
| 2929 | : "=r"(ctxt->dst.val), "=q"(zf) | ||
| 2930 | : "r"(ctxt->src.val)); | ||
| 2931 | |||
| 2932 | ctxt->eflags &= ~X86_EFLAGS_ZF; | ||
| 2933 | if (zf) { | ||
| 2934 | ctxt->eflags |= X86_EFLAGS_ZF; | ||
| 2935 | /* Disable writeback. */ | ||
| 2936 | ctxt->dst.type = OP_NONE; | ||
| 2937 | } | ||
| 2938 | return X86EMUL_CONTINUE; | ||
| 2939 | } | ||
| 2940 | |||
| 2941 | static int em_bsr(struct x86_emulate_ctxt *ctxt) | ||
| 2942 | { | ||
| 2943 | u8 zf; | ||
| 2944 | |||
| 2945 | __asm__ ("bsr %2, %0; setz %1" | ||
| 2946 | : "=r"(ctxt->dst.val), "=q"(zf) | ||
| 2947 | : "r"(ctxt->src.val)); | ||
| 2948 | |||
| 2949 | ctxt->eflags &= ~X86_EFLAGS_ZF; | ||
| 2950 | if (zf) { | ||
| 2951 | ctxt->eflags |= X86_EFLAGS_ZF; | ||
| 2952 | /* Disable writeback. */ | ||
| 2953 | ctxt->dst.type = OP_NONE; | ||
| 2954 | } | ||
| 2955 | return X86EMUL_CONTINUE; | ||
| 2956 | } | ||
| 2957 | |||
| 2924 | static bool valid_cr(int nr) | 2958 | static bool valid_cr(int nr) |
| 2925 | { | 2959 | { |
| 2926 | switch (nr) { | 2960 | switch (nr) { |
| @@ -3428,7 +3462,7 @@ static struct opcode twobyte_table[256] = { | |||
| 3428 | N, N, | 3462 | N, N, |
| 3429 | G(BitOp, group8), | 3463 | G(BitOp, group8), |
| 3430 | I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc), | 3464 | I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc), |
| 3431 | D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), | 3465 | I(DstReg | SrcMem | ModRM, em_bsf), I(DstReg | SrcMem | ModRM, em_bsr), |
| 3432 | D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), | 3466 | D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), |
| 3433 | /* 0xC0 - 0xCF */ | 3467 | /* 0xC0 - 0xCF */ |
| 3434 | D2bv(DstMem | SrcReg | ModRM | Lock), | 3468 | D2bv(DstMem | SrcReg | ModRM | Lock), |
| @@ -4176,30 +4210,6 @@ twobyte_insn: | |||
| 4176 | ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val | 4210 | ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val |
| 4177 | : (u16) ctxt->src.val; | 4211 | : (u16) ctxt->src.val; |
| 4178 | break; | 4212 | break; |
| 4179 | case 0xbc: { /* bsf */ | ||
| 4180 | u8 zf; | ||
| 4181 | __asm__ ("bsf %2, %0; setz %1" | ||
| 4182 | : "=r"(ctxt->dst.val), "=q"(zf) | ||
| 4183 | : "r"(ctxt->src.val)); | ||
| 4184 | ctxt->eflags &= ~X86_EFLAGS_ZF; | ||
| 4185 | if (zf) { | ||
| 4186 | ctxt->eflags |= X86_EFLAGS_ZF; | ||
| 4187 | ctxt->dst.type = OP_NONE; /* Disable writeback. */ | ||
| 4188 | } | ||
| 4189 | break; | ||
| 4190 | } | ||
| 4191 | case 0xbd: { /* bsr */ | ||
| 4192 | u8 zf; | ||
| 4193 | __asm__ ("bsr %2, %0; setz %1" | ||
| 4194 | : "=r"(ctxt->dst.val), "=q"(zf) | ||
| 4195 | : "r"(ctxt->src.val)); | ||
| 4196 | ctxt->eflags &= ~X86_EFLAGS_ZF; | ||
| 4197 | if (zf) { | ||
| 4198 | ctxt->eflags |= X86_EFLAGS_ZF; | ||
| 4199 | ctxt->dst.type = OP_NONE; /* Disable writeback. */ | ||
| 4200 | } | ||
| 4201 | break; | ||
| 4202 | } | ||
| 4203 | case 0xbe ... 0xbf: /* movsx */ | 4213 | case 0xbe ... 0xbf: /* movsx */ |
| 4204 | ctxt->dst.bytes = ctxt->op_bytes; | 4214 | ctxt->dst.bytes = ctxt->op_bytes; |
| 4205 | ctxt->dst.val = (ctxt->d & ByteOp) ? (s8) ctxt->src.val : | 4215 | ctxt->dst.val = (ctxt->d & ByteOp) ? (s8) ctxt->src.val : |
