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 23:08:50 +0800
committerGitHub <noreply@github.com>2024-10-10 17:08:50 +0200
commit9b733041af6affae2c47bc2a44dda41db3f82905 (patch)
tree718b2a54497c28d38ffc026ec6db4e16fe47d5d1 /src
parent9e01876747c5947a88b87a3e64c16e0e7cb170eb (diff)
downloadbox64-9b733041af6affae2c47bc2a44dda41db3f82905.tar.gz
box64-9b733041af6affae2c47bc2a44dda41db3f82905.zip
[RV64_DYNAREC] Added more opcodes for vector (#1918)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f20f_vector.c23
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f_vector.c82
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c6
3 files changed, 111 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_f20f_vector.c b/src/dynarec/rv64/dynarec_rv64_f20f_vector.c
index 33624385..1805b06d 100644
--- a/src/dynarec/rv64/dynarec_rv64_f20f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_f20f_vector.c
@@ -74,6 +74,29 @@ uintptr_t dynarec64_F20F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                 VMERGE_VVM(v0, v0, d0); // implies VMASK
             }
             break;
+        case 0x11:
+            INST_NAME("MOVSD Ex, Gx");
+            nextop = F8;
+            GETG;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            v0 = sse_get_reg_vector(dyn, ninst, x1, gd, 0, VECTOR_SEW64);
+            if (MODREG) {
+                ed = (nextop & 7) + (rex.b << 3);
+                d0 = sse_get_reg_vector(dyn, ninst, x1, ed, 1, 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 {
+                VMV_X_S(x4, v0);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
+                SD(x4, ed, fixedaddress);
+                SMWRITE2();
+            }
+            break;
         case 0x38:
             return 0;
         default: DEFAULT_VECTOR;
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f_vector.c b/src/dynarec/rv64/dynarec_rv64_f30f_vector.c
index 09f9821e..f9efddf6 100644
--- a/src/dynarec/rv64/dynarec_rv64_f30f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_f30f_vector.c
@@ -48,7 +48,89 @@ uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
     MAYUSE(j64);
 
     switch (opcode) {
+        case 0x10:
+            INST_NAME("MOVSS Gx, Ex");
+            nextop = F8;
+            GETG;
+            if (MODREG) {
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+                ed = (nextop & 7) + (rex.b << 3);
+                v0 = sse_get_reg_vector(dyn, ninst, x1, gd, 1, VECTOR_SEW32);
+                v1 = sse_get_reg_vector(dyn, ninst, x1, ed, 0, VECTOR_SEW32);
+                if (rv64_xtheadvector) {
+                    vector_loadmask(dyn, ninst, VMASK, 0b0001, 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, 0xF, 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 0x11:
+            INST_NAME("MOVSS Ex, Gx");
+            nextop = F8;
+            GETG;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+            v0 = sse_get_reg_vector(dyn, ninst, x1, gd, 0, VECTOR_SEW32);
+            if (MODREG) {
+                ed = (nextop & 7) + (rex.b << 3);
+                d0 = sse_get_reg_vector(dyn, ninst, x1, ed, 1, VECTOR_SEW32);
+                if (rv64_xtheadvector) {
+                    vector_loadmask(dyn, ninst, VMASK, 0b0001, x4, 1);
+                    VMERGE_VVM(v0, v0, v1); // implies VMASK
+                } else {
+                    VMV_X_S(x4, v1);
+                    VMV_S_X(v0, x4);
+                }
+            } else {
+                VMV_X_S(x4, v0);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
+                SW(x4, ed, fixedaddress);
+                SMWRITE2();
+            }
+            break;
         case 0x1E:
+            return 0;
+        case 0x2A:
+            INST_NAME("CVTSI2SS Gx, Ed");
+            nextop = F8;
+            GETED(0);
+            if (rex.w) {
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+                GETGX_vector(v0, 1, VECTOR_SEW64);
+                FCVTSL(v0, ed, RD_RNE);
+                if (rv64_xtheadvector) {
+                    v1 = fpu_get_scratch(dyn);
+                    VFMV_S_F(v1, v0);
+                    vector_loadmask(dyn, ninst, VMASK, 0b01, x4, 1);
+                    VMERGE_VVM(v0, v0, v1); // implies VMASK
+                } else {
+                    VFMV_S_F(v0, v0);
+                }
+            } else {
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+                GETGX_vector(v0, 1, VECTOR_SEW32);
+                FCVTSW(v0, ed, RD_RNE);
+                if (rv64_xtheadvector) {
+                    v1 = fpu_get_scratch(dyn);
+                    VFMV_S_F(v1, v0);
+                    vector_loadmask(dyn, ninst, VMASK, 0b0001, x4, 1);
+                    VMERGE_VVM(v0, v0, v1); // implies VMASK
+                } else {
+                    VFMV_S_F(v0, v0);
+                }
+            }
+            break;
         case 0x38:
         case 0xAE:
         case 0xB8:
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index faad4b1f..1d161eec 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -2752,6 +2752,12 @@ void vector_loadmask(dynarec_rv64_t* dyn, int ninst, int vreg, uint64_t imm, int
             return;
         } else if ((sew == VECTOR_SEW8 && vlmul == VECTOR_LMUL1) || (sew == VECTOR_SEW16 && vlmul == VECTOR_LMUL2)) {
             switch (imm) {
+                case 0b0000000000001111:
+                    vector_vsetvli(dyn, ninst, s1, VECTOR_SEW32, VECTOR_LMUL1, 1);
+                    MOV64x(s1, 0xFFFFFFFFFFFFFFFFULL);
+                    VMV_S_X(vreg, s1);
+                    vector_vsetvli(dyn, ninst, s1, sew, vlmul, multiple);
+                    return;
                 case 0b0000000011111111:
                     vector_vsetvli(dyn, ninst, s1, VECTOR_SEW64, VECTOR_LMUL1, 1);
                     MOV64x(s1, 0xFFFFFFFFFFFFFFFFULL);