aboutsummaryrefslogtreecommitdiffstats
path: root/target-i386/translate.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-22 09:52:38 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-22 09:52:38 +0000
commit1b9d9ebb8a2efb780365214313625b7d717bca83 (patch)
treeac5508a5ad4d660b229947ce7b7edabc0676f4bc /target-i386/translate.c
parent1130328ecb4a247d00fa820768631d93facc832c (diff)
cmpxchg8b fix - added cmpxchg16b
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4522 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386/translate.c')
-rw-r--r--target-i386/translate.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 85b3d6db4..6e5593013 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -4333,11 +4333,26 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
mod = (modrm >> 6) & 3;
if ((mod == 3) || ((modrm & 0x38) != 0x8))
goto illegal_op;
- gen_jmp_im(pc_start - s->cs_base);
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- tcg_gen_helper_0_1(helper_cmpxchg8b, cpu_A0);
+#ifdef TARGET_X86_64
+ if (dflag == 2) {
+ if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
+ goto illegal_op;
+ gen_jmp_im(pc_start - s->cs_base);
+ if (s->cc_op != CC_OP_DYNAMIC)
+ gen_op_set_cc_op(s->cc_op);
+ gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
+ tcg_gen_helper_0_1(helper_cmpxchg16b, cpu_A0);
+ } else
+#endif
+ {
+ if (!(s->cpuid_features & CPUID_CX8))
+ goto illegal_op;
+ gen_jmp_im(pc_start - s->cs_base);
+ if (s->cc_op != CC_OP_DYNAMIC)
+ gen_op_set_cc_op(s->cc_op);
+ gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
+ tcg_gen_helper_0_1(helper_cmpxchg8b, cpu_A0);
+ }
s->cc_op = CC_OP_EFLAGS;
break;