about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorphorcys <phorcys@126.com>2025-04-14 15:14:34 +0800
committerGitHub <noreply@github.com>2025-04-14 09:14:34 +0200
commit1bd471bf135dce48949975eeee89b3324ee75b51 (patch)
treeec59867f8a1c151e04558e457a97e85bcdcad633 /src
parent21911620c8e983152878795f9939e52a38603f75 (diff)
downloadbox64-1bd471bf135dce48949975eeee89b3324ee75b51.tar.gz
box64-1bd471bf135dce48949975eeee89b3324ee75b51.zip
[LA64_DYNAREC] Add mmx related mov op (#2526)
* [LA64_DYNAREC] Add SSE2's MOVQ2DQ/MOVDQ2Q mmx op

* [LA64_DYNAREC] Add mmx mov ops.
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_0f.c58
-rw-r--r--src/dynarec/la64/dynarec_la64_660f.c14
-rw-r--r--src/dynarec/la64/dynarec_la64_f20f.c7
-rw-r--r--src/dynarec/la64/dynarec_la64_f30f.c38
4 files changed, 102 insertions, 15 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c
index 18714f81..33843341 100644
--- a/src/dynarec/la64/dynarec_la64_0f.c
+++ b/src/dynarec/la64/dynarec_la64_0f.c
@@ -692,6 +692,29 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 VFMAX_S(v0, v0, v1);
             }
             break;
+        case 0x6E:
+            INST_NAME("MOVD Gm, Ed");
+            nextop = F8;
+            GETG;
+            v0 = mmx_get_reg_empty(dyn, ninst, x1, x2, x3, gd);
+            if (MODREG) {
+                ed = TO_NAT(nextop & 7);
+                if (rex.w) {
+                    MOVGR2FR_D(v0, ed);
+                } else {
+                    MOVGR2FR_W(v0, ed);
+                    MOVGR2FRH_W(v0, xZR);
+                }
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
+                if (rex.w) {
+                    FLD_D(v0, wback, fixedaddress);
+                } else {
+                    FLD_S(v0, wback, fixedaddress);
+                    MOVGR2FRH_W(v0, xZR);
+                }
+            }
+            break;
         case 0x6F:
             INST_NAME("MOVQ Gm, Em");
             nextop = F8;
@@ -1489,6 +1512,16 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             GETEM(q1, 0);
             VMUL_H(q0, q0, q1);
             break;
+        case 0xD7:
+            nextop = F8;
+            INST_NAME("PMOVMSKB Gd, Em");
+            GETGD;
+            v0 = fpu_get_scratch(dyn);
+            GETEM(v1, 0);
+            VMSKLTZ_B(v0, v1);
+            MOVFR2GR_D(x1, v0);
+            BSTRPICK_D(gd, x1, 7, 0);
+            break;
         case 0xD8:
             INST_NAME("PSUBUSB Gm, Em");
             nextop = F8;
@@ -1538,6 +1571,19 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             GETEM(v1, 0);
             VMUH_H(v0, v0, v1);
             break;
+        case 0xE7:
+            INST_NAME("MOVNTQ Em, Gm");
+            nextop = F8;
+            GETGM(v0);
+            if (MODREG) {
+                v1 = mmx_get_reg_empty(dyn, ninst, x1, x2, x3, nextop & 7);
+                FMOV_D(v1, v0);
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 1, 0);
+                FST_D(v0, ed, fixedaddress);
+                SMWRITE2();
+            }
+            break;
         case 0xE8:
             INST_NAME("PSUBSB Gm,Em");
             nextop = F8;
@@ -1626,6 +1672,18 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             VMADDWOD_W_H(q0, v0, v1);
             VBSLL_V(v0, q0, 0);
             break;
+        case 0xF7:
+            INST_NAME("MASKMOVQ Gm, Em");
+            nextop = F8;
+            GETGM(v0);
+            GETEM(v1, 0);
+            q0 = fpu_get_scratch(dyn);
+            q1 = fpu_get_scratch(dyn);
+            VSLTI_B(q1, v1, 0); // q1 = byte selection mask
+            FLD_D(q0, xRDI, 0);
+            VBITSEL_V(q0, q0, v0, q1); // sel v0 if mask is 1
+            FST_D(q0, xRDI, 0);
+            break;
         case 0xF8:
             INST_NAME("PSUBB Gm, Em");
             nextop = F8;
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c
index 8fe3981a..fc375fd7 100644
--- a/src/dynarec/la64/dynarec_la64_660f.c
+++ b/src/dynarec/la64/dynarec_la64_660f.c
@@ -208,6 +208,20 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 SMWRITE2();
             }
             break;
