about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-05-03 14:18:49 +0800
committerGitHub <noreply@github.com>2023-05-03 08:18:49 +0200
commit0079a08cb837ab0dbf24c32222e8a76ee8f54740 (patch)
tree49f2eb9931ea9e2c4fdd7e359828b33e61ee0efc /src
parentd31ff6a83f6cac81cff3da6a0bd5fde128bad197 (diff)
downloadbox64-0079a08cb837ab0dbf24c32222e8a76ee8f54740.tar.gz
box64-0079a08cb837ab0dbf24c32222e8a76ee8f54740.zip
[RV64_DYNAREC] Added more opcodes for Bastion and some fixes (#753)
* Added AE SCASB opcode

* Some small fixes

* Added FSQRT opcode

* Treat all PREFETCHh opcodes as nop

* Added DF E0 FNSTSW opcode

* Added DD FSTP opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_2.c38
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c9
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c8
-rw-r--r--src/dynarec/rv64/dynarec_rv64_d9.c7
-rw-r--r--src/dynarec/rv64/dynarec_rv64_db.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_dd.c6
-rw-r--r--src/dynarec/rv64/dynarec_rv64_df.c19
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f20f.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f.c6
9 files changed, 75 insertions, 24 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index f2fd1287..0e9144b7 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -681,6 +681,44 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 ADD(xRDI, xRDI, x3);
             }
             break;
+        case 0xAE:
+            switch (rep) {
+            case 1:
+            case 2:
+                if (rep==1) {INST_NAME("REPNZ SCASB");} else {INST_NAME("REPZ SCASB");}
+                MAYSETFLAGS();
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                CBZ_NEXT(xRCX);
+                ANDI(x1, xRAX, 0xff);
+                ANDI(x1, xFlags, 1<<F_DF);
+                BNEZ_MARK2(x1);
+                MARK;   // Part with DF==0
+                LBU(x2, xRDI, 0);
+                ADDI(xRDI, xRDI, 1);
+                SUBI(xRCX, xRCX, 1);
+                if (rep==1) {BEQ_MARK3(x1, x2);} else {BNE_MARK3(x1, x2);}
+                BNE_MARK(xRCX, xZR);
+                B_MARK3_nocond;
+                MARK2;  // Part with DF==1
+                LBU(x2, xRDI, 0);
+                SUBI(xRDI, xRDI, 1);
+                SUBI(xRCX, xRCX, 1);
+                if (rep==1) {BEQ_MARK3(x1, x2);} else {BNE_MARK3(x1, x2);}
+                BNE_MARK2(xRCX, xZR);
+                MARK3; // end
+                emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6);
+                break;
+            default:
+                INST_NAME("SCASB");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETDIR(x3, x1, 1);
+                ANDI(x1, xRAX, 0xff);
+                LBU(x2, xRDI, 0);
+                ADD(xRDI, xRDI, x3);
+                emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6);
+                break;
+            }
+            break;
         case 0xB0:
         case 0xB1:
         case 0xB2:
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index e6ac82d8..777d0ed2 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -229,16 +229,11 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else
             switch((nextop>>3)&7) {
                 case 0:
-                    DEFAULT;
-                    break;
                 case 1:
-                    DEFAULT;
-                    break;
                 case 2:
-                    DEFAULT;
-                    break;
                 case 3:
-                    DEFAULT;
+                    INST_NAME("PREFETCHh Ed");
+                    FAKEED;
                     break;
                 default:
                     INST_NAME("NOP (multibyte)");
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 6e19ab14..3fce8de1 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -1710,10 +1710,10 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETEX(x2, 0);
             v0 = fpu_get_scratch(dyn);
             v1 = fpu_get_scratch(dyn);
-            FLD(v0, wback, 0);
-            FLD(v1, wback, 8);
+            FLD(v0, wback, fixedaddress+0);
+            FLD(v1, wback, fixedaddress+8);
             if(!box64_dynarec_fastround) {
-                FSFLAGSI(xZR);  // // reset all bits
+                FSFLAGSI(0);  // // reset all bits
             }
             FCVTWD(x3, v0, RD_RTZ);
             if(!box64_dynarec_fastround) {
@@ -1722,7 +1722,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 BEQ_MARK(x5, xZR);
                 MOV32w(x3, 0x80000000);
                 MARK;
-                FSFLAGSI(xZR);  // // reset all bits
+                FSFLAGSI(0);  // // reset all bits
             }
             FCVTWD(x4, v1, RD_RTZ);
             if(!box64_dynarec_fastround) {
diff --git a/src/dynarec/rv64/dynarec_rv64_d9.c b/src/dynarec/rv64/dynarec_rv64_d9.c
index a6a7898e..f924eaff 100644
--- a/src/dynarec/rv64/dynarec_rv64_d9.c
+++ b/src/dynarec/rv64/dynarec_rv64_d9.c
@@ -263,7 +263,12 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             break;
         case 0xFA:
             INST_NAME("FSQRT");
-            DEFAULT;
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
+            if(ST_IS_F(0)) {
+                FSQRTS(v1, v1);
+            } else {
+                FSQRTD(v1, v1);
+            }
             break;
         case 0xFB:
             INST_NAME("FSINCOS");
diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c
index e037c3dd..08abacfd 100644
--- a/src/dynarec/rv64/dynarec_rv64_db.c
+++ b/src/dynarec/rv64/dynarec_rv64_db.c
@@ -196,7 +196,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0);
                     v2 = fpu_get_scratch(dyn);
                     if(!box64_dynarec_fastround) {
-                        FSFLAGSI(xZR); // reset all bits
+                        FSFLAGSI(0); // reset all bits
                     }
                     FCVTWD(x4, v1, RD_DYN);
                     x87_restoreround(dyn, ninst, u8);
diff --git a/src/dynarec/rv64/dynarec_rv64_dd.c b/src/dynarec/rv64/dynarec_rv64_dd.c
index 71b1740a..ac5fb980 100644
--- a/src/dynarec/rv64/dynarec_rv64_dd.c
+++ b/src/dynarec/rv64/dynarec_rv64_dd.c
@@ -76,7 +76,11 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xDE:
         case 0xDF:
             INST_NAME("FSTP ST0, STx");
-            DEFAULT;
+            // copy the cache value for st0 to stx
+            x87_get_st_empty(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7));
+            x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
+            x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7);
+            x87_do_pop(dyn, ninst, x3);
             break;
         case 0xE0:
         case 0xE1:
diff --git a/src/dynarec/rv64/dynarec_rv64_df.c b/src/dynarec/rv64/dynarec_rv64_df.c
index 61546975..aa5f1131 100644
--- a/src/dynarec/rv64/dynarec_rv64_df.c
+++ b/src/dynarec/rv64/dynarec_rv64_df.c
@@ -47,9 +47,18 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 
         case 0xE0:
             INST_NAME("FNSTSW AX");
-            DEFAULT;
+            LHU(x2, xEmu, offsetof(x64emu_t, top));
+            LHU(x1, xEmu, offsetof(x64emu_t, sw));
+            MOV32w(x3, 0b1100011111111111); // mask
+            AND(x1, x1, x3);
+            NOT(x3, x3);
+            AND(x2, x2, x3);
+            OR(x1, x1, x2); // inject top
+            SH(x1, xEmu, offsetof(x64emu_t, sw));
+            SRLI(xRAX, xRAX, 16);
+            SLLI(xRAX, xRAX, 16);
+            OR(xRAX, xRAX, x1);
             break;
-
         case 0xE8 ... 0xF7:
             if (nextop < 0xF0) {
                 INST_NAME("FUCOMIP ST0, STx");
@@ -122,7 +131,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_F);
                     addr = geted(dyn, addr, ninst, nextop, &wback, x3, x4, &fixedaddress, rex, NULL, 1, 0);
                     if(!box64_dynarec_fastround) {
-                        FSFLAGSI(xZR); // reset all bits
+                        FSFLAGSI(0); // reset all bits
                     }
                     FCVTWD(x4, v1, RD_RTZ);
                     if(!box64_dynarec_fastround) {
@@ -145,7 +154,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     u8 = x87_setround(dyn, ninst, x1, x2);
                     addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0);
                     if(!box64_dynarec_fastround) {
-                        FSFLAGSI(xZR); // reset all bits
+                        FSFLAGSI(0); // reset all bits
                     }
                     FCVTWD(x4, v1, RD_DYN);
                     x87_restoreround(dyn, ninst, u8);
@@ -170,7 +179,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0);
                     v2 = fpu_get_scratch(dyn);
                     if(!box64_dynarec_fastround) {
-                        FSFLAGSI(xZR); // reset all bits
+                        FSFLAGSI(0); // reset all bits
                     }
                     FCVTLD(x4, v1, RD_DYN);
                     x87_restoreround(dyn, ninst, u8);
diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c
index 35fcf562..74937408 100644
--- a/src/dynarec/rv64/dynarec_rv64_f20f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f20f.c
@@ -105,7 +105,7 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETGD;
             GETEXSD(v0, 0);
             if(!box64_dynarec_fastround) {
-                FSFLAGSI(xZR);  // // reset all bits
+                FSFLAGSI(0);  // // reset all bits
             }
             FCVTLDxw(gd, v0, RD_RTZ);
             if(!rex.w)
@@ -127,7 +127,7 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETGD;
             GETEXSD(v0, 0);
             if(!box64_dynarec_fastround) {
-                FSFLAGSI(xZR);  // // reset all bits
+                FSFLAGSI(0);  // // reset all bits
             }
             u8 = sse_setround(dyn, ninst, x2, x3);
             FCVTLDxw(gd, v0, RD_DYN);
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c
index ab7855da..bdb8fa3b 100644
--- a/src/dynarec/rv64/dynarec_rv64_f30f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f30f.c
@@ -105,7 +105,7 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETGD;
             GETEXSS(d0, 0);
             if(!box64_dynarec_fastround) {
-                FSFLAGSI(xZR);  // // reset all bits
+                FSFLAGSI(0);  // // reset all bits
             }
             FCVTSxw(gd, d0, RD_RTZ);
             if(!rex.w)
@@ -127,7 +127,7 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETGD;
             GETEXSS(d0, 0);
             if(!box64_dynarec_fastround) {
-                FSFLAGSI(xZR);  // // reset all bits
+                FSFLAGSI(0);  // // reset all bits
             }
             u8 = sse_setround(dyn, ninst, x5, x6);
             FCVTSxw(gd, d0, RD_DYN);
@@ -285,7 +285,7 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             v0 = fpu_get_scratch(dyn);
             for(int i=0; i<4; ++i) {
                 if(!box64_dynarec_fastround) {
-                    FSFLAGSI(xZR); // reset all bits
+                    FSFLAGSI(0); // reset all bits
                 }
                 FLW(v0, wback, fixedaddress+i*4);
                 FCVTWS(x3, v0, RD_RTZ);