about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-12-11 01:33:46 +0800
committerGitHub <noreply@github.com>2023-12-10 18:33:46 +0100
commit9d72c9db1bf113f9a8dba629893ec548b4714c14 (patch)
treee4b15d185b2f82e96b1c57aa8959e0972f7e38be /src
parent486df332dd2da9ffb2c586417b1ad6f184218a16 (diff)
downloadbox64-9d72c9db1bf113f9a8dba629893ec548b4714c14.tar.gz
box64-9d72c9db1bf113f9a8dba629893ec548b4714c14.zip
[DYNAREC_RV64] Added more opcodes for flatout.exe (#1134)
* [DYNAREC_RV64] Added more DA opcodes

* [DYNAREC_RV64] Added 0F E9 PSUBSW opcode

* [DYNAREC_RV64] Added 0F D9 PSUBUSW opcode

* [DYNAREC_RV64] Added more DD opcode

* [DYNAREC_RV64] Added more DE opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c52
-rw-r--r--src/dynarec/rv64/dynarec_rv64_da.c44
-rw-r--r--src/dynarec/rv64/dynarec_rv64_dd.c25
-rw-r--r--src/dynarec/rv64/dynarec_rv64_de.c26
4 files changed, 123 insertions, 24 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index a03ef8e0..c08083ee 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -1723,6 +1723,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             GETEM(x2, 0);
             MMX_LOOP_WS(x3, x4, MULW(x3, x3, x4));
             break;
+        case 0xD9:
+            INST_NAME("PSUBUSW Gm, Em");
+            nextop = F8;
+            GETGM();
+            GETEM(x2, 0);
+            MMX_LOOP_W(x3, x4, SUB(x3, x3, x4); SLT(x4, xZR, x3); NEG(x4, x4); AND(x3, x3, x4));
+            break;
         case 0xDB:
             INST_NAME("PAND Gm, Em");
             nextop = F8;
@@ -1764,16 +1771,6 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 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;
@@ -1786,14 +1783,45 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 FSD(v0, ed, fixedaddress);
             }
             break;
+        case 0xE9:
+            INST_NAME("PSUBSW Gm,Em");
+            nextop = F8;
+            GETGM();
+            GETEM(x2, 0);
+            for (int i = 0; i < 4; ++i) {
+                // tmp32s = (int32_t)GM->sw[i] - EM->sw[i];
+                // GM->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);
+                LH(x3, gback, gdoffset + 2 * i);
+                LH(x4, wback, fixedaddress + 2 * i);
+                SUBW(x3, x3, x4);
+                LUI(x4, 0xFFFF8); // -32768
+                BGE(x3, x4, 12);
+                SH(x4, gback, gdoffset + 2 * i);
+                J(20);      // continue
+                LUI(x4, 8); // 32768
+                BLT(x3, x4, 8);
+                ADDIW(x3, x4, -1);
+                SH(x3, gback, gdoffset + 2 * i);
+            }
+            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 0xED:
             INST_NAME("PADDSW Gm,Em");
             nextop = F8;
             GETGM();
             GETEM(x2, 0);
             for (int i = 0; i < 4; ++i) {
-                // tmp32s = (int32_t)GX->sw[i] + EX->sw[i];
-                // GX->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);
+                // tmp32s = (int32_t)GM->sw[i] + EM->sw[i];
+                // GM->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);
                 LH(x3, gback, gdoffset + 2 * i);
                 LH(x4, wback, fixedaddress + 2 * i);
                 ADDW(x3, x3, x4);
diff --git a/src/dynarec/rv64/dynarec_rv64_da.c b/src/dynarec/rv64/dynarec_rv64_da.c
index 519ba92f..61584090 100644
--- a/src/dynarec/rv64/dynarec_rv64_da.c
+++ b/src/dynarec/rv64/dynarec_rv64_da.c
@@ -51,7 +51,16 @@ uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xC5:
         case 0xC6:
         case 0xC7:
-            DEFAULT;
+            INST_NAME("FCMOVB ST0, STx");
+            READFLAGS(X_CF);
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            ANDI(x1, xFlags, 1 << F_CF);
+            CBZ_NEXT(x1);
+            if (ST_IS_F(0))
+                FMVS(v1, v2);
+            else
+                FMVD(v1, v2);
             break;
         case 0xC8:
         case 0xC9:
@@ -61,7 +70,16 @@ uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xCD:
         case 0xCE:
         case 0xCF:
-            DEFAULT;
+            INST_NAME("FCMOVE ST0, STx");
+            READFLAGS(X_ZF);
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            ANDI(x1, xFlags, 1 << F_ZF);
+            CBZ_NEXT(x1);
+            if (ST_IS_F(0))
+                FMVS(v1, v2);
+            else
+                FMVD(v1, v2);
             break;
         case 0xD0:
         case 0xD1:
@@ -71,7 +89,16 @@ uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xD5:
         case 0xD6:
         case 0xD7:
-            DEFAULT;
+            INST_NAME("FCMOVBE ST0, STx");
+            READFLAGS(X_CF | X_ZF);
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            ANDI(x1, xFlags, (1 << F_CF) | (1 << F_ZF));
+            CBZ_NEXT(x1);
+            if (ST_IS_F(0))
+                FMVS(v1, v2);
+            else
+                FMVD(v1, v2);
             break;
         case 0xD8:
         case 0xD9:
@@ -81,7 +108,16 @@ uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xDD:
         case 0xDE:
         case 0xDF:
-            DEFAULT;
+            INST_NAME("FCMOVU ST0, STx");
+            READFLAGS(X_PF);
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            ANDI(x1, xFlags, (1 << F_PF));
+            CBZ_NEXT(x1);
+            if (ST_IS_F(0))
+                FMVS(v1, v2);
+            else
+                FMVD(v1, v2);
             break;
         case 0xE9:
             INST_NAME("FUCOMPP ST0, ST1");
diff --git a/src/dynarec/rv64/dynarec_rv64_dd.c b/src/dynarec/rv64/dynarec_rv64_dd.c
index b5a282e1..47718d64 100644
--- a/src/dynarec/rv64/dynarec_rv64_dd.c
+++ b/src/dynarec/rv64/dynarec_rv64_dd.c
@@ -64,7 +64,13 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xD6:
         case 0xD7:
             INST_NAME("FST ST0, STx");
-            DEFAULT;
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FMVS(v2, v1);
+            } else {
+                FMVD(v2, v1);
+            }
             break;
         case 0xD8:
             INST_NAME("FSTP ST0, ST0");
