about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-11-11 19:29:55 +0800
committerGitHub <noreply@github.com>2024-11-11 12:29:55 +0100
commit56e813ccb784fb454cc314ac4f03b044569cd650 (patch)
tree977524cf00ab213f40424e60587257c3fa0026fb
parentcf5b94d4716875826a7928951b1d304d2f869e47 (diff)
downloadbox64-56e813ccb784fb454cc314ac4f03b044569cd650.tar.gz
box64-56e813ccb784fb454cc314ac4f03b044569cd650.zip
[RV64_DYNAREC] Added more MMX opcodes for vector (#2017)
* [RV64_DYNAREC] Added more MMX opcodes for vector

* fixed
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c19
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f_vector.c11
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h17
3 files changed, 43 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 0320a75b..48682842 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -1633,14 +1633,25 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0x7E:
             INST_NAME("MOVD Ed, Gm");
             nextop = F8;
-            GETGM();
+            gd = ((nextop & 0x38) >> 3);
+            v0 = mmx_get_reg(dyn, ninst, x1, x2, x3, gd);
             if ((nextop & 0xC0) == 0xC0) {
                 ed = xRAX + (nextop & 7) + (rex.b << 3);
-                LDxw(ed, gback, gdoffset);
+                if (rex.w)
+                    FMVXD(ed, v0);
+                else {
+                    FMVXW(ed, v0);
+                    ZEROUP(ed);
+                }
             } else {
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, 0);
-                LDxw(x1, gback, gdoffset);
-                SDxw(x1, wback, fixedaddress);
+                if (rex.w) {
+                    FMVXD(x1, v0);
+                    SD(x1, wback, fixedaddress);
+                } else {
+                    FMVXW(x1, v0);
+                    SW(x1, wback, fixedaddress);
+                }
                 SMWRITE2();
             }
             break;
diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
index b20767cc..2eedcc22 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
@@ -580,11 +580,22 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
             VMV_V_V(v0, d0);
             VSLIDEUP_VI(v0, d1, 2, VECTOR_UNMASKED);
             break;
+        case 0xFC:
+            INST_NAME("PADDB Gm, Em");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            GETGM_vector(v0);
+            GETEM_vector(v1, 0);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1);
+            VADD_VV(v0, v0, v1, VECTOR_UNMASKED);
+            break;
         case 0x00 ... 0x0F:
         case 0x18:
         case 0x1F:
         case 0x31:
         case 0x40 ... 0x4F:
+        case 0x77:
+        case 0x7E:
         case 0x80 ... 0xBF:
         case 0xC0 ... 0xC1:
         case 0xC3 ... 0xC5:
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index d4f4b102..9b30ab79 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -531,6 +531,11 @@
     gback = xEmu;                       \
     gdoffset = offsetof(x64emu_t, mmx[gd])
 
+// Get GM as vector, might use x1, x2 and x3
+#define GETGM_vector(a)          \
+    gd = ((nextop & 0x38) >> 3); \
+    a = mmx_get_reg_vector(dyn, ninst, x1, x2, x3, gd)
+
 // Get EM, might use x3
 #define GETEM(a, D, I12)                                                                         \
     if (MODREG) {                                                                                \
@@ -544,6 +549,18 @@
         addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, I12, D); \
     }
 
+// Get EM as vector, might use x1, x2 and x3
+#define GETEM_vector(a, D)                                                                     \
+    if (MODREG) {                                                                              \
+        a = mmx_get_reg_vector(dyn, ninst, x1, x2, x3, (nextop & 7));                          \
+    } else {                                                                                   \
+        SMREAD();                                                                              \
+        addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, 1, D); \
+        a = fpu_get_scratch(dyn);                                                              \
+        FLD(a, ed, fixedaddress);                                                              \
+        VFMV_S_F(a, a);                                                                        \
+    }
+
 #define GETGX_empty_vector(a)                   \
     gd = ((nextop & 0x38) >> 3) + (rex.r << 3); \
     a = sse_get_reg_empty_vector(dyn, ninst, x1, gd)