+        case 0x2B:
+            INST_NAME("MOVNTPD Ex,Gx");
+            nextop = F8;
+            GETG;
+            v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
+            if (MODREG) {
+                ed = (nextop & 7) + (rex.b << 3);
+                v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
+                VOR_V(v1, v0, v0);
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 1, 0);
+                VST(v0, ed, fixedaddress);
+            }
+            break;
         case 0x2E:
             // no special check...
         case 0x2F:
diff --git a/src/dynarec/la64/dynarec_la64_f20f.c b/src/dynarec/la64/dynarec_la64_f20f.c
index 33461a66..63cf78ea 100644
--- a/src/dynarec/la64/dynarec_la64_f20f.c
+++ b/src/dynarec/la64/dynarec_la64_f20f.c
@@ -385,6 +385,13 @@ uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             VEXTRINS_W(q0, v0, 0);
             VEXTRINS_W(q0, v0, 0b00100010);
             break;
+        case 0xD6:
+            INST_NAME("MOVDQ2Q Gm, Ex");
+            nextop = F8;
+            GETGM(v0);
+            GETEXSD(v1, 0, 0);
+            FMOV_D(v0, v1);
+            break;
         case 0xE6: // TODO: !fastround
             INST_NAME("CVTPD2DQ Gx, Ex");
             nextop = F8;
diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c
index 523f667d..22078287 100644
--- a/src/dynarec/la64/dynarec_la64_f30f.c
+++ b/src/dynarec/la64/dynarec_la64_f30f.c
@@ -51,7 +51,7 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             INST_NAME("MOVSS Gx, Ex");
             nextop = F8;
             GETG;
-            if(MODREG) {
+            if (MODREG) {
                 v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
                 v1 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0);
             } else {
@@ -104,7 +104,7 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETED(0);
             d1 = fpu_get_scratch(dyn);
             MOVGR2FR_D(d1, ed);
-            if(rex.w) {
+            if (rex.w) {
                 FFINT_S_L(d1, d1);
             } else {
                 FFINT_S_W(d1, d1);
@@ -183,18 +183,18 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             VEXTRINS_W(v0, d1, 0);
             break;
         case 0x52:
-             INST_NAME("RSQRTSS Gx, Ex");
-             nextop = F8;
-             GETGX(v0, 1);
-             GETEXSS(v1, 0, 0);
-             q0 = fpu_get_scratch(dyn);
-             q1 = fpu_get_scratch(dyn);
-             LU12I_W(x3, 0x3f800); // 1.0f
-             MOVGR2FR_W(q0, x3);
-             FSQRT_S(q1, v1);
-             FDIV_S(q0, q0, q1);
-             VEXTRINS_W(v0, q0, 0);
-             break;
+            INST_NAME("RSQRTSS Gx, Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEXSS(v1, 0, 0);
+            q0 = fpu_get_scratch(dyn);
+            q1 = fpu_get_scratch(dyn);
+            LU12I_W(x3, 0x3f800); // 1.0f
+            MOVGR2FR_W(q0, x3);
+            FSQRT_S(q1, v1);
+            FDIV_S(q0, q0, q1);
+            VEXTRINS_W(v0, q0, 0);
+            break;
         case 0x53:
             INST_NAME("RCPSS Gx, Ex");
             nextop = F8;
@@ -358,7 +358,7 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             INST_NAME("MOVDQU Ex,Gx");
             nextop = F8;
             GETGX(v0, 0);
-            if(MODREG) {
+            if (MODREG) {
                 v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop & 7) + (rex.b << 3));
                 VOR_V(v1, v0, v0);
             } else {
@@ -480,6 +480,14 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             MOVGR2FR_W(q1, x2);
             VEXTRINS_W(v0, q1, 0);
             break;
+        case 0xD6:
+            INST_NAME("MOVQ2DQ Gx, Em");
+            nextop = F8;
+            GETGX_empty(v0);
+            GETEM(v1, 0);
+            VXOR_V(v0, v0, v0);
+            VEXTRINS_D(v0, v1, VEXTRINS_IMM_4_0(0, 0));
+            break;
         case 0xE6:
             INST_NAME("CVTDQ2PD Gx, Ex");
             nextop = F8;