diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-03-08 13:54:34 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-03-08 13:54:34 +0100 |
| commit | 5ed3ef918dcdab1619f087f1e0747d73c8d19ded (patch) | |
| tree | ad0b4def683ee5738a948475f6952d9564856803 | |
| parent | c0f78342e1571306f5d30087ccd8f0b289ea949e (diff) | |
| download | box64-5ed3ef918dcdab1619f087f1e0747d73c8d19ded.tar.gz box64-5ed3ef918dcdab1619f087f1e0747d73c8d19ded.zip | |
[INTERPRETER] Added 67 64 8F opcodes, and fixed 67 64 89/8B opcodes
| -rw-r--r-- | src/emu/modrm.h | 2 | ||||
| -rw-r--r-- | src/emu/x64run6764_32.c | 22 | ||||
| -rw-r--r-- | src/emu/x64run_private.c | 62 | ||||
| -rw-r--r-- | src/emu/x64run_private.h | 2 |
4 files changed, 80 insertions, 8 deletions
diff --git a/src/emu/modrm.h b/src/emu/modrm.h index 72c17f0a..3e49b36b 100644 --- a/src/emu/modrm.h +++ b/src/emu/modrm.h @@ -26,6 +26,7 @@ #define GETE8xw(D) oped=TestEd8xw(test, rex.w, &addr, rex, nextop, D) #define GETED32(D) oped=TestEd32O(test, &addr, rex, nextop, D, 0) #define GETED_OFFS(D, O) oped=TestEdO(test, &addr, rex, nextop, D, O) +#define GETED_OFFS_16(O) oped=TestEd16off(test, &addr, rex, nextop, O) #define GETGD opgd=GetGd(test->emu, &addr, rex, nextop) #define GETEB(D) oped=TestEb(test, &addr, rex, nextop, D) #define GETEB32(D) oped=TestEb32O(test, &addr, rex, nextop, D, 0) @@ -51,6 +52,7 @@ #define GETE8xw(D) GETED(D) #define GETED32(D) oped=GetEd32O(emu, &addr, rex, nextop, D, 0) #define GETED_OFFS(D, O) oped=GetEdO(emu, &addr, rex, nextop, D, O) +#define GETED_OFFS_16(O) oped=GetEd16off(emu, &addr, rex, nextop, O) #define GETGD opgd=GetGd(emu, &addr, rex, nextop) #define GETEB(D) oped=GetEb(emu, &addr, rex, nextop, D) #define GETEB32(D) oped=GetEb32O(emu, &addr, rex, nextop, D, 0) diff --git a/src/emu/x64run6764_32.c b/src/emu/x64run6764_32.c index 832a970f..c17481cc 100644 --- a/src/emu/x64run6764_32.c +++ b/src/emu/x64run6764_32.c @@ -54,18 +54,24 @@ uintptr_t Run6764_32(x64emu_t *emu, rex_t rex, int rep, int seg, uintptr_t addr) switch(opcode) { - case 0x89: /* MOV FS:Ew, Gw */ + case 0x89: /* MOV FS:Ed, Gd */ nextop = F8; - GETEW_OFFS_16(tlsdata); - GETGW; - EW->word[0] = GW->word[0]; + GETED_OFFS_16(tlsdata); + GETGD; + ED->dword[0] = GD->dword[0]; break; - case 0x8B: /* MOV Gw, FS:Ew */ + case 0x8B: /* MOV Gd, FS:Ed */ nextop = F8; - GETEW_OFFS_16(tlsdata); - GETGW; - GW->word[0] = EW->word[0]; + GETED_OFFS_16(tlsdata); + GETGD; + GD->dword[0] = ED->dword[0]; + break; + + case 0x8F: /* POP FS:Ed */ + nextop = F8; + GETED_OFFS_16(tlsdata); + ED->dword[0] = Pop32(emu); break; case 0xA1: /* MOV EAX, FS:Od */ diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index 5b41cc24..cbeface8 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -1780,6 +1780,35 @@ reg64_t* GetEw16off(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uintpt } } +reg64_t* GetEd16off(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset) +{ + (void)rex; + + uint32_t m = v&0xC7; // filter Ed + if(m>=0xC0) { + return &emu->regs[(m&0x07)]; + } else { + uint32_t base = 0; + switch(m&7) { + case 0: base = R_BX+R_SI; break; + case 1: base = R_BX+R_DI; break; + case 2: base = R_BP+R_SI; break; + 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 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 3 is C0..C7, already dealt with + } + return (reg64_t*)(base+offset); + } +} + reg64_t* TestEw16off(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset) { (void)rex; @@ -1813,6 +1842,39 @@ reg64_t* TestEw16off(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uin } } +reg64_t* TestEd16off(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset) +{ + (void)rex; + x64emu_t* emu = test->emu; + + uint32_t m = v&0xC7; // filter Ed + if(m>=0xC0) { + return &emu->regs[(m&0x07)]; + } else { + uint32_t base = 0; + switch(m&7) { + case 0: base = R_BX+R_SI; break; + case 1: base = R_BX+R_DI; break; + case 2: base = R_BP+R_SI; break; + 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 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 3 is C0..C7, already dealt with + } + test->memsize = 4; + *(uint32_t*)test->mem = *(uint32_t*)(base+offset); + test->memaddr = (uintptr_t)(base+offset); + return (reg64_t*)test->mem; + } +} + mmx87_regs_t* GetEm(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta) { uint8_t m = v&0xC7; // filter Ed diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index b331a748..01cf3e4d 100644 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -104,7 +104,9 @@ reg64_t* TestEw(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t reg64_t* GetEw16(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v); reg64_t* TestEw16(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v); reg64_t* GetEw16off(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset); +reg64_t* GetEd16off(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset); reg64_t* TestEw16off(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset); +reg64_t* TestEd16off(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset); mmx87_regs_t* GetEm(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta); mmx87_regs_t* TestEm(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta); sse_regs_t* GetEx(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta); |