about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-09-19 16:43:23 +0800
committerGitHub <noreply@github.com>2024-09-19 10:43:23 +0200
commitef7f25481cb2e85da51b2da107a1b88f2434bf2d (patch)
tree735eb45eaa95877e7be75a4b4ad684ae16aba06c /src
parent35d17abeb0dfcd2009cedff7f6d0c71de182caec (diff)
downloadbox64-ef7f25481cb2e85da51b2da107a1b88f2434bf2d.tar.gz
box64-ef7f25481cb2e85da51b2da107a1b88f2434bf2d.zip
[RV64_DYNAREC] Added more opcodes for vector (#1836)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f_vector.c20
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f_vector.c66
-rw-r--r--src/dynarec/rv64/dynarec_rv64_67.c3
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h7
4 files changed, 96 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
index a6c85e53..3692d34f 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
@@ -94,6 +94,26 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 SMWRITE2();
             }
             break;
+        case 0x12:
+            nextop = F8;
+            if (MODREG) {
+                INST_NAME("MOVHLPS Gx, Ex");
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+                GETGX_vector(v0, 1, dyn->vector_eew);
+                GETEX_vector(v1, 0, 0, VECTOR_SEW64);
+                q0 = fpu_get_scratch(dyn);
+                VSLIDEDOWN_VI(q0, 1, v1, VECTOR_UNMASKED);
+                VMV_X_S(x4, q0);
+                VMV_S_X(v0, x4);
+            } else {
+                INST_NAME("MOVLPS Gx, Ex");
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+                GETGX_vector(v0, 1, VECTOR_SEW64);
+                GETEX_vector(v1, 0, 0, VECTOR_SEW64);
+                VMV_X_S(x4, v1);
+                VMV_S_X(v0, x4);
+            }
+            break;
         case 0x16:
             nextop = F8;
             if (MODREG) {
diff --git a/src/dynarec/rv64/dynarec_rv64_660f_vector.c b/src/dynarec/rv64/dynarec_rv64_660f_vector.c
index 1d2b4638..b421a053 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f_vector.c
@@ -35,6 +35,7 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
     int v0, v1;
     int q0, q1;
     int d0, d1, d2;
+    uint64_t tmp64u0, tmp64u1;
     int64_t fixedaddress, gdoffset;
     uint32_t vtypei;
     int unscaled;
@@ -843,6 +844,46 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                 VLE_V(v0, ed, dyn->vector_eew, VECTOR_UNMASKED, VECTOR_NFIELD1);
             }
             break;
+        case 0x70:
+            INST_NAME("PSHUFD Gx, Ex, Ib");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            GETGX_vector(q0, 1, VECTOR_SEW64);
+            GETEX_vector(q1, 0, 0, VECTOR_SEW64);
+            v0 = fpu_get_scratch(dyn);
+            tmp64u0 = F8;
+            tmp64u0 = ((tmp64u0 >> 6) << 48) | (((tmp64u0 >> 4) & 3) << 32) | (((tmp64u0 >> 2) & 3) << 16) | (tmp64u0 & 3);
+            VECTOR_SPLAT_IMM(v0, tmp64u0, x4);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+            if (q0 == q1) {
+                v1 = fpu_get_scratch(dyn);
+                VRGATHEREI16_VV(v1, v0, q1, VECTOR_UNMASKED);
+                VMV_V_V(q0, v1);
+            } else {
+                VRGATHEREI16_VV(q0, v0, q1, VECTOR_UNMASKED);
+            }
+            break;
+        case 0x73:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 3:
+                    INST_NAME("PSRLDQ Ex, Ib");
+                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1);
+                    GETEX_vector(q0, 1, 1, VECTOR_SEW8);
+                    u8 = F8;
+                    if (!u8) break;
+                    if (u8 > 15) {
+                        VXOR_VV(q0, q0, q0, VECTOR_UNMASKED);
+                    } else {
+                        v0 = fpu_get_scratch(dyn);
+                        VMV_V_V(v0, q0);
+                        VSLIDEDOWN_VI(q0, u8, v0, VECTOR_UNMASKED);
+                    }
+                    PUTEX_vector(q0, VECTOR_SEW8);
+                    break;
+                default: DEFAULT_VECTOR;
+            }
+            break;
         case 0x7E:
             return 0;
         case 0xEF:
@@ -869,6 +910,23 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
             GETEX_vector(q1, 0, 0, VECTOR_SEW64);
             VADD_VV(q0, q0, q1, VECTOR_UNMASKED);
             break;
+        case 0xD6:
+            INST_NAME("MOVQ Ex, Gx");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            GETGX_vector(q0, 1, VECTOR_SEW64);
+            if (MODREG) {
+                q1 = sse_get_reg_empty_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3));
+                VMV_X_S(x4, q0);
+                VXOR_VV(q1, q1, q1, VECTOR_UNMASKED);
+                VMV_S_X(q1, x4);
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 0, 0);
+                VMV_V_I(VMASK, 0b01);
+                VSE64_V(q0, ed, VECTOR_MASKED, VECTOR_NFIELD1);
+                SMWRITE2();
+            }
+            break;
         case 0xDB:
             INST_NAME("PAND Gx, Ex");
             nextop = F8;
@@ -877,6 +935,14 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
             GETEX_vector(q1, 0, 0, dyn->vector_eew);
             VAND_VV(q0, q0, q1, VECTOR_UNMASKED);
             break;
+        case 0xEB:
+            INST_NAME("POR Gx, Ex");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1);
+            GETGX_vector(q0, 1, dyn->vector_eew);
+            GETEX_vector(q1, 0, 0, dyn->vector_eew);
+            VOR_VV(q0, q0, q1, VECTOR_UNMASKED);
+            break;
         default:
             DEFAULT_VECTOR;
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c
index 59fc507a..76bdaef4 100644
--- a/src/dynarec/rv64/dynarec_rv64_67.c
+++ b/src/dynarec/rv64/dynarec_rv64_67.c
@@ -763,6 +763,9 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             break;
         #undef GO
 
+        case 0xE8:
+            return dynarec64_00(dyn, addr - 1, ip, ninst, rex, rep, ok, need_epilog); // addr-1, to "put back" opcode)
+
         case 0xF7:
             nextop = F8;
             switch ((nextop >> 3) & 7) {
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 0d1c3f7e..a04af639 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -510,6 +510,13 @@
         VLE_V(a, x2, sew, VECTOR_UNMASKED, VECTOR_NFIELD1);                                  \
     }
 
+// Put Back EX if it was a memory and not an emm register
+#define PUTEX_vector(a, sew)                                \
+    if (!MODREG) {                                          \
+        VSE_V(a, x2, sew, VECTOR_UNMASKED, VECTOR_NFIELD1); \
+        SMWRITE2();                                         \
+    }
+
 #define GETGM()                     \
     gd = ((nextop & 0x38) >> 3);    \
     mmx_forget_reg(dyn, ninst, gd); \