about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-10-12 02:15:10 +0800
committerGitHub <noreply@github.com>2025-10-11 20:15:10 +0200
commit494428dbbe1309ecc19a5b9862b0cd2ab02c501d (patch)
tree69e7bd81a8bc5923054362453af3120c12899ffc
parenta40b6d49cb19134386b56648be43b8ccdd2b6c7a (diff)
downloadbox64-494428dbbe1309ecc19a5b9862b0cd2ab02c501d.tar.gz
box64-494428dbbe1309ecc19a5b9862b0cd2ab02c501d.zip
[DYNAREC] Fixed negative issues with 0F/F0 A3/AB/B3/BB opcodes (#3057)
-rw-r--r--src/dynarec/la64/dynarec_la64_0f.c20
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c20
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f0.c10
3 files changed, 40 insertions, 10 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c
index e07d650d..39f1ac74 100644
--- a/src/dynarec/la64/dynarec_la64_0f.c
+++ b/src/dynarec/la64/dynarec_la64_0f.c
@@ -1387,7 +1387,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
-                SRAIxw(x1, gd, 5 + rex.w);        // r1 = (gd>>5)
+                if (rex.w)
+                    SRAI_D(x1, gd, 6);
+                else
+                    SRAI_W(x1, gd, 5);
                 ALSL_D(x3, x1, wback, 2 + rex.w); // (&ed) += r1*4;
                 LDxw(x1, x3, fixedaddress);
                 ed = x1;
@@ -1429,7 +1432,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
-                SRAI_D(x1, gd, 5 + rex.w);
+                if (rex.w)
+                    SRAI_D(x1, gd, 6);
+                else
+                    SRAI_W(x1, gd, 5);
                 ALSL_D(x3, x1, wback, 2 + rex.w);
                 LDxw(x1, x3, fixedaddress);
                 ed = x1;
@@ -1672,7 +1678,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
-                SRAIxw(x1, gd, 5 + rex.w);
+                if (rex.w)
+                    SRAI_D(x1, gd, 6);
+                else
+                    SRAI_W(x1, gd, 5);
                 ADDSL(x3, wback, x1, 2 + rex.w, x1);
                 LDxw(x1, x3, fixedaddress);
                 ed = x1;
@@ -1827,7 +1836,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
-                SRAIxw(x1, gd, 5 + rex.w);
+                if (rex.w)
+                    SRAI_D(x1, gd, 6);
+                else
+                    SRAI_W(x1, gd, 5);
                 ADDSL(x3, wback, x1, 2 + rex.w, x1);
                 LDxw(x1, x3, fixedaddress);
                 ed = x1;
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 31cfd7ea..8039a8fc 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -1861,7 +1861,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
-                SRAIxw(x1, gd, 5 + rex.w); // r1 = (gd>>5)
+                if (rex.w)
+                    SRAI(x1, gd, 6);
+                else
+                    SRAIW(x1, gd, 5);
                 ADDSL(x3, wback, x1, 2 + rex.w, x1);
                 LDxw(x1, x3, fixedaddress);
                 ed = x1;
@@ -1914,7 +1917,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
-                SRAIxw(x1, gd, 5 + rex.w);
+                if (rex.w)
+                    SRAI(x1, gd, 6);
+                else
+                    SRAIW(x1, gd, 5);
                 ADDSL(x3, wback, x1, 2 + rex.w, x1);
                 LDxw(x1, x3, fixedaddress);
                 ed = x1;
@@ -2142,7 +2148,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
-                SRAIxw(x1, gd, 5 + rex.w);
+                if (rex.w)
+                    SRAI(x1, gd, 6);
+                else
+                    SRAIW(x1, gd, 5);
                 ADDSL(x3, wback, x1, 2 + rex.w, x1);
                 LDxw(x1, x3, fixedaddress);
                 ed = x1;
@@ -2312,7 +2321,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
-                SRAIxw(x1, gd, 5 + rex.w);
+                if (rex.w)
+                    SRAI(x1, gd, 6);
+                else
+                    SRAIW(x1, gd, 5);
                 ADDSL(x3, wback, x1, 2 + rex.w, x1);
                 LDxw(x1, x3, fixedaddress);
                 ed = x1;
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c
index 544a8c11..2a3f93c0 100644
--- a/src/dynarec/rv64/dynarec_rv64_f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_f0.c
@@ -130,7 +130,10 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         if (!rex.w) ZEROUP(ed);
                     } else {
                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
-                        SRAIxw(x1, gd, 5 + rex.w);
+                        if (rex.w)
+                            SRAI(x1, gd, 6);
+                        else
+                            SRAIW(x1, gd, 5);
                         ADDSL(x3, wback, x1, 2 + rex.w, x1);
                         ed = x1;
                         wback = x3;
@@ -310,7 +313,10 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         if (!rex.w) ZEROUP(ed);
                     } else {
                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
-                        SRAIxw(x1, gd, 5 + rex.w);
+                        if (rex.w)
+                            SRAI(x1, gd, 6);
+                        else
+                            SRAIW(x1, gd, 5);
                         ADDSL(x3, wback, x1, 2 + rex.w, x1);
                         LDxw(x1, x3, fixedaddress);
                         ed = x1;