aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86_emulate.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-07-20 05:30:58 -0400
committerAvi Kivity <avi@qumranet.com>2007-10-13 04:18:19 -0400
commite3243452f4f35ed5f79d575100521bf257504b81 (patch)
treef694786005d9835c80070d11881872cc8e708b19 /drivers/kvm/x86_emulate.c
parent7075bc816cfad142da92207ed5a6f3da55b143ef (diff)
KVM: x86 emulator: fix cmov for writeback changes
The writeback fixes (02c03a326a5df825cc01de426f72e160db2b9538) broke cmov emulation. Fix. Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r--drivers/kvm/x86_emulate.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index db9f9553487d..82b4ea62c982 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -1235,40 +1235,40 @@ twobyte_insn:
1235 break; 1235 break;
1236 case 0x40 ... 0x4f: /* cmov */ 1236 case 0x40 ... 0x4f: /* cmov */
1237 dst.val = dst.orig_val = src.val; 1237 dst.val = dst.orig_val = src.val;
1238 d &= ~Mov; /* default to no move */ 1238 no_wb = 1;
1239 /* 1239 /*
1240 * First, assume we're decoding an even cmov opcode 1240 * First, assume we're decoding an even cmov opcode
1241 * (lsb == 0). 1241 * (lsb == 0).
1242 */ 1242 */
1243 switch ((b & 15) >> 1) { 1243 switch ((b & 15) >> 1) {
1244 case 0: /* cmovo */ 1244 case 0: /* cmovo */
1245 d |= (_eflags & EFLG_OF) ? Mov : 0; 1245 no_wb = (_eflags & EFLG_OF) ? 0 : 1;
1246 break; 1246 break;
1247 case 1: /* cmovb/cmovc/cmovnae */ 1247 case 1: /* cmovb/cmovc/cmovnae */
1248 d |= (_eflags & EFLG_CF) ? Mov : 0; 1248 no_wb = (_eflags & EFLG_CF) ? 0 : 1;
1249 break; 1249 break;
1250 case 2: /* cmovz/cmove */ 1250 case 2: /* cmovz/cmove */
1251 d |= (_eflags & EFLG_ZF) ? Mov : 0; 1251 no_wb = (_eflags & EFLG_ZF) ? 0 : 1;
1252 break; 1252 break;
1253 case 3: /* cmovbe/cmovna */ 1253 case 3: /* cmovbe/cmovna */
1254 d |= (_eflags & (EFLG_CF | EFLG_ZF)) ? Mov : 0; 1254 no_wb = (_eflags & (EFLG_CF | EFLG_ZF)) ? 0 : 1;
1255 break; 1255 break;
1256 case 4: /* cmovs */ 1256 case 4: /* cmovs */
1257 d |= (_eflags & EFLG_SF) ? Mov : 0; 1257 no_wb = (_eflags & EFLG_SF) ? 0 : 1;
1258 break; 1258 break;
1259 case 5: /* cmovp/cmovpe */ 1259 case 5: /* cmovp/cmovpe */
1260 d |= (_eflags & EFLG_PF) ? Mov : 0; 1260 no_wb = (_eflags & EFLG_PF) ? 0 : 1;
1261 break; 1261 break;
1262 case 7: /* cmovle/cmovng */ 1262 case 7: /* cmovle/cmovng */
1263 d |= (_eflags & EFLG_ZF) ? Mov : 0; 1263 no_wb = (_eflags & EFLG_ZF) ? 0 : 1;
1264 /* fall through */ 1264 /* fall through */
1265 case 6: /* cmovl/cmovnge */ 1265 case 6: /* cmovl/cmovnge */
1266 d |= (!(_eflags & EFLG_SF) != 1266 no_wb &= (!(_eflags & EFLG_SF) !=
1267 !(_eflags & EFLG_OF)) ? Mov : 0; 1267 !(_eflags & EFLG_OF)) ? 0 : 1;
1268 break; 1268 break;
1269 } 1269 }
1270 /* Odd cmov opcodes (lsb == 1) have inverted sense. */ 1270 /* Odd cmov opcodes (lsb == 1) have inverted sense. */
1271 d ^= (b & 1) ? Mov : 0; 1271 no_wb ^= b & 1;
1272 break; 1272 break;
1273 case 0xb0 ... 0xb1: /* cmpxchg */ 1273 case 0xb0 ... 0xb1: /* cmpxchg */
1274 /* 1274 /*