about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-09-24 23:03:11 +0800
committerGitHub <noreply@github.com>2024-09-24 17:03:11 +0200
commit2d0b60898cc4b7d7feaa49f47d3d569d407e93c1 (patch)
tree854688c32639949babb375aca9755f407c7c9030 /src
parentc25fc8cc24bfcd67772971bbe467d0e7c6250d54 (diff)
downloadbox64-2d0b60898cc4b7d7feaa49f47d3d569d407e93c1.tar.gz
box64-2d0b60898cc4b7d7feaa49f47d3d569d407e93c1.zip
[RV64_DYNAREC] Added more opcodes for vector (#1863)
* [RV64_DYNAREC] Added more opcodes for vector

* [RV64_DYNAREC] Added more opcodes for vector

* [RV64_DYNAREC] Added more opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f_vector.c15
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f_vector.c99
2 files changed, 113 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
index 96f7e7ee..104db227 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
@@ -193,6 +193,21 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 SMWRITE2();
             }
             break;
+        case 0x57:
+            INST_NAME("XORPS Gx, Ex");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1);
+            GETG;
+            if (MODREG && ((nextop & 7) + (rex.b << 3) == gd)) {
+                // special case for XORPS Gx, Gx
+                q0 = sse_get_reg_empty_vector(dyn, ninst, x1, gd);
+                VXOR_VV(q0, q0, q0, VECTOR_UNMASKED);
+            } else {
+                q0 = sse_get_reg_vector(dyn, ninst, x1, gd, 1, dyn->vector_eew);
+                GETEX_vector(q1, 0, 0, dyn->vector_eew);
+                VXOR_VV(q0, q0, q1, VECTOR_UNMASKED);
+            }
+            break;
         case 0xC6:
             INST_NAME("SHUFPS Gx, Ex, Ib");
             nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_660f_vector.c b/src/dynarec/rv64/dynarec_rv64_660f_vector.c
index 6f6207dc..81afe063 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f_vector.c
@@ -47,6 +47,87 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
     MAYUSE(eb2);
     MAYUSE(j64);
     switch (opcode) {
+        case 0x10:
+            INST_NAME("MOVUPD Gx, Ex");
+            nextop = F8;
+            GETG;
+            if (MODREG) {
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1);
+                v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, dyn->vector_eew);
+                v0 = sse_get_reg_empty_vector(dyn, ninst, x1, gd);
+                VMV_V_V(v0, v1);
+            } else {
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1); // unaligned!
+                SMREAD();
+                v0 = sse_get_reg_empty_vector(dyn, ninst, x1, gd);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 0, 0);
+                VLE8_V(v0, ed, VECTOR_UNMASKED, VECTOR_NFIELD1);
+            }
+            break;
+        case 0x11:
+            INST_NAME("MOVUPD Ex, Gx");
+            nextop = F8;
+            GETG;
+            if (MODREG) {
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1);
+                v0 = sse_get_reg_vector(dyn, ninst, x1, gd, 0, dyn->vector_eew);
+                v1 = sse_get_reg_empty_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3));
+                VMV_V_V(v1, v0);
+            } else {
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1); // unaligned!
+                v0 = sse_get_reg_vector(dyn, ninst, x1, gd, 0, dyn->vector_eew);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 0, 0);
+                VSE8_V(v0, ed, VECTOR_UNMASKED, VECTOR_NFIELD1);
+                SMWRITE2();
+            }
+            break;
+        case 0x14:
+            INST_NAME("UNPCKLPD Gx, Ex");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            // GX->q[0] = GX->q[0]; -> unchanged
+            // GX->q[1] = EX->q[0];
+            GETGX_vector(v0, 1, VECTOR_SEW64);
+            if (MODREG) {
+                v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW64);
+                if (v0 == v1) {
+                    // for vslideup.vi, cannot be overlapped
+                    v1 = fpu_get_scratch(dyn);
+                    VMV_V_V(v1, v0);
+                }
+                VSLIDEUP_VI(v0, 1, v1, VECTOR_UNMASKED);
+            } else {
+                q0 = fpu_get_scratch(dyn);
+                VXOR_VV(q0, q0, q0, VECTOR_UNMASKED);
+                VMV_V_I(VMASK, 0b10);
+                SMREAD();
+                addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0);
+                VLUXEI64_V(v0, ed, q0, VECTOR_MASKED, VECTOR_NFIELD1);
+            }
+            break;
+        case 0x15:
+            INST_NAME("PUNPCKHQDQ Gx, Ex");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            // GX->q[0] = GX->q[1];
+            // GX->q[1] = EX->q[1];
+            GETGX_vector(v0, 1, VECTOR_SEW64);
+            if (MODREG) {
+                v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW64);
+                q0 == fpu_get_scratch(dyn);
+                VSLIDE1DOWN_VX(q0, xZR, v0, VECTOR_UNMASKED);
+                VMV_X_S(x4, q0);
+                if (v0 != v1) { VMV_V_V(v0, v1); }
+                VMV_S_X(v0, x4);
+            } else {
+                q0 = fpu_get_scratch(dyn);
+                VMV_V_I(VMASK, 0b10);
+                VSLIDE1DOWN_VX(v0, xZR, v0, VECTOR_UNMASKED);
+                SMREAD();
+                addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0);
+                VLE64_V(v0, ed, VECTOR_MASKED, VECTOR_NFIELD1);
+            }
+            break;
         case 0x1F:
             return 0;
         case 0x28:
@@ -66,6 +147,22 @@ 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 0x29:
+            INST_NAME("MOVAPD Ex, Gx");
+            nextop = F8;
+            GETG;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1);
+            v0 = sse_get_reg_vector(dyn, ninst, x1, gd, 0, dyn->vector_eew);
+            if (MODREG) {
+                ed = (nextop & 7) + (rex.b << 3);
+                v1 = sse_get_reg_empty_vector(dyn, ninst, x1, ed);
+                VMV_V_V(v1, v0);
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 0, 0);
+                VSE_V(v0, ed, dyn->vector_eew, VECTOR_UNMASKED, VECTOR_NFIELD1);
+                SMWRITE2();
+            }
+            break;
         case 0x2E:
         case 0x2F:
             return 0;
@@ -1217,7 +1314,7 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                 VSE_V(v1, ed, dyn->vector_eew, VECTOR_UNMASKED, VECTOR_NFIELD1);
             }
             break;
-        case 0xBE: return 0;
+        case 0xA3 ... 0xC1: return 0;
         case 0xC4:
             INST_NAME("PINSRW Gx, Ed, Ib");
             nextop = F8;