about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-10-10 21:30:41 +0800
committerGitHub <noreply@github.com>2024-10-10 15:30:41 +0200
commit88ccd7f53742c498f6a90c5f25ab525ca2cc6a1c (patch)
tree773418638b53b858daf650e9bda4b043166d6eea /src
parentc6cd9ceb759ae28c84bc203ea6989984d972ca91 (diff)
downloadbox64-88ccd7f53742c498f6a90c5f25ab525ca2cc6a1c.tar.gz
box64-88ccd7f53742c498f6a90c5f25ab525ca2cc6a1c.zip
[RV64_DYNAREC] Added 1 more opcode for vector, some fixes too (#1917)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f_vector.c36
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f20f_vector.c28
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c13
3 files changed, 49 insertions, 28 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
index 4888aa17..268023c9 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
@@ -98,16 +98,9 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
             nextop = F8;
             if (MODREG) {
                 INST_NAME("MOVHLPS Gx, Ex");
-                if (MODREG) {
-                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
-                    GETGX_vector(v0, 1, VECTOR_SEW64);
-                    GETEX_vector(v1, 0, 0, VECTOR_SEW64);
-                } else {
-                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1); // unaligned!
-                    GETGX_vector(v0, 1, VECTOR_SEW8);
-                    GETEX_vector(v1, 0, 0, VECTOR_SEW8);
-                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
-                }
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+                GETGX_vector(v0, 1, VECTOR_SEW64);
+                GETEX_vector(v1, 0, 0, VECTOR_SEW64);
                 q0 = fpu_get_scratch(dyn);
                 VSLIDEDOWN_VI(q0, v1, 1, VECTOR_UNMASKED);
                 if (rv64_xtheadvector) {
@@ -119,23 +112,12 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 }
             } else {
                 INST_NAME("MOVLPS Gx, Ex");
-                if (MODREG) {
-                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
-                    GETGX_vector(v0, 1, VECTOR_SEW64);
-                    GETEX_vector(v1, 0, 0, VECTOR_SEW64);
-                } else {
-                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1); // unaligned!
-                    GETGX_vector(v0, 1, VECTOR_SEW8);
-                    GETEX_vector(v1, 0, 0, VECTOR_SEW8);
-                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
-                }
-                if (rv64_xtheadvector) {
-                    vector_loadmask(dyn, ninst, VMASK, 0b01, x4, 1);
-                    VMERGE_VVM(v0, v0, v1); // implies VMASK
-                } else {
-                    VMV_X_S(x4, v1);
-                    VMV_S_X(v0, x4);
-                }
+                SMREAD();
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1); // unaligned!
+                GETGX_vector(v0, 1, VECTOR_SEW8);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 0);
+                vector_loadmask(dyn, ninst, VMASK, 0xFF, x4, 1);
+                VLE8_V(v0, ed, VECTOR_MASKED, VECTOR_NFIELD1);
             }
             break;
         case 0x16:
diff --git a/src/dynarec/rv64/dynarec_rv64_f20f_vector.c b/src/dynarec/rv64/dynarec_rv64_f20f_vector.c
index 47747125..33624385 100644
--- a/src/dynarec/rv64/dynarec_rv64_f20f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_f20f_vector.c
@@ -46,6 +46,34 @@ uintptr_t dynarec64_F20F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
     MAYUSE(v1);
 
     switch (opcode) {
+        case 0x10:
+            INST_NAME("MOVSD Gx, Ex");
+            nextop = F8;
+            GETG;
+            if (MODREG) {
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+                ed = (nextop & 7) + (rex.b << 3);
+                v0 = sse_get_reg_vector(dyn, ninst, x1, gd, 1, VECTOR_SEW64);
+                v1 = sse_get_reg_vector(dyn, ninst, x1, ed, 0, VECTOR_SEW64);
+                if (rv64_xtheadvector) {
+                    vector_loadmask(dyn, ninst, VMASK, 0b01, x4, 1);
+                    VMERGE_VVM(v0, v0, v1); // implies VMASK
+                } else {
+                    VMV_X_S(x4, v1);
+                    VMV_S_X(v0, x4);
+                }
+            } else {
+                SMREAD();
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1);
+                v0 = sse_get_reg_empty_vector(dyn, ninst, x1, gd);
+                d0 = fpu_get_scratch(dyn);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 0);
+                vector_loadmask(dyn, ninst, VMASK, 0xFF, x4, 1);
+                VLE8_V(d0, ed, VECTOR_MASKED, VECTOR_NFIELD1);
+                VXOR_VV(v0, v0, v0, VECTOR_UNMASKED);
+                VMERGE_VVM(v0, v0, d0); // implies VMASK
+            }
+            break;
         case 0x38:
             return 0;
         default: DEFAULT_VECTOR;
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index 3dbe24f2..faad4b1f 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -2777,9 +2777,20 @@ void vector_loadmask(dynarec_rv64_t* dyn, int ninst, int vreg, uint64_t imm, int
     } else {
         if (imm <= 0xF && (dyn->vector_eew == VECTOR_SEW32 || dyn->vector_eew == VECTOR_SEW64)) {
             VMV_V_I(vreg, imm);
+        } else if (dyn->vector_eew == VECTOR_SEW8 && imm >= 0xFF) {
+            if ((imm > 0xFF) && (imm & 0xFF) == (imm >> 8)) {
+                MOV64x(s1, imm);
+                VMV_V_X(vreg, s1);
+            } else if (imm > 0xFF) {
+                abort(); // not used (yet)
+            } else {
+                MOV64x(s1, imm);
+                VXOR_VV(vreg, vreg, vreg, VECTOR_UNMASKED);
+                VMV_S_X(vreg, s1);
+            }
         } else {
             MOV64x(s1, imm);
-            VMV_V_X(vreg, s1);
+            VMV_S_X(vreg, s1);
         }
     }
 #endif