about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-12-08 19:28:11 +0800
committerGitHub <noreply@github.com>2023-12-08 12:28:11 +0100
commit840c454c1c06df4695008bea72ba4fc9a266e437 (patch)
tree6392f35f0b51128562d0cc165d6199b94dd01af6 /src
parent77143dc8cf12bbd00f74fe15130f1554af6563ce (diff)
downloadbox64-840c454c1c06df4695008bea72ba4fc9a266e437.tar.gz
box64-840c454c1c06df4695008bea72ba4fc9a266e437.zip
[DYNAREC_RV64] Added more opcodes for flatout.exe (#1126)
* [DYNAREC_RV64] Added DC C8..CF FMUL opcodes

* [DYNAREC_RV64] Added D8 /7 FDIVR opcode

* [DYNAREC_RV64] Added A7 CMPSD opcode

* [DYNAREC_RV64] Added more DC opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_2.c42
-rw-r--r--src/dynarec/rv64/dynarec_rv64_d8.c22
-rw-r--r--src/dynarec/rv64/dynarec_rv64_dc.c59
3 files changed, 114 insertions, 9 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index 998795e3..bf1d1f73 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -644,6 +644,48 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 break;
             }
             break;
+        case 0xA7:
+            switch (rep) {
+                case 1:
+                case 2:
+                    if (rep == 1) { INST_NAME("REPNZ CMPSD"); } else { INST_NAME("REPZ CMPSD"); }
+                    MAYSETFLAGS();
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    CBZ_NEXT(xRCX);
+                    ANDI(x1, xFlags, 1 << F_DF);
+                    BNEZ_MARK2(x1);
+                    MARK; // Part with DF==0
+                    LDxw(x1, xRSI, 0);
+                    ADDI(xRSI, xRSI, rex.w ? 8 : 4);
+                    LDxw(x2, xRDI, 0);
+                    ADDI(xRDI, xRDI, rex.w ? 8 : 4);
+                    SUBI(xRCX, xRCX, 1);
+                    if (rep == 1) { BEQ_MARK3(x1, x2); } else { BNE_MARK3(x1, x2); }
+                    BNEZ_MARK(xRCX);
+                    B_MARK3_nocond;
+                    MARK2; // Part with DF==1
+                    LDxw(x1, xRSI, 0);
+                    SUBI(xRSI, xRSI, rex.w ? 8 : 4);
+                    LDxw(x2, xRDI, 0);
+                    SUBI(xRDI, xRDI, rex.w ? 8 : 4);
+                    SUBI(xRCX, xRCX, 1);
+                    if (rep == 1) { BEQ_MARK3(x1, x2); } else { BNE_MARK3(x1, x2); }
+                    BNEZ_MARK2(xRCX);
+                    MARK3; // end
+                    emit_cmp32(dyn, ninst, rex, x1, x2, x3, x4, x5, x6);
+                    break;
+                default:
+                    INST_NAME("CMPSD");
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETDIR(x3, x1, rex.w ? 8 : 4);
+                    LDxw(x1, xRSI, 0);
+                    LDxw(x2, xRDI, 0);
+                    ADD(xRSI, xRSI, x3);
+                    ADD(xRDI, xRDI, x3);
+                    emit_cmp32(dyn, ninst, rex, x1, x2, x3, x4, x5, x6);
+                    break;
+            }
+            break;
         case 0xA8:
             INST_NAME("TEST AL, Ib");
             SETFLAGS(X_ALL, SF_SET_PENDING);
diff --git a/src/dynarec/rv64/dynarec_rv64_d8.c b/src/dynarec/rv64/dynarec_rv64_d8.c
index c9372ee7..3f7f2314 100644
--- a/src/dynarec/rv64/dynarec_rv64_d8.c
+++ b/src/dynarec/rv64/dynarec_rv64_d8.c
@@ -43,7 +43,14 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 
     switch(nextop) {
         case 0xC0 ... 0xC7:
-            DEFAULT;
+            INST_NAME("FADD 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)) {
+                FADDS(v1, v1, v2);
+            } else {
+                FADDD(v1, v1, v2);
+            }
             break;
         case 0xC8 ... 0xCF:
             DEFAULT;
@@ -170,6 +177,19 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         FDIVD(v1, v1, s0);
                     }
                     break;
+                case 7:
+                    INST_NAME("FDIVR ST0, float[ED]");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
+                    s0 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    FLW(s0, ed, fixedaddress);
+                    if (ST_IS_F(0)) {
+                        FDIVS(v1, s0, v1);
+                    } else {
+                        FCVTDS(s0, s0);
+                        FDIVD(v1, s0, v1);
+                    }
+                    break;
                 default:
                     DEFAULT;
             }
diff --git a/src/dynarec/rv64/dynarec_rv64_dc.c b/src/dynarec/rv64/dynarec_rv64_dc.c
index 9625cfda..7f680f00 100644
--- a/src/dynarec/rv64/dynarec_rv64_dc.c
+++ b/src/dynarec/rv64/dynarec_rv64_dc.c
@@ -43,31 +43,74 @@ uintptr_t dynarec64_DC(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             break;
         case 0xC8 ... 0xCF:
             INST_NAME("FMUL STx, ST0");
-            DEFAULT;
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FMULS(v1, v1, v2);
+            } else {
+                FMULD(v1, v1, v2);
+            }
             break;
         case 0xD0 ... 0xD7:
             INST_NAME("FCOM ST0, STx"); //yep
-            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 0xD8 ... 0xDF:
             INST_NAME("FCOMP 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 0xE0 ... 0xE7:
             INST_NAME("FSUBR STx, ST0");
-            DEFAULT;
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FSUBS(v1, v2, v1);
+            } else {
+                FSUBD(v1, v2, v1);
+            }
             break;
         case 0xE8 ... 0xEF:
             INST_NAME("FSUB STx, ST0");
-            DEFAULT;
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FSUBS(v1, v1, v2);
+            } else {
+                FSUBD(v1, v1, v2);
+            }
             break;
         case 0xF0 ... 0xF7:
             INST_NAME("FDIVR STx, ST0");
-            DEFAULT;
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FDIVS(v1, v2, v1);
+            } else {
+                FDIVD(v1, v2, v1);
+            }
             break;
         case 0xF8 ... 0xFF:
             INST_NAME("FDIV STx, ST0");
-            DEFAULT;
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FDIVS(v1, v1, v2);
+            } else {
+                FDIVD(v1, v1, v2);
+            }
             break;
         default:
             switch((nextop>>3)&7) {
@@ -77,7 +120,7 @@ uintptr_t dynarec64_DC(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     v2 = fpu_get_scratch(dyn);
                     addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
                     FLD(v2, wback, fixedaddress);
-                    FCOMD(v1, v2, x1, x2, x3, x4, x5);
+                    FCOMD(v1, v2, x1, x6, x3, x4, x5);
                     X87_POP_OR_FAIL(dyn, ninst, x3);
                     break;
                 case 6: