diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64run66f0.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/emu/x64run66f0.c b/src/emu/x64run66f0.c index da67fcbe..951edccd 100644 --- a/src/emu/x64run66f0.c +++ b/src/emu/x64run66f0.c @@ -32,9 +32,11 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) { uint8_t opcode; uint8_t nextop; + uint8_t tmp8u, tmp8u2; int16_t tmp16s; uint16_t tmp16u, tmp16u2; int32_t tmp32s; + uint32_t tmp32u, tmp32u2; int64_t tmp64s; uint64_t tmp64u, tmp64u2; reg64_t *oped, *opgd; @@ -89,6 +91,57 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr) #endif break; + case 0xBA: /* BTS Ew, Ib */ + CHECK_FLAGS(emu); + nextop = F8; + GETEW(0); + tmp8u = F8; +#if defined(DYNAREC) && !defined(TEST_INTERPRETER) + tmp8u &= 15; + if ((uintptr_t)ED & 1) { + do { + tmp32u = native_lock_read_b(ED + (tmp8u >> 3)); + if (tmp32u & (1 << (tmp8u & 7))) { + SET_FLAG(F_CF); + tmp32s = 0; + } else { + tmp32u ^= (1 << (tmp8u & 7)); + tmp32s = native_lock_write_b(ED + (tmp8u >> 3), tmp32u); + CLEAR_FLAG(F_CF); + } + } while (tmp32s); + } else { + do { + tmp32u = native_lock_read_h(ED); + if (tmp32u & (1 << tmp8u)) { + SET_FLAG(F_CF); + tmp32s = 0; + } else { + tmp32u ^= (1 << tmp8u); + tmp32s = native_lock_write_h(ED, tmp32u); + CLEAR_FLAG(F_CF); + } + } while (tmp32s); + } +#else + pthread_mutex_lock(&my_context->mutex_lock); + tmp8u &= 15; + if (ED->dword[0] & (1 << tmp8u)) { + SET_FLAG(F_CF); + } else { + ED->dword[0] ^= (1 << tmp8u); + CLEAR_FLAG(F_CF); + } + pthread_mutex_unlock(&my_context->mutex_lock); +#endif + if (BOX64ENV(dynarec_test)) { + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_PF); + } + break; + case 0xC1: /* XADD Gw,Ew */ nextop = F8; GETEW(0); |