about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-03-08 13:54:34 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-03-08 13:54:34 +0100
commit5ed3ef918dcdab1619f087f1e0747d73c8d19ded (patch)
treead0b4def683ee5738a948475f6952d9564856803 /src
parentc0f78342e1571306f5d30087ccd8f0b289ea949e (diff)
downloadbox64-5ed3ef918dcdab1619f087f1e0747d73c8d19ded.tar.gz
box64-5ed3ef918dcdab1619f087f1e0747d73c8d19ded.zip
[INTERPRETER] Added 67 64 8F opcodes, and fixed 67 64 89/8B opcodes
Diffstat (limited to 'src')
-rw-r--r--src/emu/modrm.h2
-rw-r--r--src/emu/x64run6764_32.c22
-rw-r--r--src/emu/x64run_private.c62
-rw-r--r--src/emu/x64run_private.h2
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);