@@ -93,7 +99,13 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xE6:
         case 0xE7:
             INST_NAME("FUCOM ST0, STx");
-            DEFAULT;
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FCOMS(v1, v2, x1, x2, x3, x4, x5);
+            } else {
+                FCOMD(v1, v2, x1, x2, x3, x4, x5);
+            }
             break;
         case 0xE8:
         case 0xE9:
@@ -104,7 +116,14 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xEE:
         case 0xEF:
             INST_NAME("FUCOMP ST0, STx");
-            DEFAULT;
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FCOMS(v1, v2, x1, x2, x3, x4, x5);
+            } else {
+                FCOMD(v1, v2, x1, x2, x3, x4, x5);
+            }
+            X87_POP_OR_FAIL(dyn, ninst, x3);
             break;
         case 0xC8:
         case 0xC9:
diff --git a/src/dynarec/rv64/dynarec_rv64_de.c b/src/dynarec/rv64/dynarec_rv64_de.c
index 6712a97c..f20cc686 100644
--- a/src/dynarec/rv64/dynarec_rv64_de.c
+++ b/src/dynarec/rv64/dynarec_rv64_de.c
@@ -80,12 +80,27 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xD5:
         case 0xD6:
         case 0xD7:
-            // INST_NAME("FCOMP ST0, STx"); //yep
-            DEFAULT;
+            INST_NAME("FCOMP ST0, STx"); // yep
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FCOMS(v1, v2, x1, x2, x3, x4, x5);
+            } else {
+                FCOMD(v1, v2, x1, x2, x3, x4, x5);
+            }
+            X87_POP_OR_FAIL(dyn, ninst, x3);
             break;
         case 0xD9:
-            // INST_NAME("FCOMPP ST0, STx");
-            DEFAULT;
+            INST_NAME("FCOMPP ST0, STx");
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FCOMS(v1, v2, x1, x2, x3, x4, x5);
+            } else {
+                FCOMD(v1, v2, x1, x2, x3, x4, x5);
+            }
+            X87_POP_OR_FAIL(dyn, ninst, x3);
+            X87_POP_OR_FAIL(dyn, ninst, x3);
             break;
         case 0xE0:
         case 0xE1:
@@ -166,7 +181,8 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xDD:
         case 0xDE:
         case 0xDF:
-            return 0;
+            DEFAULT;
+            break;
         default:
             switch((nextop>>3)&7) {
                 default: