about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-07-05 00:47:45 +0800
committerGitHub <noreply@github.com>2024-07-04 18:47:45 +0200
commit2c0bbc06b7b05c2f5f06ef3ccc7d2e4cfb9117f1 (patch)
tree569e96cef7c1e16f6b5f19a790ee6f2ce721026a /src
parent299551428f2f68a720e0148f0176840f55976dc4 (diff)
downloadbox64-2c0bbc06b7b05c2f5f06ef3ccc7d2e4cfb9117f1.tar.gz
box64-2c0bbc06b7b05c2f5f06ef3ccc7d2e4cfb9117f1.zip
[DYNAREC] Fixed IMUL sign extension issue (#1639)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c6
-rw-r--r--src/dynarec/la64/dynarec_la64_0f.c4
-rw-r--r--src/dynarec/la64/la64_printer.c14
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_1.c6
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c30
5 files changed, 26 insertions, 34 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index a7207003..ba441913 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -529,7 +529,8 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 // 32bits imul
                 UFLAG_IF {
-                    MUL_D(gd, ed, x4);
+                    SLLI_W(x3, ed, 0);
+                    MUL_D(gd, x3, x4);
                     UFLAG_RES(gd);
                     SRLI_D(x3, gd, 32);
                     UFLAG_OP1(x3);
@@ -568,7 +569,8 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 // 32bits imul
                 UFLAG_IF {
-                    MUL_D(gd, ed, x4);
+                    SLLI_W(x3, ed, 0);
+                    MUL_D(gd, x3, x4);
                     UFLAG_RES(gd);
                     SRLI_D(x3, gd, 32);
                     UFLAG_OP1(x3);
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c
index 0c40f766..2bdc22a1 100644
--- a/src/dynarec/la64/dynarec_la64_0f.c
+++ b/src/dynarec/la64/dynarec_la64_0f.c
@@ -784,7 +784,9 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     if (la64_lbt) {
                         X64_MUL_W(gd, ed);
                     }
-                    MUL_D(gd, gd, ed);
+                    SLLI_W(gd, gd, 0);
+                    SLLI_W(x3, ed, 0);
+                    MUL_D(gd, gd, x3);
                     SRLI_D(x3, gd, 32);
                     SLLI_W(gd, gd, 0);
                     IFX (X_PEND) {
diff --git a/src/dynarec/la64/la64_printer.c b/src/dynarec/la64/la64_printer.c
index 5c58541c..aae90869 100644
--- a/src/dynarec/la64/la64_printer.c
+++ b/src/dynarec/la64/la64_printer.c
@@ -2237,31 +2237,31 @@ const char* la64_print(uint32_t opcode, uintptr_t addr)
         return buff;
     }
     if (isMask(opcode, "00000000001111101kkkkkjjjjj00001", &a)) {
-        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]);
+        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.H", Xt[Rj], Xt[Rk]);
         return buff;
     }
     if (isMask(opcode, "00000000001111101kkkkkjjjjj00010", &a)) {
-        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]);
+        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.W", Xt[Rj], Xt[Rk]);
         return buff;
     }
     if (isMask(opcode, "00000000001111101kkkkkjjjjj00011", &a)) {
-        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]);
+        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.D", Xt[Rj], Xt[Rk]);
         return buff;
     }
     if (isMask(opcode, "00000000001111101kkkkkjjjjj00100", &a)) {
-        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]);
+        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.BU", Xt[Rj], Xt[Rk]);
         return buff;
     }
     if (isMask(opcode, "00000000001111101kkkkkjjjjj00101", &a)) {
-        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]);
+        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.HU", Xt[Rj], Xt[Rk]);
         return buff;
     }
     if (isMask(opcode, "00000000001111101kkkkkjjjjj00110", &a)) {
-        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]);
+        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.WU", Xt[Rj], Xt[Rk]);
         return buff;
     }
     if (isMask(opcode, "00000000001111101kkkkkjjjjj00111", &a)) {
-        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]);
+        snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.DU", Xt[Rj], Xt[Rk]);
         return buff;
     }
     if (isMask(opcode, "00000000001111110kkkkkjjjjj00000", &a)) {
diff --git a/src/dynarec/rv64/dynarec_rv64_00_1.c b/src/dynarec/rv64/dynarec_rv64_00_1.c
index 08c39829..a361af5f 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_1.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_1.c
@@ -212,7 +212,8 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             } else {
                 // 32bits imul
                 UFLAG_IF {
-                    MUL(gd, ed, x4);
+                    SEXT_W(x3, ed);
+                    MUL(gd, x3, x4);
                     UFLAG_RES(gd);
                     SRLI(x3, gd, 32);
                     UFLAG_OP1(x3);
@@ -251,7 +252,8 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             } else {
                 // 32bits imul
                 UFLAG_IF {
-                    MUL(gd, ed, x4);
+                    SEXT_W(x3, ed);
+                    MUL(gd, x3, x4);
                     UFLAG_RES(gd);
                     SRLI(x3, gd, 32);
                     UFLAG_OP1(x3);
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 26e64d3d..f7565a7e 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -1894,43 +1894,29 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             GETED(0);
             if (rex.w) {
                 // 64bits imul
-                UFLAG_IF
-                {
+                UFLAG_IF {
                     MULH(x3, gd, ed);
                     MUL(gd, gd, ed);
                     UFLAG_OP1(x3);
                     UFLAG_RES(gd);
                     UFLAG_DF(x3, d_imul64);
-                }
-                else
-                {
+                } else {
                     MULxw(gd, gd, ed);
                 }
             } else {
                 // 32bits imul
-                UFLAG_IF
-                {
-                    SLLI(gd, gd, 32);
-                    SRAI(gd, gd, 32);
-                    if(MODREG) {
-                        SLLI(x1, ed, 32);
-                        ed = x1;
-                    } else {
-                        SLLI(ed, ed, 32);
-                    }
-                    SRAI(ed, ed, 32);
-                    MUL(gd, gd, ed);
+                UFLAG_IF {
+                    SEXT_W(gd, gd);
+                    SEXT_W(x3, ed);
+                    MUL(gd, gd, x3);
                     UFLAG_RES(gd);
                     SRLI(x3, gd, 32);
                     UFLAG_OP1(x3);
                     UFLAG_DF(x3, d_imul32);
-                }
-                else
-                {
+                } else {
                     MULxw(gd, gd, ed);
                 }
-                SLLI(gd, gd, 32);
-                SRLI(gd, gd, 32);
+                ZEROUP(gd);
             }
             break;
         case 0xB3: