about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-02-21 17:50:08 +0800
committerGitHub <noreply@github.com>2025-02-21 10:50:08 +0100
commitc517d7196d270c164b642e3ec9f043b5e66c259d (patch)
treeb15a9cdc2128e58b27962c7b4378634b82bfd96e /src
parentcb42b3b00f3d999a10d44a0b48d806128ccf5cfa (diff)
downloadbox64-c517d7196d270c164b642e3ec9f043b5e66c259d.tar.gz
box64-c517d7196d270c164b642e3ec9f043b5e66c259d.zip
[RV64_DYNAREC] Added more opcodes (#2400)
* [RV64_DYNAREC] Added more 66 0F 38 opcodes for vector

* [RV64_DYNAREC] Added more opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_0.c3
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f_vector.c20
-rw-r--r--src/dynarec/rv64/dynarec_rv64_67.c21
-rw-r--r--src/dynarec/rv64/dynarec_rv64_67_vector.c23
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h11
-rw-r--r--src/dynarec/rv64/dynarec_rv64_pass0.h2
6 files changed, 76 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_0.c b/src/dynarec/rv64/dynarec_rv64_00_0.c
index 4399c7c1..5172bf7a 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_0.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_0.c
@@ -478,6 +478,9 @@ uintptr_t dynarec64_00_0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             i64 = F32S;
             emit_sub32c(dyn, ninst, rex, xRAX, i64, x2, x3, x4, x5);
             break;
+        case 0x2E:
+            INST_NAME("CS:");
+            break;
         case 0x30:
             INST_NAME("XOR Eb, Gb");
             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
diff --git a/src/dynarec/rv64/dynarec_rv64_660f_vector.c b/src/dynarec/rv64/dynarec_rv64_660f_vector.c
index a339ccf2..f206d7d5 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f_vector.c
@@ -400,6 +400,16 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                     vector_vsetvli(dyn, ninst, x1, VECTOR_SEW16, VECTOR_LMUL1, 1);
                     VNSRL_WI(q0, v0, 1, VECTOR_UNMASKED);
                     break;
+                case 0x10:
+                    INST_NAME("PBLENDVB Gx, Ex");
+                    nextop = F8;
+                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1);
+                    GETGX_vector(q0, 1, VECTOR_SEW8);
+                    GETEX_vector(q1, 0, 0, VECTOR_SEW8);
+                    v0 = sse_get_reg_vector(dyn, ninst, x4, 0, 0, VECTOR_SEW8);
+                    VMSLT_VX(VMASK, v0, xZR, VECTOR_UNMASKED);
+                    VADD_VX(q0, q1, xZR, VECTOR_MASKED);
+                    break;
                 case 0x14:
                     INST_NAME("PBLENDVPS Gx, Ex");
                     nextop = F8;
@@ -589,6 +599,16 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                     vector_vsetvli(dyn, ninst, x1, VECTOR_SEW64, VECTOR_LMUL1, 1);
                     if (v0 != q0) VMV_V_V(q0, v0);
                     break;
