about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-12-10 15:16:24 +0800
committerGitHub <noreply@github.com>2023-12-10 08:16:24 +0100
commit486df332dd2da9ffb2c586417b1ad6f184218a16 (patch)
tree8ab712f3b5a1c1f57c285cb6ce33248a016066fc /src
parent8806c8ba8b9f8a34e666c30cc1139e55797a994d (diff)
downloadbox64-486df332dd2da9ffb2c586417b1ad6f184218a16.tar.gz
box64-486df332dd2da9ffb2c586417b1ad6f184218a16.zip
[DYNAREC_RV64] Added more opcodes for flatout.exe (#1133)
* [DYNAREC_RV64] Added 0F 6B PACKSSDW opcode

* [DYNAREC_RV64] Added more 0F opcodes

* [DYNAREC_RV64] Added 67 63 MOVSXD opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c70
-rw-r--r--src/dynarec/rv64/dynarec_rv64_67.c23
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h8
3 files changed, 100 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 283b6793..a03ef8e0 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -819,6 +819,41 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 SW(x3, gback, gdoffset + 1 * 4);
             }
             break;
+        case 0x6B:
+            INST_NAME("PACKSSDW Gm,Em");
+            nextop = F8;
+            GETGM();
+            for (int i = 0; i < 2; ++i) {
+                // GM->sw[i] = (GM->sd[i]<-32768)?-32768:((GM->sd[i]>32767)?32767:GM->sd[i]);
+                LW(x3, gback, gdoffset + i * 4);
+                LUI(x4, 0xFFFF8); // -32768
+                BGE(x3, x4, 12);
+                SH(x4, gback, gdoffset + i * 2);
+                J(20);      // continue
+                LUI(x4, 8); // 32768
+                BLT(x3, x4, 8);
+                ADDIW(x3, x4, -1);
+                SH(x3, gback, gdoffset + i * 2);
+            }
+            if (MODREG && gd == (nextop & 7)) {
+                LWU(x3, gback, gdoffset);
+                SW(x3, gback, gdoffset + 4);
+            } else {
+                GETEM(x1, 0);
+                for (int i = 0; i < 2; ++i) {
+                    // GM->sw[2+i] = (EM->sd[i]<-32768)?-32768:((EM->sd[i]>32767)?32767:EM->sd[i]);
+                    LW(x3, wback, fixedaddress + i * 4);
+                    LUI(x4, 0xFFFF8); // -32768
+                    BGE(x3, x4, 12);
+                    SH(x4, gback, gdoffset + 4 + i * 2);
+                    J(20);      // continue
+                    LUI(x4, 8); // 32768
+                    BLT(x3, x4, 8);
+                    ADDIW(x3, x4, -1);
+                    SH(x3, gback, gdoffset + 4 + i * 2);
+                }
+            }
+            break;
         case 0x6E:
             INST_NAME("MOVD Gm, Ed");
             nextop = F8;
@@ -1681,6 +1716,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             gd = xRAX + (opcode & 7) + (rex.b << 3);
             REV8xw(gd, gd, x1, x2, x3, x4);
             break;
+        case 0xD5:
+            INST_NAME("PMULLW Gm, Em");
+            nextop = F8;
+            GETGM();
+            GETEM(x2, 0);
+            MMX_LOOP_WS(x3, x4, MULW(x3, x3, x4));
+            break;
         case 0xDB:
             INST_NAME("PAND Gm, Em");
             nextop = F8;
@@ -1704,6 +1746,34 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 SH(x3, gback, gdoffset + 2 * i);
             }
             break;
+            INST_NAME("PSUBSW Gm,Em");
+            nextop = F8;
+            GETGM();
+            GETEM(x2, 0);
+            for (int i = 0; i < 4; ++i) {
+                LH(x3, gback, gdoffset + i * 2);
+                LH(x4, wback, fixedaddress);
+                SUBW(x3, x3, x4);
+                LUI(x4, 0xFFFF8); // -32768
+                BGE(x3, x4, 12);
+                SH(x4, gback, gdoffset + i * 2);
+                J(20);      // continue
+                LUI(x4, 8); // 32768
+                BLT(x3, x4, 8);
+                ADDIW(x3, x4, -1);
+                SH(x4, gback, gdoffset + i * 2);
+            }
+            break;
+        case 0xEB:
+            INST_NAME("POR Gm, Em");
+            nextop = F8;
+            GETGM();
+            GETEM(x2, 0);
+            LD(x3, gback, gdoffset);
+            LD(x4, wback, fixedaddress);
+            OR(x3, x3, x4);
+            SD(x3, gback, gdoffset);
+            break;
         case 0xE7:
             INST_NAME("MOVNTQ Em, Gm");
             nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c
index 9fc634f1..2ede9c3d 100644
--- a/src/dynarec/rv64/dynarec_rv64_67.c
+++ b/src/dynarec/rv64/dynarec_rv64_67.c
@@ -448,7 +448,28 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else
                 emit_cmp32_0(dyn, ninst, rex, xRAX, x3, x4);
             break;
-        
+        case 0x63:
+            INST_NAME("MOVSXD Gd, Ed");
+            nextop = F8;
+            GETGD;
+            if (rex.w) {
+                if (MODREG) { // reg <= reg
+                    ADDIW(gd, xRAX + (nextop & 7) + (rex.b << 3), 0);
+                } else { // mem <= reg
+                    SMREAD();
+                    addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0);
+                    LW(gd, ed, fixedaddress);
+                }
+            } else {
+                if (MODREG) { // reg <= reg
+                    AND(gd, xRAX + (nextop & 7) + (rex.b << 3), xMASK);
+                } else { // mem <= reg
+                    SMREAD();
+                    addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0);
+                    LWU(gd, ed, fixedaddress);
+                }
+            }
+            break;
         case 0x66:
             opcode = F8;
             switch (opcode) {
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index af6cc1a8..5a6d1cdb 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -562,6 +562,14 @@
         SH(GX1, gback, gdoffset + i * 2);      \
     }
 
+#define MMX_LOOP_WS(GX1, EX1, F)              \
+    for (int i = 0; i < 4; ++i) {             \
+        LH(GX1, gback, gdoffset + i * 2);     \
+        LH(EX1, wback, fixedaddress + i * 2); \
+        F;                                    \
+        SH(GX1, gback, gdoffset + i * 2);     \
+    }
+
 #define SSE_LOOP_W(GX1, EX1, F)                \
     for (int i = 0; i < 8; ++i) {              \
         LHU(GX1, gback, gdoffset + i * 2);     \