about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-03-28 21:32:10 +0800
committerGitHub <noreply@github.com>2025-03-28 14:32:10 +0100
commit0a59695fb37315962168188a1db6d2685d09c6c2 (patch)
tree60f809b09dd50388497a355ae3ea69b317f6c0f9 /src
parentcfdeb3685cdfed402a01baa2fb693ef16f5ba7d7 (diff)
downloadbox64-0a59695fb37315962168188a1db6d2685d09c6c2.tar.gz
box64-0a59695fb37315962168188a1db6d2685d09c6c2.zip
[LA64_DYNAREC] Added more MMX opcodes (#2477)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_0f.c98
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h16
-rw-r--r--src/dynarec/la64/la64_emitter.h3
-rw-r--r--src/dynarec/la64/la64_printer.c8
4 files changed, 125 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c
index c94ad178..3ae7cffc 100644
--- a/src/dynarec/la64/dynarec_la64_0f.c
+++ b/src/dynarec/la64/dynarec_la64_0f.c
@@ -716,6 +716,27 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             // empty MMX, FPU now usable
             mmx_purgecache(dyn, ninst, 0, x1);
             break;
+        case 0x7E:
+            INST_NAME("MOVD Ed, Gm");
+            nextop = F8;
+            GETGM(v0);
+            if (MODREG) {
+                ed = TO_NAT((nextop & 0x07) + (rex.b << 3));
+                if (rex.w) {
+                    MOVFR2GR_D(ed, v0);
+                } else {
+                    MOVFR2GR_S(ed, v0);
+                    ZEROUP(ed);
+                }
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 1, 0);
+                if (rex.w)
+                    FST_D(v0, ed, fixedaddress);
+                else
+                    FST_S(v0, ed, fixedaddress);
+                SMWRITE2();
+            }
+            break;
 
 #define GO(GETFLAGS, NO, YES, NATNO, NATYES, F, I)                                          \
     READFLAGS_FUSION(F, x1, x2, x3, x4, x5);                                                \
@@ -1419,6 +1440,83 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             gd = TO_NAT((opcode & 7) + (rex.b << 3));
             REVBxw(gd, gd);
             break;
+        case 0xD1:
+             INST_NAME("PSRLW Gm, Em");
+             nextop = F8;
+             GETGM(d0);
+             GETEM(d1, 0);
+             v0 = fpu_get_scratch(dyn);
+             v1 = fpu_get_scratch(dyn);
+             VSLEI_DU(v0, d1, 15);
+             VREPLVEI_H(v1, d1, 0);
+             VSRL_H(d0, d0, v1);
+             VAND_V(d0, d0, v0);
+             break;
+         case 0xD2:
+             INST_NAME("PSRLD Gm, Em");
+             nextop = F8;
+             GETGM(d0);
+             GETEM(d1, 0);
+             v0 = fpu_get_scratch(dyn);
+             v1 = fpu_get_scratch(dyn);
+             VSLEI_DU(v0, d1, 31);
+             VREPLVEI_W(v1, d1, 0);
+             VSRL_W(d0, d0, v1);
+             VAND_V(d0, d0, v0);
+             break;
+         case 0xD3:
+             INST_NAME("PSRLQ Gm, Em");
+             nextop = F8;
+             GETGM(d0);
+             GETEM(d1, 0);
+             v0 = fpu_get_scratch(dyn);
+             VLDI(v0, 0b0110000111111); // broadcast 63 as 64bit imm
+             VSLE_DU(v0, d1, v0);
+             VSRL_D(d0, d0, d1);
+             VAND_V(d0, d0, v0);
+             break;
+         case 0xF1:
+             INST_NAME("PSLLW Gm,Em");
+             nextop = F8;
+             GETGM(d0);
+             GETEM(d1, 0);
+             v0 = fpu_get_scratch(dyn);
+             v1 = fpu_get_scratch(dyn);
+             VSLEI_DU(v0, d1, 15);
+             VREPLVEI_H(v1, d1, 0);
+             VSLL_H(d0, d0, v1);
+             VAND_V(d0, d0, v0);
+             break;
+         case 0xF2:
+             INST_NAME("PSLLD Gm,Em");
+             nextop = F8;
+             GETGM(d0);
+             GETEM(d1, 0);
+             v0 = fpu_get_scratch(dyn);
+             v1 = fpu_get_scratch(dyn);
+             VSLEI_DU(v0, d1, 31);
+             VREPLVEI_W(v1, d1, 0);
+             VSLL_W(d0, d0, v1);
+             VAND_V(d0, d0, v0);
+             break;
+         case 0xF3:
+             INST_NAME("PSLLQ Gm, Em");
+             nextop = F8;
+             GETGM(d0);
+             GETEM(d1, 0);
+             v0 = fpu_get_scratch(dyn);
+             VLDI(v0, 0b0110000111111); // broadcast 63 as 64bit imm
+             VSLE_DU(v0, d1, v0);
+             VSLL_D(d0, d0, d1);
+             VAND_V(d0, d0, v0);
+             break;
+        case 0xFC:
+            INST_NAME("PADDB Gm, Em");
+            nextop = F8;
+            GETGM(v0);
+            GETEM(v1, 0);
+            VADD_B(v0, v0, v1);
+            break;
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index 4f5e9b08..40568420 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -395,6 +395,22 @@
         MOVGR2FR_D(a, x2);                                                                   \
     }
 
