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 16:03:19 +0800
committerGitHub <noreply@github.com>2025-02-21 09:03:19 +0100
commitcb42b3b00f3d999a10d44a0b48d806128ccf5cfa (patch)
treede7c93e160fd813450d8abee29696c8e689d39a8 /src
parent61362b06ecea0af9164f1a70992ad610633531a0 (diff)
downloadbox64-cb42b3b00f3d999a10d44a0b48d806128ccf5cfa.tar.gz
box64-cb42b3b00f3d999a10d44a0b48d806128ccf5cfa.zip
[RV64_DYNAREC] Added more MMX opcodes for vector and fixes too (#2399)
* [RV64_DYNAREC] Fixed fallback to scalar messge

* [RV64_DYNAREC] Added more MMX opcodes for vector and fixes too
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f_vector.c114
-rw-r--r--src/dynarec/rv64/dynarec_rv64_pass3.h28
2 files changed, 124 insertions, 18 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
index 40a5d8df..ddcf0b80 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
@@ -289,6 +289,9 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 SMWRITE2();
             }
             break;
+        case 0x2E:
+        case 0x2F:
+            return 0;
         case 0x50:
             INST_NAME("MOVMSKPS Gd, Ex");
             nextop = F8;
@@ -683,13 +686,105 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 VMV_S_X(v0, x4);
             }
             break;
