aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-08-18 07:16:35 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:51:11 -0400
commit7af04fc05cc185869271927eb470de3d25064b4a (patch)
tree5f9903d0d7bdc2c7187970354ee6b40476e20646 /arch/x86/kvm/emulate.c
parentfb2c264105c64511dbd1a7488b482960895aace4 (diff)
KVM: x86 emulator: implement DAS (opcode 2F)
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c42
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
2178static 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),