diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-04-27 15:51:17 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-04-27 15:51:17 +0200 |
| commit | b7ae6ebc27ee7a2511400740e800ef1c67816c03 (patch) | |
| tree | efdf342d5f6227722904365266f1f42b7503f661 /src | |
| parent | 9b904c622a321397fa0a4aed2c975c005d39ae46 (diff) | |
| download | box64-b7ae6ebc27ee7a2511400740e800ef1c67816c03.tar.gz box64-b7ae6ebc27ee7a2511400740e800ef1c67816c03.zip | |
[INTERP] More work on UD flags
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/modrm.h | 2 | ||||
| -rw-r--r-- | src/emu/x64run0f.c | 25 | ||||
| -rw-r--r-- | src/emu/x64run660f.c | 26 | ||||
| -rw-r--r-- | src/emu/x64run66f30f.c | 13 | ||||
| -rw-r--r-- | src/emu/x64runf30f.c | 12 |
5 files changed, 65 insertions, 13 deletions
diff --git a/src/emu/modrm.h b/src/emu/modrm.h index cd2c3636..bbad2e81 100644 --- a/src/emu/modrm.h +++ b/src/emu/modrm.h @@ -10,6 +10,8 @@ #define F64 *(uint64_t*)(addr+=8, addr-8) #define F64S *(int64_t*)(addr+=8, addr-8) #define PK(a) *(uint8_t*)(addr+a) +#define PARITY(x) (((emu->x64emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0) + #ifdef DYNAREC #define STEP CheckExec(emu, addr); if(step && !ACCESS_FLAG(F_TF)) return 0; #define STEP2 CheckExec(emu, addr); if(step && !ACCESS_FLAG(F_TF)) {R_RIP = addr; return 0;} diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c index 61fa11f4..bc182097 100644 --- a/src/emu/x64run0f.c +++ b/src/emu/x64run0f.c @@ -1590,26 +1590,32 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) nextop = F8; GETED(0); GETGD; + tmp8u = 0; if(rex.w) { tmp64u = ED->q[0]; if(tmp64u) { CLEAR_FLAG(F_ZF); - tmp8u = 0; while(!(tmp64u&(1LL<<tmp8u))) ++tmp8u; - GD->q[0] = tmp8u; } else { SET_FLAG(F_ZF); } + GD->q[0] = tmp8u; } else { tmp32u = ED->dword[0]; if(tmp32u) { CLEAR_FLAG(F_ZF); - tmp8u = 0; while(!(tmp32u&(1<<tmp8u))) ++tmp8u; - GD->q[0] = tmp8u; } else { SET_FLAG(F_ZF); } + GD->q[0] = tmp8u; + } + if(!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(PARITY(tmp8u), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_OF); } break; case 0xBD: /* BSR Ed,Gd */ @@ -1617,16 +1623,17 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) nextop = F8; GETED(0); GETGD; + tmp8u = 0; if(rex.w) { tmp64u = ED->q[0]; if(tmp64u) { CLEAR_FLAG(F_ZF); tmp8u = 63; while(!(tmp64u&(1LL<<tmp8u))) --tmp8u; - GD->q[0] = tmp8u; } else { SET_FLAG(F_ZF); } + GD->q[0] = tmp8u; } else { tmp32u = ED->dword[0]; if(tmp32u) { @@ -1636,8 +1643,16 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) GD->q[0] = tmp8u; } else { SET_FLAG(F_ZF); + GD->q[0] = tmp8u; } } + if(!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(PARITY(tmp8u), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_OF); + } break; case 0xBE: /* MOVSX Gd,Eb */ nextop = F8; diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c index 001a9aa4..8bb00f52 100644 --- a/src/emu/x64run660f.c +++ b/src/emu/x64run660f.c @@ -2115,26 +2115,32 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr) nextop = F8; GETEW(0); GETGW; + tmp8u = 0; if(rex.w) { tmp64u = EW->q[0]; if(tmp64u) { CLEAR_FLAG(F_ZF); - tmp8u = 0; while(!(tmp64u&(1LL<<tmp8u))) ++tmp8u; - GW->q[0] = tmp8u; } else { SET_FLAG(F_ZF); } + GW->q[0] = tmp8u; } else { tmp16u = EW->word[0]; if(tmp16u) { CLEAR_FLAG(F_ZF); - tmp8u = 0; while(!(tmp16u&(1<<tmp8u))) ++tmp8u; - GW->word[0] = tmp8u; } else { SET_FLAG(F_ZF); } + GW->word[0] = tmp8u; + } + if(!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(PARITY(tmp8u), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_OF); } break; case 0xBD: /* BSR Ew,Gw */ @@ -2142,26 +2148,34 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr) nextop = F8; GETEW(0); GETGW; + tmp8u = 0; if(rex.w) { tmp64u = EW->q[0]; if(tmp64u) { CLEAR_FLAG(F_ZF); tmp8u = 63; while(!(tmp64u&(1LL<<tmp8u))) --tmp8u; - GW->q[0] = tmp8u; } else { SET_FLAG(F_ZF); } + GW->q[0] = tmp8u; } else { tmp16u = EW->word[0]; if(tmp16u) { CLEAR_FLAG(F_ZF); tmp8u = 15; while(!(tmp16u&(1<<tmp8u))) --tmp8u; - GW->word[0] = tmp8u; } else { SET_FLAG(F_ZF); } + GW->word[0] = tmp8u; + } + if(!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(PARITY(tmp8u), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_OF); } break; case 0xBE: /* MOVSX Gw,Eb */ diff --git a/src/emu/x64run66f30f.c b/src/emu/x64run66f30f.c index 9e56e94d..00cd6cca 100644 --- a/src/emu/x64run66f30f.c +++ b/src/emu/x64run66f30f.c @@ -87,6 +87,11 @@ uintptr_t Run66F30F(x64emu_t *emu, rex_t rex, uintptr_t addr) GD->word[0] = 16; } } + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + if(!BOX64ENV(cputype)) + CLEAR_FLAG(F_OF); break; case 0xBD: /* LZCNT Ed,Gd */ CHECK_FLAGS(emu); @@ -98,13 +103,19 @@ uintptr_t Run66F30F(x64emu_t *emu, rex_t rex, uintptr_t addr) tmp8u = (tmp64u)?__builtin_clzl(tmp64u):64; CONDITIONAL_SET_FLAG(tmp8u==0, F_ZF); CONDITIONAL_SET_FLAG(tmp8u==64, F_CF); + GD->q[0] = tmp8u; } else { tmp32u = EW->word[0]; tmp8u = (tmp32u)?__builtin_clz(tmp32u<<16):16; CONDITIONAL_SET_FLAG(tmp8u==0, F_ZF); CONDITIONAL_SET_FLAG(tmp8u==16, F_CF); + GD->word[0] = tmp8u; } - GD->q[0] = tmp8u; + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + if(!BOX64ENV(cputype)) + CLEAR_FLAG(F_OF); break; case 0xB8: /* POPCNT Gd,Ed */ diff --git a/src/emu/x64runf30f.c b/src/emu/x64runf30f.c index 38ef2ad4..ea31cf01 100644 --- a/src/emu/x64runf30f.c +++ b/src/emu/x64runf30f.c @@ -388,7 +388,12 @@ uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr) GD->q[0] = 32; } } - break; + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + if(!BOX64ENV(cputype)) + CLEAR_FLAG(F_OF); + break; case 0xBD: /* LZCNT Ed,Gd */ CHECK_FLAGS(emu); nextop = F8; @@ -406,6 +411,11 @@ uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr) CONDITIONAL_SET_FLAG(tmp8u==32, F_CF); } GD->q[0] = tmp8u; + CLEAR_FLAG(F_PF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + if(!BOX64ENV(cputype)) + CLEAR_FLAG(F_OF); break; case 0xC2: /* CMPSS Gx, Ex, Ib */ |