about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-03-19 20:51:04 +0800
committerGitHub <noreply@github.com>2025-03-19 13:51:04 +0100
commitba630300b609cce283f2658205db4d9789fe104c (patch)
tree22858b552741b468567c00de9fa189bd007f382c /src
parent0e32c17076ea4377168fa3e6be0b210a7eea1634 (diff)
downloadbox64-ba630300b609cce283f2658205db4d9789fe104c.tar.gz
box64-ba630300b609cce283f2658205db4d9789fe104c.zip
[RV64_DYNAREC] Fixed many minor issues (#2451)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c4
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h41
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c8
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c6
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_shift.c26
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h40
6 files changed, 65 insertions, 60 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index 68295c71..eabb0ac1 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -2672,7 +2672,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                             MOD_DU(xRDX, xRAX, ed);
                             MV(xRAX, x2);
                         } else {
-                            GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
+                            GETEDH(x4, x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
                             BEQ_MARK(xRDX, xZR);
                             if (ed != x1) { MV(x1, ed); }
                             CALL(div64, -1);
@@ -2710,7 +2710,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                             MOD_D(xRDX, xRAX, ed);
                             MV(xRAX, x2);
                         } else {
-                            GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
+                            GETEDH(x4, x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
                             // need to see if RDX == 0 and RAX not signed
                             // or RDX == -1 and RAX signed
                             BNE_MARK2(xRDX, xZR);
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index 4199aef1..e3146d77 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -77,28 +77,27 @@
         LDxw(x1, wback, fixedaddress);                                                            \
         ed = x1;                                                                                  \
     }
-// GETEDH can use hint for ed, and x1 or x2 for wback (depending on hint), might also use x3. wback is 0 if ed is xEAX..xEDI
-#define GETEDH(hint, D)                                                                                                                 \
-    if (MODREG) {                                                                                                                       \
-        ed = TO_NAT((nextop & 7) + (rex.b << 3));                                                                                       \
-        wback = 0;                                                                                                                      \
-    } else {                                                                                                                            \
-        SMREAD();                                                                                                                       \
-        addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 1, D); \
-        LDxw(hint, wback, fixedaddress);                                                                                                \
-        ed = hint;                                                                                                                      \
+// GETEDH can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI
+#define GETEDH(hint, ret, D)                                                                       \
+    if (MODREG) {                                                                                  \
+        ed = TO_NAT((nextop & 7) + (rex.b << 3));                                                  \
+        wback = 0;                                                                                 \
+    } else {                                                                                       \
+        SMREAD();                                                                                  \
+        addr = geted(dyn, addr, ninst, nextop, &wback, hint, ret, &fixedaddress, rex, NULL, 1, D); \
+        ed = ret;                                                                                  \
+        LDxw(ed, wback, fixedaddress);                                                             \
     }
-// GETEDW can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI
-#define GETEDW(hint, ret, D)                                                                                                            \
-    if (MODREG) {                                                                                                                       \
-        ed = TO_NAT((nextop & 7) + (rex.b << 3));                                                                                       \
-        MV(ret, ed);                                                                                                                    \
-        wback = 0;                                                                                                                      \
-    } else {                                                                                                                            \
-        SMREAD();                                                                                                                       \
-        addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 0, D); \
-        ed = ret;                                                                                                                       \
-        LDxw(ed, wback, fixedaddress);                                                                                                  \
+#define GETEDW(hint, ret, D)                                                                       \
+    if (MODREG) {                                                                                  \
+        ed = TO_NAT((nextop & 7) + (rex.b << 3));                                                  \
+        MV(ret, ed);                                                                               \
+        wback = 0;                                                                                 \
+    } else {                                                                                       \
+        SMREAD();                                                                                  \
+        addr = geted(dyn, addr, ninst, nextop, &wback, hint, ret, &fixedaddress, rex, NULL, 0, D); \
+        ed = ret;                                                                                  \
+        LDxw(ed, wback, fixedaddress);                                                             \
     }
 // GETEWW will use i for ed, and can use w for wback.
 #define GETEWW(w, i, D)                                                                       \
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index 81c240e4..f814a75a 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -193,9 +193,9 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
                     SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION);
+                    GETEDW(x4, x1, 0);
                     u8 = (F8) & (rex.w ? 0x3f : 0x1f);
                     MOV32w(x2, u8);
-                    GETEDW(x4, x1, 0);
                     CALL_(rex.w ? ((void*)rcl64) : ((void*)rcl32), ed, x4, x1, x2);
                     WBACK;
                     if (!wback && !rex.w) ZEROUP(ed);
@@ -205,9 +205,9 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
                     SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION);
+                    GETEDW(x4, x1, 0);
                     u8 = (F8) & (rex.w ? 0x3f : 0x1f);
                     MOV32w(x2, u8);
-                    GETEDW(x4, x1, 0);
                     CALL_(rex.w ? ((void*)rcr64) : ((void*)rcr32), ed, x4, x1, x2);
                     WBACK;
                     if (!wback && !rex.w) ZEROUP(ed);
