diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-09-01 15:03:29 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-09-01 15:03:29 +0200 |
| commit | cb3cfa991f5cf20ce7f781cc9b824541b0549fdc (patch) | |
| tree | ac8d1760b6c8eae03ec9c4af49a0883d0c9765ff /src | |
| parent | 4b6766c84bfe4a9101e59696527b37d594fbe3f5 (diff) | |
| download | box64-cb3cfa991f5cf20ce7f781cc9b824541b0549fdc.tar.gz box64-cb3cfa991f5cf20ce7f781cc9b824541b0549fdc.zip | |
[INTERP] Fixed and improved 67 prefixed 32bits opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64run.c | 33 | ||||
| -rw-r--r-- | src/emu/x64run_private.c | 26 |
2 files changed, 28 insertions, 31 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c index fc9e8270..34bd0368 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -864,15 +864,25 @@ x64emurun: R_AH = (uint8_t)emu->eflags.x64; break; case 0xA0: /* MOV AL,Ob */ - if(rex.is32bits) + if(rex.is32bits && rex.is67) + R_AL = *(uint8_t*)(uintptr_t)(ptr_t)(rex.offset+F16S); + else if(rex.is32bits || rex.is67) R_AL = *(uint8_t*)(uintptr_t)(ptr_t)(F32+rex.offset); else R_AL = *(uint8_t*)(F64+rex.offset); break; case 0xA1: /* MOV EAX,Od */ - if(rex.is32bits) - R_EAX = *(int32_t*)(uintptr_t)(ptr_t)(F32+rex.offset); - else { + if(rex.is32bits && rex.is67) + R_EAX = *(uint32_t*)(uintptr_t)(ptr_t)(rex.offset+F16S); + else if(rex.is32bits || rex.is67) { + if(rex.w) + R_RAX = *(int64_t*)(uintptr_t)(ptr_t)(F32+rex.offset); + else { + R_EAX = *(int32_t*)(uintptr_t)(ptr_t)(F32+rex.offset); + if(!rex.is32bits) + R_RAX = R_EAX; + } + } else { if(rex.w) R_RAX = *(uint64_t*)(F64+rex.offset); else @@ -880,15 +890,22 @@ x64emurun: } break; case 0xA2: /* MOV Ob,AL */ - if(rex.is32bits) + if(rex.is32bits && rex.is67) + *(uint8_t*)(uintptr_t)(ptr_t)(rex.offset+F16S) = R_AL; + else if(rex.is32bits || rex.is67) *(uint8_t*)(uintptr_t)(ptr_t)(F32+rex.offset) = R_AL; else *(uint8_t*)(F64+rex.offset) = R_AL; break; case 0xA3: /* MOV Od,EAX */ - if(rex.is32bits) - *(uint32_t*)(uintptr_t)(ptr_t)(F32+rex.offset) = R_EAX; - else { + if(rex.is32bits && rex.is67) + *(uint32_t*)(uintptr_t)(ptr_t)(rex.offset+F16S) = R_EAX; + else if(rex.is32bits || rex.is67) { + if(rex.w) + *(uint64_t*)(uintptr_t)(ptr_t)(F32+rex.offset) = R_RAX; + else + *(uint32_t*)(uintptr_t)(ptr_t)(F32+rex.offset) = R_EAX; + } else { if(rex.w) *(uint64_t*)(F64+rex.offset) = R_RAX; else diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index be268d4d..9fcd0b46 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -233,7 +233,7 @@ reg64_t* GetECommon_32(x64emu_t* emu, uintptr_t* addr, uint8_t m, uint32_t base) return (reg64_t*)(uintptr_t)base; } } -reg64_t* GetECommon_16(x64emu_t *emu, uintptr_t* addr, uint8_t m, uint32_t base) +reg64_t* GetECommon_16(x64emu_t *emu, uintptr_t* addr, uint8_t m, uint64_t base) { switch(m&7) { case 0: base+= R_BX+R_SI; break; @@ -242,13 +242,13 @@ reg64_t* GetECommon_16(x64emu_t *emu, uintptr_t* addr, uint8_t m, uint32_t base) case 3: base+= R_BP+R_DI; break; case 4: base+= R_SI; break; case 5: base+= R_DI; break; - case 6: base+= R_BP; break; + case 6: if((m>>6)&3) base += R_BP; else base += F16S(addr); break; case 7: base+= R_BX; break; } switch((m>>6)&3) { - case 0: if((m&7)==6) base= F16S(addr); break; case 1: base += F8S(addr); break; case 2: base += F16S(addr); break; + // case 0 is already dealt with on case 6 // case 3 is C0..C7, already dealt with } return (reg64_t*)(uintptr_t)base; @@ -344,11 +344,6 @@ reg64_t* GetECommon(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_ reg64_t* GetEb(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta) { - if(rex.is67 && rex.is32bits) { - printf_log(LOG_NONE, "Need 32bits 67 prefix GetEb\n"); - emu->quit = 1; - return NULL; - } uint8_t m = v&0xC7; // filter Eb if(m>=0xC0) { if(rex.rex) { @@ -362,11 +357,6 @@ reg64_t* GetEb(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t del reg64_t* TestEb(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta) { - if(rex.is67 && rex.is32bits) { - printf_log(LOG_NONE, "Need 32bits 67 prefix TestEb\n"); - test->emu->quit = 1; - return NULL; - } uint8_t m = v&0xC7; // filter Eb if(m>=0xC0) { if(rex.rex) { @@ -386,11 +376,6 @@ reg64_t* TestEb(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t reg64_t* GetEd(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta) { - if(rex.is67 && rex.is32bits) { - printf_log(LOG_NONE, "Need 32bits 67 prefix GetEd\n"); - emu->quit = 1; - return NULL; - } uint8_t m = v&0xC7; // filter Ed if(m>=0xC0) { return &emu->regs[(m&0x07)+(rex.b<<3)]; @@ -399,11 +384,6 @@ reg64_t* GetEd(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t del reg64_t* TestEd(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta) { - if(rex.is67 && rex.is32bits) { - printf_log(LOG_NONE, "Need 32bits 67 prefix TestEd\n"); - test->emu->quit = 1; - return NULL; - } uint8_t m = v&0xC7; // filter Ed if(m>=0xC0) { return &test->emu->regs[(m&0x07)+(rex.b<<3)]; |