+// Get GM, might use x1, x2 and x3
+#define GETGM(a)                 \
+    gd = ((nextop & 0x38) >> 3); \
+    a = mmx_get_reg(dyn, ninst, x1, x2, x3, gd)
+
+// Get EM, might use x1, x2 and x3
+#define GETEM(a, D)                                                                          \
+    if (MODREG) {                                                                            \
+        a = mmx_get_reg(dyn, ninst, x1, x2, x3, (nextop & 7));                               \
+    } else {                                                                                 \
+        SMREAD();                                                                            \
+        addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D); \
+        a = fpu_get_scratch(dyn);                                                            \
+        FLD_D(a, ed, fixedaddress);                                                          \
+    }
+
 // Write gb (gd) back to original register / memory, using s1 as scratch
 #define GBBACK() BSTRINS_D(gb1, gd, gb2 + 7, gb2);
 
diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h
index 54240f96..39e53ff9 100644
--- a/src/dynarec/la64/la64_emitter.h
+++ b/src/dynarec/la64/la64_emitter.h
@@ -1436,6 +1436,9 @@ LSX instruction starts with V, LASX instruction starts with XV.
 #define VSLE_HU(vd, vj, vk)          EMIT(type_3R(0b01110000000001001, vk, vj, vd))
 #define VSLE_WU(vd, vj, vk)          EMIT(type_3R(0b01110000000001010, vk, vj, vd))
 #define VSLE_DU(vd, vj, vk)          EMIT(type_3R(0b01110000000001011, vk, vj, vd))
+#define VSLEI_BU(vd, vj, imm5)       EMIT(type_2RI5(0b01110010100001000, imm5, vj, vd))
+#define VSLEI_HU(vd, vj, imm5)       EMIT(type_2RI5(0b01110010100001001, imm5, vj, vd))
+#define VSLEI_WU(vd, vj, imm5)       EMIT(type_2RI5(0b01110010100001010, imm5, vj, vd))
 #define VSLEI_DU(vd, vj, imm5)       EMIT(type_2RI5(0b01110010100001011, imm5, vj, vd))
 #define VSLT_B(vd, vj, vk)           EMIT(type_3R(0b01110000000001100, vk, vj, vd))
 #define VSLT_H(vd, vj, vk)           EMIT(type_3R(0b01110000000001101, vk, vj, vd))
diff --git a/src/dynarec/la64/la64_printer.c b/src/dynarec/la64/la64_printer.c
index c88b95ba..93aab1a3 100644
--- a/src/dynarec/la64/la64_printer.c
+++ b/src/dynarec/la64/la64_printer.c
@@ -691,6 +691,14 @@ const char* la64_print(uint32_t opcode, uintptr_t addr)
         snprintf(buff, sizeof(buff), "%-15s %s, %s, %s", "FCOPYSIGN.D", Ft[Rd], Ft[Rj], Ft[Rk]);
         return buff;
     }
+    if (isMask(opcode, "0000000100010100100101jjjjjddddd", &a)) {
+        snprintf(buff, sizeof(buff), "%-15s %s, %s", "FMOV.S", Ft[Rd], Ft[Rj]);
+        return buff;
+    }
+    if (isMask(opcode, "0000000100010100100110jjjjjddddd", &a)) {
+        snprintf(buff, sizeof(buff), "%-15s %s, %s", "FMOV.D", Ft[Rd], Ft[Rj]);
+        return buff;
+    }
     if (isMask(opcode, "0000000100010100101001jjjjjddddd", &a)) {
         snprintf(buff, sizeof(buff), "%-15s %s, %s", "MOVGR2FR.W", Ft[Rd], Xt[Rj]);
         return buff;