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/helper.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/helper.c')
-rw-r--r-- | target-i386/helper.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/target-i386/helper.c b/target-i386/helper.c index 0317f9ca1d..4562a16a83 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1879,8 +1879,8 @@ void helper_cmpxchg8b(target_ulong a0) eflags = cc_table[CC_OP].compute_all(); d = ldq(a0); - if (d == (((uint64_t)EDX << 32) | EAX)) { - stq(a0, ((uint64_t)ECX << 32) | EBX); + if (d == (((uint64_t)EDX << 32) | (uint32_t)EAX)) { + stq(a0, ((uint64_t)ECX << 32) | (uint32_t)EBX); eflags |= CC_Z; } else { EDX = (uint32_t)(d >> 32); @@ -1890,6 +1890,28 @@ void helper_cmpxchg8b(target_ulong a0) CC_SRC = eflags; } +#ifdef TARGET_X86_64 +void helper_cmpxchg16b(target_ulong a0) +{ + uint64_t d0, d1; + int eflags; + + eflags = cc_table[CC_OP].compute_all(); + d0 = ldq(a0); + d1 = ldq(a0 + 8); + if (d0 == EAX && d1 == EDX) { + stq(a0, EBX); + stq(a0 + 8, ECX); + eflags |= CC_Z; + } else { + EDX = d1; + EAX = d0; + eflags &= ~CC_Z; + } + CC_SRC = eflags; +} +#endif + void helper_single_step(void) { env->dr[6] |= 0x4000; |