about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f_vector.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
index 7429c7eb..41e91486 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
@@ -631,6 +631,30 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
             VAND_VX(q0, v0, x3, VECTOR_UNMASKED);
             VXOR_VV(v0, v0, q0, VECTOR_UNMASKED);
             break;
+        case 0xD8:
+        case 0xD9:
+            if (opcode == 0xD8) {
+                INST_NAME("PSUBUSB Gm, Em");
+                u8 = VECTOR_SEW8;
+            } else {
+                INST_NAME("PSUBUSW Gm, Em");
+                u8 = VECTOR_SEW16;
+            }
+            nextop = F8;
+            GETGM_vector(v0);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            GETEM_vector(v1, 0);
+            SET_ELEMENT_WIDTH(x1, u8, 1);
+            VSSUBU_VV(v0, v0, v1, VECTOR_UNMASKED);
+            break;
+        case 0xDB:
+            INST_NAME("PAND Gm, Em");
+            nextop = F8;
+            GETGM_vector(v0);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            GETEM_vector(v1, 0);
+            VAND_VV(v0, v0, v1, VECTOR_UNMASKED);
+            break;
         case 0xDC:
         case 0xDD:
             if (opcode == 0xDC) {
@@ -647,6 +671,41 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
             SET_ELEMENT_WIDTH(x1, u8, 1);
             VSADDU_VV(v0, v0, v1, VECTOR_UNMASKED);
             break;
+        case 0xDF:
+            INST_NAME("PANDN Gm, Em");
+            nextop = F8;
+            GETGM_vector(v0);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            GETEM_vector(v1, 0);
+            VXOR_VI(v0, v0, 0x1F, VECTOR_UNMASKED);
+            VAND_VV(v0, v0, v1, VECTOR_UNMASKED);
+            break;
+        case 0xE8:
+            INST_NAME("PSUBSB Gm, Em");
+            nextop = F8;
+            GETGM_vector(v0);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            GETEM_vector(v1, 0);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1);
+            VSSUB_VV(v0, v0, v1, VECTOR_UNMASKED);
+            break;
+        case 0xE9:
+            INST_NAME("PSUBSW Gm, Em");
+            nextop = F8;
+            GETGM_vector(v0);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            GETEM_vector(v1, 0);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW16, 1);
+            VSSUB_VV(v0, v0, v1, VECTOR_UNMASKED);
+            break;
+        case 0xEB:
+            INST_NAME("POR Gm, Em");
+            nextop = F8;
+            GETGM_vector(v0);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            GETEM_vector(v1, 0);
+            VOR_VV(v0, v0, v1, VECTOR_UNMASKED);
+            break;
         case 0xEC:
             INST_NAME("PADDSB Gm, Em");
             nextop = F8;
@@ -665,6 +724,78 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
             SET_ELEMENT_WIDTH(x1, VECTOR_SEW16, 1);
             VSADD_VV(v0, v0, v1, VECTOR_UNMASKED);
             break;
+        case 0xEF:
+            INST_NAME("PXOR Gm, Em");
+            nextop = F8;
+            GETG;
+            if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1);
+                // special case
+                q0 = mmx_get_reg_empty_vector(dyn, ninst, x1, x2, x3, gd);
+                VXOR_VV(q0, q0, q0, VECTOR_UNMASKED);
+            } else {
+                GETGM_vector(v0);
+                SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+                GETEM_vector(v1, 0);
+                VXOR_VV(v0, v0, v1, VECTOR_UNMASKED);
+            }
+            break;
+        case 0xF1:
+        case 0xF2:
+        case 0xF3:
+            if (opcode == 0xF1) {
+                INST_NAME("PSLLW Gm, Em");
+                u8 = VECTOR_SEW16;
+                i32 = 16;
+            } else if (opcode == 0xF2) {
+                INST_NAME("PSLLD Gm, Em");
+                u8 = VECTOR_SEW32;
+                i32 = 32;
+            } else {
+                INST_NAME("PSLLQ Gm, Em");
+                u8 = VECTOR_SEW64;
+                i32 = 64;
+            }
+            nextop = F8;
+            q0 = fpu_get_scratch(dyn);
+            GETGM_vector(v0);
+            SET_ELEMENT_WIDTH(x1, u8, 1);
+            if (MODREG) {
+                v1 = mmx_get_reg_vector(dyn, ninst, x1, x2, x3, (nextop & 7));
+                VMV_X_S(x4, v1);
+            } else {
+                SMREAD();
+                addr = geted(dyn, addr, ninst, nextop, &wback, v1, x3, &fixedaddress, rex, NULL, 1, 0);
+                LD(x4, wback, fixedaddress);
+            }
+            SLTIU(x3, x4, i32);
+            SUB(x3, xZR, x3);
+            NOT(x3, x3); // mask
+            VSLL_VX(v0, v0, x4, VECTOR_UNMASKED);
+            VAND_VX(q0, v0, x3, VECTOR_UNMASKED);
+            VXOR_VV(v0, v0, q0, VECTOR_UNMASKED);
+            break;
+        case 0xF8 ... 0xFB:
+            nextop = F8;
+            if (opcode == 0xF8) {
+                INST_NAME("PSUBB Gm, Em");
+                u8 = VECTOR_SEW8;
+            } else if (opcode == 0xF9) {
+                INST_NAME("PSUBW Gm, Em");
+                u8 = VECTOR_SEW16;
+            } else if (opcode == 0xFA) {
+                INST_NAME("PSUBD Gm, Em");
+                u8 = VECTOR_SEW32;
+            } else {
+                INST_NAME("PSUBQ Gm, Em");
+                u8 = VECTOR_SEW64;
+            }
+            GETGM_vector(v0);
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+            GETEM_vector(v1, 0);
+            SET_ELEMENT_WIDTH(x1, u8, 1);
+            VSUB_VV(v0, v0, v1, VECTOR_UNMASKED);
+            break;
         case 0xFC ... 0xFE:
             nextop = F8;
             if (opcode == 0xFC) {