diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-07-09 11:48:57 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-07-09 11:48:57 +0200 |
| commit | c1e67c31bc55afeaa4ec38bfdbb6f6a4f8e8b424 (patch) | |
| tree | d1bbf78baad25d4834d82b2f4b82d73e647ee13e | |
| parent | 6eccdc1baf3d0d580afa0f66b632aa05453d3c69 (diff) | |
| download | box64-c1e67c31bc55afeaa4ec38bfdbb6f6a4f8e8b424.tar.gz box64-c1e67c31bc55afeaa4ec38bfdbb6f6a4f8e8b424.zip | |
Added F0 0F BA opcodes (for #21)
| -rw-r--r-- | src/emu/x64runf0.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c index 4c4d504d..f3c0fb10 100644 --- a/src/emu/x64runf0.c +++ b/src/emu/x64runf0.c @@ -405,6 +405,187 @@ int RunF0(x64emu_t *emu, rex_t rex) #endif break; + case 0xBA: + nextop = F8; + switch((nextop>>3)&7) { + case 4: /* BT Ed,Ib */ + CHECK_FLAGS(emu); + GETED(1); + tmp8u = F8; + if(rex.w) { + tmp8u&=63; + if(ED->q[0] & (1LL<<tmp8u)) + SET_FLAG(F_CF); + else + CLEAR_FLAG(F_CF); + } else { + tmp8u&=31; + if(ED->dword[0] & (1<<tmp8u)) + SET_FLAG(F_CF); + else + CLEAR_FLAG(F_CF); + } + break; + case 5: /* BTS Ed, Ib */ + CHECK_FLAGS(emu); + GETED(1); + tmp8u = F8; +#ifdef DYNAREC + if(rex.w) { + tmp8u&=63; + do { + tmp64u = arm64_lock_read_dd(ED); + if(tmp64u & (1LL<<tmp8u)) { + SET_FLAG(F_CF); + tmp32s = 0; + } else { + tmp64u ^= (1LL<<tmp8u); + tmp32s = arm64_lock_write_dd(ED, tmp64u); + CLEAR_FLAG(F_CF); + } + } while(tmp32s); + } else { + tmp8u&=31; + do { + tmp32u = arm64_lock_read_d(ED); + if(tmp32u & (1<<tmp8u)) { + SET_FLAG(F_CF); + tmp32s = 0; + } else { + tmp32u ^= (1<<tmp8u); + tmp32s = arm64_lock_write_d(ED, tmp32u); + CLEAR_FLAG(F_CF); + } + } while(tmp32s); + } +#else + pthread_mutex_lock(&emu->context->mutex_lock); + if(rex.w) { + tmp8u&=63; + if(ED->q[0] & (1LL<<tmp8u)) { + SET_FLAG(F_CF); + } else { + ED->q[0] ^= (1LL<<tmp8u); + CLEAR_FLAG(F_CF); + } + } else { + tmp8u&=31; + if(ED->dword[0] & (1<<tmp8u)) { + SET_FLAG(F_CF); + } else { + ED->dword[0] ^= (1<<tmp8u); + CLEAR_FLAG(F_CF); + } + } + pthread_mutex_unlock(&emu->context->mutex_lock); +#endif + break; + case 6: /* BTR Ed, Ib */ + CHECK_FLAGS(emu); + GETED(1); + tmp8u = F8; +#ifdef DYNAREC + if(rex.w) { + do { + tmp8u&=63; + tmp64u = arm64_lock_read_dd(ED); + if(tmp64u & (1LL<<tmp8u)) { + SET_FLAG(F_CF); + tmp64u ^= (1LL<<tmp8u); + tmp32s = arm64_lock_write_dd(ED, tmp64u); + } else { + tmp32s = 0; + CLEAR_FLAG(F_CF); + } + } while(tmp32s); + } else { + tmp8u&=31; + do { + tmp32u = arm64_lock_read_d(ED); + if(tmp32u & (1<<tmp8u)) { + SET_FLAG(F_CF); + tmp32u ^= (1<<tmp8u); + tmp32s = arm64_lock_write_d(ED, tmp32u); + } else { + CLEAR_FLAG(F_CF); + tmp32s = 0; + } + } while(tmp32s); + } +#else + pthread_mutex_lock(&emu->context->mutex_lock); + if(rex.w) { + tmp8u&=63; + if(ED->q[0] & (1LL<<tmp8u)) { + SET_FLAG(F_CF); + ED->q[0] ^= (1LL<<tmp8u); + } else + CLEAR_FLAG(F_CF); + } else { + tmp8u&=31; + if(ED->dword[0] & (1<<tmp8u)) { + SET_FLAG(F_CF); + ED->dword[0] ^= (1<<tmp8u); + } else + CLEAR_FLAG(F_CF); + } + pthread_mutex_unlock(&emu->context->mutex_lock); +#endif + break; + case 7: /* BTC Ed, Ib */ + CHECK_FLAGS(emu); + GETED(1); + tmp8u = F8; +#ifdef DYNAREC + if(rex.w) { + tmp8u&=63; + do { + tmp64u = arm64_lock_read_dd(ED); + if(tmp64u & (1LL<<tmp8u)) + SET_FLAG(F_CF); + else + CLEAR_FLAG(F_CF); + tmp64u ^= (1LL<<tmp8u); + tmp32s = arm64_lock_write_dd(ED, tmp64u); + } while(tmp32s); + } else { + tmp8u&=31; + do { + tmp32u = arm64_lock_read_d(ED); + if(tmp32u & (1<<tmp8u)) + SET_FLAG(F_CF); + else + CLEAR_FLAG(F_CF); + tmp32u ^= (1<<tmp8u); + tmp32s = arm64_lock_write_d(ED, tmp32u); + } while(tmp32s); + } +#else + pthread_mutex_lock(&emu->context->mutex_lock); + if(rex.w) { + tmp8u&=63; + if(ED->q[0] & (1LL<<tmp8u)) + SET_FLAG(F_CF); + else + CLEAR_FLAG(F_CF); + ED->q[0] ^= (1LL<<tmp8u); + } else { + tmp8u&=31; + if(ED->dword[0] & (1<<tmp8u)) + SET_FLAG(F_CF); + else + CLEAR_FLAG(F_CF); + ED->dword[0] ^= (1<<tmp8u); + } + pthread_mutex_unlock(&emu->context->mutex_lock); +#endif + break; + + default: + return 1; + } + break; + case 0xC1: /* XADD Gd,Ed */ nextop = F8; GETED(0); |