about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f_vector.c38
-rw-r--r--src/dynarec/rv64/dynarec_rv64_functions.h3
-rw-r--r--src/dynarec/rv64/dynarec_rv64_private.h9
3 files changed, 44 insertions, 6 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f_vector.c b/src/dynarec/rv64/dynarec_rv64_660f_vector.c
index 36b629a7..3155dfda 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f_vector.c
@@ -123,8 +123,44 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                     DEFAULT_VECTOR;
             }
             break;
+        case 0x6C:
+            INST_NAME("PUNPCKLQDQ 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);
+            q0 = fpu_get_scratch(dyn);
+            VXOR_VV(q0, q0, q0, VECTOR_UNMASKED);
+            VMV_V_I(VMASK, 0b10);
+            if (MODREG) {
+                v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW64);
+                if (v0 == v1) {
+                    // for vrgather.vv, cannot be overlapped
+                    v1 = fpu_get_scratch(dyn);
+                    VMV_V_V(v1, v0);
+                }
+                VRGATHER_VV(v0, q0, v1, VECTOR_MASKED);
+            } else {
+                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 0x6E:
-            return 0;
+            INST_NAME("MOVD Gx, Ed");
+            nextop = F8;
+            GETED(0);
+            GETGX_empty_vector(v0);
+            if (rex.w) {
+                SET_ELEMENT_WIDTH(x3, VECTOR_SEW64, 1);
+            } else {
+                SET_ELEMENT_WIDTH(x3, VECTOR_SEW32, 1);
+            }
+            VXOR_VV(v0, v0, v0, VECTOR_UNMASKED);
+            VMV_V_I(VMASK, 1);
+            VMERGE_VXM(v0, ed, v0);
+            break;
         case 0x6F:
             INST_NAME("MOVDQA Gx, Ex");
             nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_functions.h b/src/dynarec/rv64/dynarec_rv64_functions.h
index 41d01c4b..04cf7c47 100644
--- a/src/dynarec/rv64/dynarec_rv64_functions.h
+++ b/src/dynarec/rv64/dynarec_rv64_functions.h
@@ -6,7 +6,8 @@
 typedef struct x64emu_s x64emu_t;
 typedef struct dynarec_rv64_s dynarec_rv64_t;
 
-#define SCRATCH0    2
+#define SCRATCH0 3
+#define VMASK    0
 
 // Get an FPU scratch reg
 int fpu_get_scratch(dynarec_rv64_t* dyn);
diff --git a/src/dynarec/rv64/dynarec_rv64_private.h b/src/dynarec/rv64/dynarec_rv64_private.h
index 06312105..771e02d8 100644
--- a/src/dynarec/rv64/dynarec_rv64_private.h
+++ b/src/dynarec/rv64/dynarec_rv64_private.h
@@ -157,10 +157,11 @@ typedef struct dynarec_rv64_s {
     uint8_t             vector_eew; // effective element width
 } dynarec_rv64_t;
 
-// convert idx (0..24) to reg index (10..31 0..1)
-#define EXTREG(A)   (((A)+10)&31)
-// convert reg index (10..31 0..1) to idx (0..24)
-#define EXTIDX(A)   (((A)-10)&31)
+// v0 is hardware wired to vector mask register, which should be always reserved
+// convert idx (0..23) to reg index (10..31 1..2)
+#define EXTREG(A) (((A) + 10 + ((A) > 21)) & 31)
+// convert reg index (10..31 1..2) to idx (0..23)
+#define EXTIDX(A) (((A) - 10 - ((A) < 3)) & 31)
 
 void add_next(dynarec_rv64_t *dyn, uintptr_t addr);
 uintptr_t get_closest_next(dynarec_rv64_t *dyn, uintptr_t addr);