diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-22 09:52:38 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-22 09:52:38 +0000 |
commit | 1b9d9ebb8a2efb780365214313625b7d717bca83 (patch) | |
tree | ac5508a5ad4d660b229947ce7b7edabc0676f4bc /target-i386/translate.c | |
parent | 1130328ecb4a247d00fa820768631d93facc832c (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.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/target-i386/translate.c b/target-i386/translate.c index 85b3d6db4a..6e55930131 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, ®_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, ®_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, ®_addr, &offset_addr); + tcg_gen_helper_0_1(helper_cmpxchg8b, cpu_A0); + } s->cc_op = CC_OP_EFLAGS; break; |