diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-04-08 15:32:35 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-04-08 15:32:35 +0200 |
| commit | b90991f039f9d7a480f19fbf518f9365e035678b (patch) | |
| tree | 1cb2f3ff37f76e8d3ab67426ffc98dadb5652d2b /src | |
| parent | 8d49ae5c68f5d5c68bb0ef9e5f87d9424881f07a (diff) | |
| download | box64-b90991f039f9d7a480f19fbf518f9365e035678b.tar.gz box64-b90991f039f9d7a480f19fbf518f9365e035678b.zip | |
Added F0 0F AB/B3 opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64runf0.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c index 2dac7129..01394618 100644 --- a/src/emu/x64runf0.c +++ b/src/emu/x64runf0.c @@ -168,6 +168,86 @@ int RunF0(x64emu_t *emu, rex_t rex) opcode = F8; switch (opcode) { + case 0xAB: /* BTS Ed,Gd */ + CHECK_FLAGS(emu); + nextop = F8; + GETED(0); + GETGD; + tmp8u = GD->byte[0]; + if(!MODREG) + { + ED=(reg64_t*)(((uint32_t*)(ED))+(tmp8u>>5)); + } +#ifdef DYNAREC + if(rex.w) { + tmp8u&=63; + if(MODREG) { + if(ED->q[0] & (1LL<<tmp8u)) + SET_FLAG(F_CF); + else { + ED->q[0] |= (1LL<<tmp8u); + CLEAR_FLAG(F_CF); + } + } else + do { + tmp64u = arm64_lock_read_dd(ED); + if(tmp64u & (1LL<<tmp8u)) { + SET_FLAG(F_CF); + tmp32s = 0; + } else { + tmp64u |= (1LL<<tmp8u); + CLEAR_FLAG(F_CF); + tmp32s = arm64_lock_write_d(ED, tmp64u); + } + } while(tmp32s); + } else { + tmp8u&=31; + if(MODREG) { + if(ED->dword[0] & (1<<tmp8u)) + SET_FLAG(F_CF); + else { + ED->dword[0] |= (1<<tmp8u); + CLEAR_FLAG(F_CF); + } + ED->dword[1] = 0; + } else + do { + tmp32u = arm64_lock_read_d(ED); + if(tmp32u & (1<<tmp8u)) { + SET_FLAG(F_CF); + tmp32s = 0; + } else { + tmp32u |= (1<<tmp8u); + CLEAR_FLAG(F_CF); + 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 { + 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); + } + if(MODREG) + ED->dword[1] = 0; + } + pthread_mutex_unlock(&emu->context->mutex_lock); +#endif + break; + case 0xB0: /* CMPXCHG Eb,Gb */ CHECK_FLAGS(emu); nextop = F8; @@ -243,6 +323,63 @@ int RunF0(x64emu_t *emu, rex_t rex) #endif break; + case 0xB3: /* BTR Ed,Gd */ + CHECK_FLAGS(emu); + nextop = F8; + GETED(0); + GETGD; + tmp8u = GD->byte[0]; + if(!MODREG) + { + ED=(reg64_t*)(((uint32_t*)(ED))+(tmp8u>>5)); + } + tmp8u&=rex.w?63:31; +#ifdef DYNAREC + if(rex.w) + do { + 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 { + CLEAR_FLAG(F_CF); + tmp32s = 0; + } + } while(tmp32s); + else + 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) { + if(ED->q[0] & (1<<tmp8u)) { + SET_FLAG(F_CF); + ED->q[0] ^= (1<<tmp8u); + } else + CLEAR_FLAG(F_CF); + } else { + if(ED->dword[0] & (1<<tmp8u)) { + SET_FLAG(F_CF); + ED->dword[0] ^= (1<<tmp8u); + } else + CLEAR_FLAG(F_CF); + if(MODREG) + ED->dword[1] = 0; + } + pthread_mutex_unlock(&emu->context->mutex_lock); +#endif + break; + case 0xC1: /* XADD Gd,Ed */ nextop = F8; GETED(0); |