about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-09-11 20:26:50 +0800
committerGitHub <noreply@github.com>2024-09-11 14:26:50 +0200
commit6b6d20732e6e93066095261f5c3c7a2146668c99 (patch)
tree980d4479bab91aa510c37bc1e03b2f2c091ba326 /src
parent4d60b75240ef44b7b15b73dda5c45b6aabdbb7e7 (diff)
downloadbox64-6b6d20732e6e93066095261f5c3c7a2146668c99.tar.gz
box64-6b6d20732e6e93066095261f5c3c7a2146668c99.zip
[RV64_DYNAREC] Added more 0F opcodes for vector (#1817)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f_vector.c40
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h12
2 files changed, 51 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
index 6de7eaef..b3e3a7d6 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
@@ -42,7 +42,7 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
     int q0, q1;
     int d0, d1;
     int s0, s1;
-    uint64_t tmp64u;
+    uint64_t tmp64u0, tmp64u1;
     int64_t j64;
     int64_t fixedaddress, gdoffset;
     int unscaled;
@@ -116,6 +116,23 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 VLUXEI64_V(v0, ed, q0, VECTOR_MASKED, VECTOR_NFIELD1);
             }
             break;
+        case 0x28:
+            INST_NAME("MOVAPS Gx, Ex");
+            nextop = F8;
+            GETG;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1);
+            if (MODREG) {
+                ed = (nextop & 7) + (rex.b << 3);
+                v1 = sse_get_reg_vector(dyn, ninst, x1, ed, 0, dyn->vector_eew);
+                v0 = sse_get_reg_empty_vector(dyn, ninst, x1, gd);
+                VMV_V_V(v0, v1);
+            } else {
+                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);
+                VLE_V(v0, ed, dyn->vector_eew, VECTOR_UNMASKED, VECTOR_NFIELD1);
+            }
+            break;
         case 0x29:
             INST_NAME("MOVAPS Ex, Gx");
             nextop = F8;
@@ -131,6 +148,27 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 SMWRITE2();
             }
             break;
+        case 0xC6:
+            INST_NAME("SHUFPS Gx, Ex, Ib");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+            GETGX_vector(v0, 1, VECTOR_SEW32);
+            GETEX_vector(v1, 0, 1, VECTOR_SEW32);
+            u8 = F8;
+            q0 = fpu_get_scratch(dyn);
+            d0 = fpu_get_scratch(dyn);
+            d1 = fpu_get_scratch(dyn);
+            tmp64u0 = (((u8 >> 2) & 3) << 16) | (u8 & 3);
+            VECTOR_SPLAT_IMM(q0, tmp64u0, x4);
+            VRGATHEREI16_VV(d0, q0, v0, VECTOR_UNMASKED);
+            tmp64u1 = (((u8 >> 6) & 3) << 16) | ((u8 >> 4) & 3);
+            if (tmp64u1 != tmp64u0) {
+                VECTOR_SPLAT_IMM(q0, tmp64u1, x4);
+            }
+            VRGATHEREI16_VV(d1, q0, v1, VECTOR_UNMASKED);
+            VMV_V_V(v0, d0);
+            VSLIDEUP_VI(v0, 2, d1, VECTOR_UNMASKED);
+            break;
         case 0x00 ... 0x0F:
         case 0x18:
         case 0x1F:
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 345b3c0f..2acd1810 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -1795,4 +1795,16 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
         break;                                                                       \
     }
 
+#define VECTOR_SPLAT_IMM(vreg, imm, s1)                 \
+    do {                                                \
+        if (imm == 0) {                                 \
+            VXOR_VV(vreg, vreg, vreg, VECTOR_UNMASKED); \
+        } else if ((imm & 0xf) == imm) {                \
+            VMV_V_I(vreg, imm);                         \
+        } else {                                        \
+            MOV64x(s1, imm);                            \
+            VMV_V_X(vreg, s1);                          \
+        }                                               \
+    } while (0)
+
 #endif //__DYNAREC_RV64_HELPER_H__