@@ -1366,7 +1366,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                             REMU(xRDX, xRAX, ed);
                             MV(xRAX, x2);
                         } else {
-                            GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
+                            GETEDH(x4, x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
                             if (BOX64ENV(dynarec_div0)) {
                                 BNE_MARK3(ed, xZR);
                                 GETIP_(ip, x7);
@@ -1431,7 +1431,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                             REM(xRDX, xRAX, ed);
                             MV(xRAX, x2);
                         } else {
-                            GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
+                            GETEDH(x4, x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
                             if (BOX64ENV(dynarec_div0)) {
                                 BNE_MARK3(ed, xZR);
                                 GETIP_(ip, x7);
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index 9535ce8d..25e595f5 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -1398,11 +1398,12 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     GETEW(x1, 0);
                     ZEXTH(x2, xRAX);
                     MULW(x1, x2, x1);
+                    ZEROUP(x1);
                     UFLAG_RES(x1);
                     INSHz(xRAX, x1, x4, x5, 1, 1);
                     SRLI(xRDX, xRDX, 16);
                     SLLI(xRDX, xRDX, 16);
-                    SRLI(x1, x1, 48);
+                    SRLI(x1, x1, 16);
                     OR(xRDX, xRDX, x1);
                     UFLAG_DF(x1, d_mul16);
                     break;
@@ -1413,11 +1414,12 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     SLLI(x2, xRAX, 16);
                     SRAIW(x2, x2, 16);
                     MULW(x1, x2, x1);
+                    ZEROUP(x1);
                     UFLAG_RES(x1);
                     INSHz(xRAX, x1, x4, x5, 1, 1);
                     SRLI(xRDX, xRDX, 16);
                     SLLI(xRDX, xRDX, 16);
-                    SRLI(x1, x1, 48);
+                    SRLI(x1, x1, 16);
                     OR(xRDX, xRDX, x1);
                     UFLAG_DF(x1, d_imul16);
                     break;
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
index 91c9bb6c..797c769b 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
@@ -1068,10 +1068,12 @@ void emit_rol16c(dynarec_rv64_t* dyn, int ninst, int s1, uint32_t c, int s3, int
 
     SET_DFNONE();
 
-    SLLI(s3, s1, 48 + c);
-    SRLI(s3, s3, 48);
-    SRLI(s1, s1, 16 - c);
-    OR(s1, s1, s3);
+    if (c & 15) {
+        SRLI(s3, s1, 16 - (c & 15));
+        SLLI(s1, s1, c & 15);
+        OR(s1, s1, s3);
+        ZEXTH(s1, s1);
+    }
 
     if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR);
 
@@ -1148,10 +1150,12 @@ void emit_ror16c(dynarec_rv64_t* dyn, int ninst, int s1, uint32_t c, int s3, int
 
     SET_DFNONE();
 
-    SRLI(s3, s1, c);
-    SLLI(s1, s1, 64 - c);
-    SRLI(s1, s1, 48);
-    OR(s1, s1, s3);
+    if (c & 15) {
+        SRLI(s3, s1, c & 15);
+        SLLI(s1, s1, 16 - (c & 15));
+        OR(s1, s1, s3);
+        ZEXTH(s1, s1);
+    }
 
     if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR);
 
@@ -1692,10 +1696,10 @@ void emit_rcr16c(dynarec_rv64_t* dyn, int ninst, int s1, uint32_t c, int s3, int
     OR(s1, s1, s3); // insert CF to bit 16
 
     SRLI(s3, s1, c);
-    SLLI(s4, s1, 63 - c);
-    SLLI(s1, s4, s1);
-    SRLI(s1, s1, 48);
+    SLLI(s1, s1, 17 - c);
     OR(s1, s1, s3);
+    SLLI(s4, s1, 47);
+    ZEXTH(s1, s1);
 
     if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR);
 
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 684357bf..a519b71a 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -98,28 +98,28 @@
         LDxw(x1, wback, fixedaddress);                                                            \
         ed = x1;                                                                                  \
     }
-// GETEDH can use hint for ed, and x1 or x2 for wback (depending on hint), might also use x3. wback is 0 if ed is xEAX..xEDI
-#define GETEDH(hint, D)                                                                                                                 \
-    if (MODREG) {                                                                                                                       \
-        ed = TO_NAT((nextop & 7) + (rex.b << 3));                                                                                       \
-        wback = 0;                                                                                                                      \
-    } else {                                                                                                                            \
-        SMREAD();                                                                                                                       \
-        addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 1, D); \
-        LDxw(hint, wback, fixedaddress);                                                                                                \
-        ed = hint;                                                                                                                      \
+// GETEDH can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI
+#define GETEDH(hint, ret, D)                                                                       \
+    if (MODREG) {                                                                                  \
+        ed = TO_NAT((nextop & 7) + (rex.b << 3));                                                  \
+        wback = 0;                                                                                 \
+    } else {                                                                                       \
+        SMREAD();                                                                                  \
+        addr = geted(dyn, addr, ninst, nextop, &wback, hint, ret, &fixedaddress, rex, NULL, 1, D); \
+        ed = ret;                                                                                  \
+        LDxw(ed, wback, fixedaddress);                                                             \
     }
 // GETEDW can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI
-#define GETEDW(hint, ret, D)                                                                                                            \
-    if (MODREG) {                                                                                                                       \
-        ed = TO_NAT((nextop & 7) + (rex.b << 3));                                                                                       \
-        MV(ret, ed);                                                                                                                    \
-        wback = 0;                                                                                                                      \
-    } else {                                                                                                                            \
-        SMREAD();                                                                                                                       \
-        addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 0, D); \
-        ed = ret;                                                                                                                       \
-        LDxw(ed, wback, fixedaddress);                                                                                                  \
+#define GETEDW(hint, ret, D)                                                                       \
+    if (MODREG) {                                                                                  \
+        ed = TO_NAT((nextop & 7) + (rex.b << 3));                                                  \
+        MV(ret, ed);                                                                               \
+        wback = 0;                                                                                 \
+    } else {                                                                                       \
+        SMREAD();                                                                                  \
+        addr = geted(dyn, addr, ninst, nextop, &wback, hint, ret, &fixedaddress, rex, NULL, 0, D); \
+        ed = ret;                                                                                  \
+        LDxw(ed, wback, fixedaddress);                                                             \
     }
 // GETGW extract x64 register in gd, that is i
 #define GETGW(i)                                        \