+        case 0x71:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 2:
+                    INST_NAME("PSRLW Em, Ib");
+                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW16, 1);
+                    GETEM_vector(q0, 1);
+                    u8 = F8;
+                    if (u8 > 15) {
+                        VXOR_VV(q0, q0, q0, VECTOR_UNMASKED);
+                        PUTEM_vector(q0);
+                    } else if (u8) {
+                        MOV64x(x4, u8);
+                        VSRL_VX(q0, q0, x4, VECTOR_UNMASKED);
+                        PUTEM_vector(q0);
+                    }
+                    break;
+                case 4:
+                    INST_NAME("PSRAW Em, Ib");
+                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW16, 1);
+                    GETEM_vector(q0, 1);
+                    u8 = F8;
+                    if (u8 > 15) u8 = 15;
+                    if (u8) {
+                        MOV64x(x4, u8);
+                        VSRA_VX(q0, q0, x4, VECTOR_UNMASKED);
+                        PUTEM_vector(q0);
+                    }
+                    break;
+                case 6:
+                    INST_NAME("PSLLW Em, Ib");
+                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW16, 1);
+                    GETEM_vector(q0, 1);
+                    u8 = F8;
+                    if (u8 > 15) {
+                        VXOR_VV(q0, q0, q0, VECTOR_UNMASKED);
+                        PUTEM_vector(q0);
+                    } else if (u8) {
+                        MOV64x(x4, u8);
+                        VSLL_VX(q0, q0, x4, VECTOR_UNMASKED);
+                        PUTEM_vector(q0);
+                    }
+                    break;
+                default: DEFAULT_VECTOR;
+            }
+            break;
+        case 0x72:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 2:
+                    INST_NAME("PSRLD Em, Ib");
+                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+                    GETEM_vector(q0, 1);
+                    u8 = F8;
+                    if (u8 > 31) {
+                        VXOR_VV(q0, q0, q0, VECTOR_UNMASKED);
+                        PUTEM_vector(q0);
+                    } else if (u8) {
+                        MOV64x(x4, u8);
+                        VSRL_VX(q0, q0, x4, VECTOR_UNMASKED);
+                        PUTEM_vector(q0);
+                    }
+                    break;
+                case 4:
+                    INST_NAME("PSRAD Em, Ib");
+                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+                    GETEM_vector(q0, 1);
+                    u8 = F8;
+                    if (u8 > 31) u8 = 31;
+                    if (u8) {
+                        MOV64x(x4, u8);
+                        VSRA_VX(q0, q0, x4, VECTOR_UNMASKED);
+                    }
+                    PUTEM_vector(q0);
+                    break;
+                case 6:
+                    INST_NAME("PSLLD Em, Ib");
+                    SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+                    GETEM_vector(q0, 1);
+                    u8 = F8;
+                    if (u8 > 31) {
+                        VXOR_VV(q0, q0, q0, VECTOR_UNMASKED);
+                        PUTEM_vector(q0);
+                    } else if (u8) {
+                        MOV64x(x4, u8);
+                        VSLL_VX(q0, q0, x4, VECTOR_UNMASKED);
+                        PUTEM_vector(q0);
+                    }
+                    break;
+                default: DEFAULT_VECTOR;
+            }
+            break;
         case 0x73:
             nextop = F8;
             switch ((nextop >> 3) & 7) {
                 case 2:
                     INST_NAME("PSRLQ Em, Ib");
                     SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
-                    GETEM_vector(q0, 0);
+                    GETEM_vector(q0, 1);
                     u8 = F8;
                     if (u8) {
                         if (u8 > 63) {
@@ -704,7 +799,7 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 case 6:
                     INST_NAME("PSLLQ Em, Ib");
                     SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
-                    GETEM_vector(q0, 0);
+                    GETEM_vector(q0, 1);
                     u8 = F8;
                     if (u8) {
                         if (u8 > 63) {
@@ -861,7 +956,7 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 VMV_X_S(x4, v1);
             } else {
                 SMREAD();
-                addr = geted(dyn, addr, ninst, nextop, &wback, v1, x3, &fixedaddress, rex, NULL, 1, 0);
+                addr = geted(dyn, addr, ninst, nextop, &wback, x1, x3, &fixedaddress, rex, NULL, 1, 0);
                 LD(x4, wback, fixedaddress);
             }
             SET_ELEMENT_WIDTH(x1, u8, 1);
@@ -961,6 +1056,17 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
             SET_ELEMENT_WIDTH(x1, VECTOR_SEW16, 1);
             VMULH_VV(v0, v0, v1, VECTOR_UNMASKED);
             break;
+        case 0xE7:
+            INST_NAME("MOVNTQ Em, Gm");
+            nextop = F8;
+            if (MODREG) {
+                DEFAULT;
+            } else {
+                GETGM_vector(v0);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x3, &fixedaddress, rex, NULL, 1, 0);
+                PUTEM_vector(v0);
+            }
+            break;
         case 0xE8:
             INST_NAME("PSUBSB Gm, Em");
             nextop = F8;
@@ -1046,7 +1152,7 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 VMV_X_S(x4, v1);
             } else {
                 SMREAD();
-                addr = geted(dyn, addr, ninst, nextop, &wback, v1, x3, &fixedaddress, rex, NULL, 1, 0);
+                addr = geted(dyn, addr, ninst, nextop, &wback, x1, x3, &fixedaddress, rex, NULL, 1, 0);
                 LD(x4, wback, fixedaddress);
             }
             SET_ELEMENT_WIDTH(x1, u8, 1);
diff --git a/src/dynarec/rv64/dynarec_rv64_pass3.h b/src/dynarec/rv64/dynarec_rv64_pass3.h
index 4b92fd79..1fec3dcb 100644
--- a/src/dynarec/rv64/dynarec_rv64_pass3.h
+++ b/src/dynarec/rv64/dynarec_rv64_pass3.h
@@ -43,18 +43,18 @@
         FLD(A, x1, SPLIT12(val64offset));           \
     }
 
-#define DEFAULT_VECTOR                                                                                                    \
-    if (BOX64ENV(dynarec_log) >= LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing) == 2) {                \
-        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) {                                                                                                        \
-            dynarec_log_prefix(0, LOG_NONE, "%s", DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 1));                    \
-        } else {                                                                                                          \
-            dynarec_log_prefix(0, LOG_NONE, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", \
-                PKip(0), PKip(1), PKip(2), PKip(3), PKip(4), PKip(5), PKip(6), PKip(7), PKip(8), PKip(9),                 \
-                PKip(10), PKip(11), PKip(12), PKip(13), PKip(14));                                                        \
-        }                                                                                                                 \
-        printFunctionAddr(ip, " => ");                                                                                    \
-        dynarec_log_prefix(0, LOG_NONE, "\n");                                                                            \
-    }                                                                                                                     \
+#define DEFAULT_VECTOR                                                                                                                  \
+    if (BOX64ENV(dynarec_log) >= LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing) == 2) {                              \
+        dynarec_log(LOG_NONE, "%p: Dynarec fallback to scalar version because of %s Opcode ", (void*)ip, rex.is32bits ? "x86" : "x64"); \
+        zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec;                                                          \
+        if (dec) {                                                                                                                      \
+            dynarec_log_prefix(0, LOG_NONE, "%s", DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 1));                                  \
+        } else {                                                                                                                        \
+            dynarec_log_prefix(0, LOG_NONE, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",               \
+                PKip(0), PKip(1), PKip(2), PKip(3), PKip(4), PKip(5), PKip(6), PKip(7), PKip(8), PKip(9),                               \
+                PKip(10), PKip(11), PKip(12), PKip(13), PKip(14));                                                                      \
+        }                                                                                                                               \
+        printFunctionAddr(ip, " => ");                                                                                                  \
+        dynarec_log_prefix(0, LOG_NONE, "\n");                                                                                          \
+    }                                                                                                                                   \
     return 0