diff options
author | Avi Kivity <avi@redhat.com> | 2010-08-18 07:16:35 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-10-24 04:51:11 -0400 |
commit | 7af04fc05cc185869271927eb470de3d25064b4a (patch) | |
tree | 5f9903d0d7bdc2c7187970354ee6b40476e20646 | |
parent | fb2c264105c64511dbd1a7488b482960895aace4 (diff) |
KVM: x86 emulator: implement DAS (opcode 2F)
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/kvm/emulate.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 81b0f8848960..83ded7c03d12 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2175,6 +2175,45 @@ static int em_push(struct x86_emulate_ctxt *ctxt) | |||
2175 | return X86EMUL_CONTINUE; | 2175 | return X86EMUL_CONTINUE; |
2176 | } | 2176 | } |
2177 | 2177 | ||
2178 | static int em_das(struct x86_emulate_ctxt *ctxt) | ||
2179 | { | ||
2180 | struct decode_cache *c = &ctxt->decode; | ||
2181 | u8 al, old_al; | ||
2182 | bool af, cf, old_cf; | ||
2183 | |||
2184 | cf = ctxt->eflags & X86_EFLAGS_CF; | ||
2185 | al = c->dst.val; | ||
2186 | |||
2187 | old_al = al; | ||
2188 | old_cf = cf; | ||
2189 | cf = false; | ||
2190 | af = ctxt->eflags & X86_EFLAGS_AF; | ||
2191 | if ((al & 0x0f) > 9 || af) { | ||
2192 | al -= 6; | ||
2193 | cf = old_cf | (al >= 250); | ||
2194 | af = true; | ||
2195 | } else { | ||
2196 | af = false; | ||
2197 | } | ||
2198 | if (old_al > 0x99 || old_cf) { | ||
2199 | al -= 0x60; | ||
2200 | cf = true; | ||
2201 | } | ||
2202 | |||
2203 | c->dst.val = al; | ||
2204 | /* Set PF, ZF, SF */ | ||
2205 | c->src.type = OP_IMM; | ||
2206 | c->src.val = 0; | ||
2207 | c->src.bytes = 1; | ||
2208 | emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags); | ||
2209 | ctxt->eflags &= ~(X86_EFLAGS_AF | X86_EFLAGS_CF); | ||
2210 | if (cf) | ||
2211 | ctxt->eflags |= X86_EFLAGS_CF; | ||
2212 | if (af) | ||
2213 | ctxt->eflags |= X86_EFLAGS_AF; | ||
2214 | return X86EMUL_CONTINUE; | ||
2215 | } | ||
2216 | |||
2178 | #define D(_y) { .flags = (_y) } | 2217 | #define D(_y) { .flags = (_y) } |
2179 | #define N D(0) | 2218 | #define N D(0) |
2180 | #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) } | 2219 | #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) } |
@@ -2258,7 +2297,8 @@ static struct opcode opcode_table[256] = { | |||
2258 | /* 0x28 - 0x2F */ | 2297 | /* 0x28 - 0x2F */ |
2259 | D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock), | 2298 | D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock), |
2260 | D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), | 2299 | D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), |
2261 | D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N, | 2300 | D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), |
2301 | N, I(ByteOp | DstAcc | No64, em_das), | ||
2262 | /* 0x30 - 0x37 */ | 2302 | /* 0x30 - 0x37 */ |
2263 | D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock), | 2303 | D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock), |
2264 | D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), | 2304 | D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), |