aboutsummaryrefslogtreecommitdiff
path: root/target-i386/helper.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/helper.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/helper.c')
-rw-r--r--target-i386/helper.c26
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;