+                case 0x29:
+                    INST_NAME("PCMPEQQ Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
+                    GETEX_vector(q1, 0, 0, VECTOR_SEW64);
+                    GETGX_vector(q0, 1, VECTOR_SEW64);
+                    VMSEQ_VV(VMASK, q0, q1, VECTOR_UNMASKED);
+                    VXOR_VV(q0, q0, q0, VECTOR_UNMASKED);
+                    VMERGE_VIM(q0, q0, 0b11111);
+                    break;
                 case 0x2B:
                     INST_NAME("PACKUSDW Gx, Ex");
                     nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c
index a42cc19e..eeedc831 100644
--- a/src/dynarec/rv64/dynarec_rv64_67.c
+++ b/src/dynarec/rv64/dynarec_rv64_67.c
@@ -29,8 +29,8 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 
     uint8_t opcode = F8;
     uint8_t nextop;
-    uint8_t gd, ed, wback, wb, wb1, wb2, gb, gb1, gb2, eb1, eb2;
-    int64_t fixedaddress;
+    uint8_t gd, ed, wback, wb, wb1, wb2, gback, gb, gb1, gb2, eb1, eb2;
+    int64_t fixedaddress, gdoffset;
     int unscaled;
     int8_t i8;
     uint8_t u8;
@@ -136,6 +136,23 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0x0F:
             opcode = F8;
             switch (opcode) {
+                case 0x11:
+                    switch (rep) {
+                        case 0:
+                            INST_NAME("MOVUPS Ex, Gx");
+                            nextop = F8;
+                            GETGX();
+                            GETEX32(x2, 0, 8);
+                            LD(x3, gback, gdoffset + 0);
+                            LD(x4, gback, gdoffset + 8);
+                            SD(x3, wback, fixedaddress + 0);
+                            SD(x4, wback, fixedaddress + 8);
+                            if (!MODREG) SMWRITE2();
+                            break;
+                        default:
+                            DEFAULT;
+                    }
+                    break;
                 case 0x2E:
                     // no special check...
                 case 0x2F:
diff --git a/src/dynarec/rv64/dynarec_rv64_67_vector.c b/src/dynarec/rv64/dynarec_rv64_67_vector.c
index 297893b0..23613308 100644
--- a/src/dynarec/rv64/dynarec_rv64_67_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_67_vector.c
@@ -66,7 +66,28 @@ uintptr_t dynarec64_67_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
             opcode = F8;
             switch (opcode) {
                 case 0x11:
-                    DEFAULT_VECTOR;
+                    switch (rep) {
+                        case 0:
+                            INST_NAME("MOVUPS Ex,Gx");
+                            nextop = F8;
+                            if (MODREG) {
+                                SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1);
+                                GETGX_vector(v0, 0, dyn->vector_eew);
+                                ed = (nextop & 7) + (rex.b << 3);
+                                v1 = sse_get_reg_empty_vector(dyn, ninst, x1, ed);
+                                VMV_V_V(v1, v0);
+                            } else {
+                                SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1); // unaligned!
+                                GETGX_vector(v0, 0, dyn->vector_eew);
+                                addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 0, 0);
+                                VSE_V(v0, ed, dyn->vector_eew, VECTOR_UNMASKED, VECTOR_NFIELD1);
+                                SMWRITE2();
+                            }
+                            break;
+                        default:
+                            DEFAULT;
+                    }
+                    break;
                 case 0x2E:
                 case 0x2F:
                     DEFAULT_VECTOR;
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 4c223b6b..1183feb7 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -474,6 +474,17 @@
         ed = 16;                                                                                 \
         addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, I12, D); \
     }
+#define GETEX32(a, D, I12)                                                                         \
+    if (MODREG) {                                                                                  \
+        ed = (nextop & 7) + (rex.b << 3);                                                          \
+        sse_forget_reg(dyn, ninst, x3, ed);                                                        \
+        fixedaddress = offsetof(x64emu_t, xmm[ed]);                                                \
+        wback = xEmu;                                                                              \
+    } else {                                                                                       \
+        SMREAD();                                                                                  \
+        ed = 16;                                                                                   \
+        addr = geted32(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, I12, D); \
+    }
 
 // Get GX as a quad (might use x1)
 #define GETGX_vector(a, w, sew)                 \
diff --git a/src/dynarec/rv64/dynarec_rv64_pass0.h b/src/dynarec/rv64/dynarec_rv64_pass0.h
index ed5b7b0b..3c675e33 100644
--- a/src/dynarec/rv64/dynarec_rv64_pass0.h
+++ b/src/dynarec/rv64/dynarec_rv64_pass0.h
@@ -74,7 +74,7 @@
     --dyn->size;                                                                                                          \
     *ok = -1;                                                                                                             \
     if (ninst) { dyn->insts[ninst - 1].x64.size = ip - dyn->insts[ninst - 1].x64.addr; }                                  \
-    if (BOX64ENV(dynarec_log) >= LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing) == 1) {                \
+    if (BOX64ENV(dynarec_log) >= LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing)) {                     \
         dynarec_log(LOG_NONE, "%p: Dynarec stopped because of %s Opcode ", (void*)ip, rex.is32bits ? "x86" : "x64");      \
         zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec;                                            \
         if (dec) {                                                                                                        \