about summary refs log tree commit diff stats
path: root/src/dynarec
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-10-10 17:39:02 +0800
committerGitHub <noreply@github.com>2025-10-10 11:39:02 +0200
commitf0eab197be50e18b2040c92d1bc4612d264dbcd3 (patch)
tree8284e13ec251ea52376fe92dd8adfd8f204aab5d /src/dynarec
parent6250f03b098619bc6c2dabaedf8560775cdb9bdf (diff)
downloadbox64-f0eab197be50e18b2040c92d1bc4612d264dbcd3.tar.gz
box64-f0eab197be50e18b2040c92d1bc4612d264dbcd3.zip
[DYNAREC] Fixed a special case of SHLD/SHRD opcodes (#3047)
Diffstat (limited to 'src/dynarec')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c2
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h9
-rw-r--r--src/dynarec/la64/dynarec_la64_0f.c2
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h9
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h9
6 files changed, 24 insertions, 9 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 446822c0..8813a577 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -1799,6 +1799,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 WBACK;

             } else {

                 FAKEED;

+                if (!rex.w && !rex.is32bits && MODREG) { MOVw_REG(ed, ed); }

                 F8;

             }

             break;

@@ -1886,6 +1887,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 WBACK;

             } else {

                 FAKEED;

+                if (!rex.w && !rex.is32bits && MODREG) { MOVw_REG(ed, ed); }

                 F8;

             }

             break;

diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 48e809bf..9519e991 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -219,9 +219,12 @@
         wb = ed = x1;                                                                                   \
     }
 //FAKEELike GETED, but doesn't get anything
-#define FAKEED                                   \
-    if (!MODREG) {                               \
-        addr = fakeed(dyn, addr, ninst, nextop); \
+#define FAKEED                                    \
+    if (MODREG) {                                 \
+        ed = TO_NAT((nextop & 7) + (rex.b << 3)); \
+        wback = 0;                                \
+    } else {                                      \
+        addr = fakeed(dyn, addr, ninst, nextop);  \
     }
 
 // GETGW extract x64 register in gd, that is i
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c
index c4dcf9da..4391a0db 100644
--- a/src/dynarec/la64/dynarec_la64_0f.c
+++ b/src/dynarec/la64/dynarec_la64_0f.c
@@ -1413,6 +1413,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 WBACK;
             } else {
                 FAKEED;
+                if (!rex.w && !rex.is32bits && MODREG) { ZEROUP(ed); }
                 F8;
             }
             break;
@@ -1466,6 +1467,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 WBACK;
             } else {
                 FAKEED;
+                if (!rex.w && !rex.is32bits && MODREG) { ZEROUP(ed); }
                 F8;
             }
             break;
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index 740c6909..9cb25114 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -168,9 +168,12 @@
     }
 
 // FAKEED like GETED, but doesn't get anything
-#define FAKEED                                   \
-    if (!MODREG) {                               \
-        addr = fakeed(dyn, addr, ninst, nextop); \
+#define FAKEED                                    \
+    if (MODREG) {                                 \
+        ed = TO_NAT((nextop & 7) + (rex.b << 3)); \
+        wback = 0;                                \
+    } else {                                      \
+        addr = fakeed(dyn, addr, ninst, nextop);  \
     }
 
 // GETGW extract x64 register in gd, that is i, Signed extented
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 5cee64c1..31cfd7ea 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -1884,6 +1884,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 WBACK;
             } else {
                 FAKEED;
+                if (!rex.w && !rex.is32bits && MODREG) { ZEROUP(ed); }
                 F8;
             }
             break;
@@ -1946,6 +1947,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 WBACK;
             } else {
                 FAKEED;
+                if (!rex.w && !rex.is32bits && MODREG) { ZEROUP(ed); }
                 F8;
             }
             break;
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index d59e07f2..7daba6bf 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -210,9 +210,12 @@
     }
 
 // FAKEED like GETED, but doesn't get anything
-#define FAKEED                                   \
-    if (!MODREG) {                               \
-        addr = fakeed(dyn, addr, ninst, nextop); \
+#define FAKEED                                    \
+    if (MODREG) {                                 \
+        ed = TO_NAT((nextop & 7) + (rex.b << 3)); \
+        wback = 0;                                \
+    } else {                                      \
+        addr = fakeed(dyn, addr, ninst, nextop);  \
     }
 
 // GETGW extract x64 register in gd, that is i, Signed extented