diff options
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; |