From 56bd83f6fbcf46699e28eb4164360f6fbd64a1ed Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 7 Nov 2024 15:52:10 +0100 Subject: Added 64/65 D8..D9 opcodes --- src/emu/modrm.h | 5 +++++ src/emu/x64run.c | 8 ++++---- src/emu/x64run64.c | 15 ++++++++++++++ src/emu/x64run_private.c | 26 ++++++++++++++++++++++++ src/emu/x64run_private.h | 10 ++++++---- src/emu/x64rund8.c | 52 ++++++++++++++++++++++++++++++++++++++---------- src/emu/x64rund9.c | 46 +++++++++++++++++++++++++++++++++--------- 7 files changed, 135 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/emu/modrm.h b/src/emu/modrm.h index 6b02e74a..fcfc7dc6 100644 --- a/src/emu/modrm.h +++ b/src/emu/modrm.h @@ -23,7 +23,9 @@ #ifdef TEST_INTERPRETER #define GETED(D) oped=TestEd(test, &addr, rex, nextop, D) #define GETE4(D) oped=TestEd4(test, &addr, rex, nextop, D) +#define GETE4_OFFS(D, O) oped=TestEd4O(test, &addr, rex, nextop, D, O) #define GETE8(D) oped=TestEd8(test, &addr, rex, nextop, D) +#define GETE8_OFFS(D, O) oped=TestEd8O(test, &addr, rex, nextop, D, O) #define GETET(D) oped=TestEdt(test, &addr, rex, nextop, D) #define GETE8xw(D) oped=TestEd8xw(test, rex.w, &addr, rex, nextop, D) #define GETED32(D) oped=TestEd32O(test, &addr, rex, nextop, D, 0) @@ -56,7 +58,9 @@ #else #define GETED(D) oped=GetEd(emu, &addr, rex, nextop, D) #define GETE4(D) GETED(D) +#define GETE4_OFFS(D, O) GETED_OFFS(D, O) #define GETE8(D) GETED(D) +#define GETE8_OFFS(D, O) GETED_OFFS(D, O) #define GETET(D) GETED(D) #define GETE8xw(D) GETED(D) #define GETED32(D) oped=GetEd32O(emu, &addr, rex, nextop, D, 0) @@ -107,6 +111,7 @@ #define GETEA(D) GetEA(emu, &addr, rex, nextop, D) #define GETEA32(D) GetEA32(emu, &addr, rex, nextop, D) #define _GETED(D) oped=GetEd(emu, &addr, rex, nextop, D) +#define _GETED_OFFS(D, O) oped=GetEdO(emu, &addr, rex, nextop, D, O) #define _GETED32(D) oped=GetEd32O(emu, &addr, rex, nextop, D, 0) #define _GETEB(D) oped=GetEb(emu, &addr, rex, nextop, D) #define _GETEX(D) opex=GetEx(emu, &addr, rex, nextop, D) diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 5859ec34..c5c6d620 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -1658,10 +1658,10 @@ x64emurun: break; case 0xD8: /* x87 opcodes */ #ifdef TEST_INTERPRETER - if(!(addr = TestD8(test, rex, addr))) + if(!(addr = TestD8(test, rex, addr, 0))) unimp = 1; #else - if(!(addr = RunD8(emu, rex, addr))) { + if(!(addr = RunD8(emu, rex, addr, 0))) { unimp = 1; goto fini; } @@ -1673,10 +1673,10 @@ x64emurun: break; case 0xD9: /* x87 opcodes */ #ifdef TEST_INTERPRETER - if(!(addr = TestD9(test, rex, addr))) + if(!(addr = TestD9(test, rex, addr, 0))) unimp = 1; #else - if(!(addr = RunD9(emu, rex, addr))) { + if(!(addr = RunD9(emu, rex, addr, 0))) { unimp = 1; goto fini; } diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c index c3960e83..605e464d 100644 --- a/src/emu/x64run64.c +++ b/src/emu/x64run64.c @@ -756,6 +756,21 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr) } break; + case 0xD8: /* x87 opcodes */ + #ifdef TEST_INTERPRETER + return TestD8(test, rex, addr, tlsdata); + #else + return RunD8(emu, rex, addr, tlsdata); + #endif + break; + case 0xD9: /* x87 opcodes */ + #ifdef TEST_INTERPRETER + return TestD9(test, rex, addr, tlsdata); + #else + return RunD9(emu, rex, addr, tlsdata); + #endif + break; + case 0xEB: /* JMP Ib */ tmp32s = F8S; // jump is relative addr += tmp32s; diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index dca534a8..58331a1d 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -1614,6 +1614,19 @@ reg64_t* TestEd4(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t return (reg64_t*)test->mem; } } +reg64_t* TestEd4O(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset) +{ + uint8_t m = v&0xC7; // filter Ed + if(m>=0xC0) { + return &test->emu->regs[(m&0x07)+(rex.b<<3)]; + } else { + reg64_t* ret = GetECommonO(test->emu, addr, rex, m, delta, offset); + test->memsize = 4; + test->memaddr = (uintptr_t)ret; + *(uint32_t*)test->mem = ret->dword[0]; + return (reg64_t*)test->mem; + } +} reg64_t* TestEd8(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta) { uint8_t m = v&0xC7; // filter Ed @@ -1627,6 +1640,19 @@ reg64_t* TestEd8(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t return (reg64_t*)test->mem; } } +reg64_t* TestEd8O(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset) +{ + uint8_t m = v&0xC7; // filter Ed + if(m>=0xC0) { + return &test->emu->regs[(m&0x07)+(rex.b<<3)]; + } else { + reg64_t* ret = GetECommonO(test->emu, addr, rex, m, delta, offset); + test->memsize = 8; + test->memaddr = (uintptr_t)ret; + *(uint64_t*)test->mem = ret->q[0]; + return (reg64_t*)test->mem; + } +} reg64_t* TestEdt(x64test_t *test, 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 925e14d5..e7416b19 100644 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -122,7 +122,9 @@ reg64_t* TestEbO(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); reg64_t* TestEd(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta); reg64_t* TestEd4(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta); +reg64_t* TestEd4O(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset); reg64_t* TestEd8(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta); +reg64_t* TestEd8O(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset); reg64_t* TestEd8xw(x64test_t *test, int w, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta); reg64_t* TestEdt(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta); uintptr_t GetEA(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta); @@ -183,8 +185,8 @@ uintptr_t Run6764_32(x64emu_t *emu, rex_t rex, int rep, int seg, uintptr_t addr) uintptr_t Run670F(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr); uintptr_t Run6766(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr); uintptr_t Run67660F(x64emu_t *emu, rex_t rex, uintptr_t addr); -uintptr_t RunD8(x64emu_t *emu, rex_t rex, uintptr_t addr); -uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr); +uintptr_t RunD8(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs); +uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs); uintptr_t RunDA(x64emu_t *emu, rex_t rex, uintptr_t addr); uintptr_t RunDB(x64emu_t *emu, rex_t rex, uintptr_t addr); uintptr_t RunDC(x64emu_t *emu, rex_t rex, uintptr_t addr); @@ -224,8 +226,8 @@ uintptr_t Test6764_32(x64test_t *test, rex_t rex, int rep, int seg, uintptr_t ad uintptr_t Test670F(x64test_t *test, rex_t rex, int rep, uintptr_t addr); uintptr_t Test6766(x64test_t *test, rex_t rex, int rep, uintptr_t addr); uintptr_t Test67660F(x64test_t *test, rex_t rex, uintptr_t addr); -uintptr_t TestD8(x64test_t *test, rex_t rex, uintptr_t addr); -uintptr_t TestD9(x64test_t *test, rex_t rex, uintptr_t addr); +uintptr_t TestD8(x64test_t *test, rex_t rex, uintptr_t addr, uintptr_t offs); +uintptr_t TestD9(x64test_t *test, rex_t rex, uintptr_t addr, uintptr_t offs); uintptr_t TestDA(x64test_t *test, rex_t rex, uintptr_t addr); uintptr_t TestDB(x64test_t *test, rex_t rex, uintptr_t addr); uintptr_t TestDC(x64test_t *test, rex_t rex, uintptr_t addr); diff --git a/src/emu/x64rund8.c b/src/emu/x64rund8.c index fcd0b0ee..000eab21 100644 --- a/src/emu/x64rund8.c +++ b/src/emu/x64rund8.c @@ -23,9 +23,9 @@ #include "modrm.h" #ifdef TEST_INTERPRETER -uintptr_t TestD8(x64test_t *test, rex_t rex, uintptr_t addr) +uintptr_t TestD8(x64test_t *test, rex_t rex, uintptr_t addr, uintptr_t offs) #else -uintptr_t RunD8(x64emu_t *emu, rex_t rex, uintptr_t addr) +uintptr_t RunD8(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs) #endif { uint8_t nextop; @@ -125,36 +125,68 @@ uintptr_t RunD8(x64emu_t *emu, rex_t rex, uintptr_t addr) } else switch((nextop>>3)&7) { case 0: /* FADD ST0, float */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } ST0.d += *(float*)ED; break; case 1: /* FMUL ST0, float */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } ST0.d *= *(float*)ED; break; case 2: /* FCOM ST0, float */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } fpu_fcom(emu, *(float*)ED); break; case 3: /* FCOMP */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } fpu_fcom(emu, *(float*)ED); fpu_do_pop(emu); break; case 4: /* FSUB ST0, float */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } ST0.d -= *(float*)ED; break; case 5: /* FSUBR ST0, float */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } ST0.d = *(float*)ED - ST0.d; break; case 6: /* FDIV ST0, float */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } ST0.d /= *(float*)ED; break; case 7: /* FDIVR ST0, float */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } ST0.d = *(float*)ED / ST0.d; break; default: diff --git a/src/emu/x64rund9.c b/src/emu/x64rund9.c index df39ed3e..3c7ac142 100644 --- a/src/emu/x64rund9.c +++ b/src/emu/x64rund9.c @@ -23,9 +23,9 @@ #include "modrm.h" #ifdef TEST_INTERPRETER -uintptr_t TestD9(x64test_t *test, rex_t rex, uintptr_t addr) +uintptr_t TestD9(x64test_t *test, rex_t rex, uintptr_t addr, uintptr_t offs) #else -uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr) +uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs) #endif { uint8_t nextop; @@ -232,39 +232,67 @@ uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr) } else switch((nextop>>3)&7) { case 0: /* FLD ST0, Ed float */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } fpu_do_push(emu); ST0.d = *(float*)ED; break; case 2: /* FST Ed, ST0 */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } *(float*)ED = ST0.d; break; case 3: /* FSTP Ed, ST0 */ - GETE4(0); + if(offs) { + GETE4_OFFS(0, offs); + } else { + GETE4(0); + } *(float*)ED = ST0.d; fpu_do_pop(emu); break; case 4: /* FLDENV m */ // warning, incomplete - _GETED(0); + if(offs) { + _GETED_OFFS(0, offs); + } else { + _GETED(0); + } fpu_loadenv(emu, (char*)ED, 0); break; case 5: /* FLDCW Ew */ - GETEW(0); + if(offs) { + GETEW_OFFS(0, offs); + } else { + GETEW(0); + } emu->cw.x16 = EW->word[0]; // do something with cw? break; case 6: /* FNSTENV m */ // warning, incomplete - GETE8(0); + if(offs) { + GETE8_OFFS(0, offs); + } else { + GETE8(0); + } fpu_savenv(emu, (char*)ED, 0); // intruction pointer: 48bits // data (operand) pointer: 48bits // last opcode: 11bits save: 16bits restaured (1st and 2nd opcode only) break; case 7: /* FNSTCW Ew */ - GETEW(0); + if(offs) { + GETEW_OFFS(0, offs); + } else { + GETEW(0); + } EW->word[0] = emu->cw.x16; break; default: -- cgit 1.4.1