about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-11-07 15:52:10 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-11-07 15:52:10 +0100
commit56bd83f6fbcf46699e28eb4164360f6fbd64a1ed (patch)
tree48cd0c25aa688d3eb1ad9bb59219547453355501
parent2473bb69025c7b88eca3bf3496037278126ac613 (diff)
downloadbox64-56bd83f6fbcf46699e28eb4164360f6fbd64a1ed.tar.gz
box64-56bd83f6fbcf46699e28eb4164360f6fbd64a1ed.zip
Added 64/65 D8..D9 opcodes
-rw-r--r--src/emu/modrm.h5
-rw-r--r--src/emu/x64run.c8
-rw-r--r--src/emu/x64run64.c15
-rw-r--r--src/emu/x64run_private.c26
-rw-r--r--src/emu/x64run_private.h10
-rw-r--r--src/emu/x64rund8.c52
-rw-r--r--src/emu/x64rund9.c46
7 files changed, 135 insertions, 27 deletions
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: