about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-03-17 15:12:31 +0800
committerGitHub <noreply@github.com>2025-03-17 08:12:31 +0100
commit394513971cf97619f34de6f84a5792d8ecd8f9c7 (patch)
treee5b9ef73e6e16fd775ad5ff470b26f59f2562313 /src
parent8b750200360cede1b6442462ed47f25c27f376d5 (diff)
downloadbox64-394513971cf97619f34de6f84a5792d8ecd8f9c7.tar.gz
box64-394513971cf97619f34de6f84a5792d8ecd8f9c7.zip
[RV64_DYNAREC] Minor x87 changes to enable test31 (#2441)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_d9.c26
-rw-r--r--src/dynarec/rv64/dynarec_rv64_db.c8
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c10
3 files changed, 21 insertions, 23 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_d9.c b/src/dynarec/rv64/dynarec_rv64_d9.c
index 51321ab9..52c8ec10 100644
--- a/src/dynarec/rv64/dynarec_rv64_d9.c
+++ b/src/dynarec/rv64/dynarec_rv64_d9.c
@@ -152,17 +152,6 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         ADDI(x5, x5, i2);
                         ANDI(x5, x5, 7); // (emu->top + i)&7
                     }
-                    // load tag
-                    LHU(x3, xEmu, offsetof(x64emu_t, fpu_tags));
-                    if (i2 < 0) {
-                        SLLI(x3, x3, -i2 * 2);
-                    } else if (i2 > 0) {
-                        LUI(x2, 0xffff0);
-                        OR(x3, x3, x2);
-                        SRLI(x3, x3, i2 * 2);
-                    }
-                    ANDI(x2, x3, 0b11);
-                    BNEZ_MARK3(x2); // empty: C3,C2,C0 = 101
                     // load x2 with ST0 anyway, for sign extraction
                     if (rv64_zba)
                         SH3ADD(x1, x5, xEmu);
@@ -171,6 +160,17 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         ADD(x1, xEmu, x5);
                     }
                     LD(x2, x1, offsetof(x64emu_t, x87));
+                    // load tag
+                    if (i2 >= 0) {
+                        LHU(x3, xEmu, offsetof(x64emu_t, fpu_tags));
+                        if (i2 > 0) {
+                            LUI(x5, 0xffff0);
+                            OR(x3, x3, x5);
+                            SRLI(x3, x3, i2 * 2);
+                        }
+                        ANDI(x3, x3, 0b11);
+                        BNEZ_MARK3(x3); // empty: C3,C2,C0 = 101
+                    }
                 }
             } else {
                 // simply move from cache reg to x2
@@ -312,7 +312,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xF4:
             INST_NAME("FXTRACT");
             MESSAGE(LOG_DUMP, "Need Optimization\n");
-            X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
+            X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3);
             x87_forget(dyn, ninst, x1, x2, 1);
             s0 = x87_stackcount(dyn, ninst, x3);
             CALL(native_fxtract, -1, 0, 0);
@@ -376,7 +376,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xFB:
             INST_NAME("FSINCOS");
             MESSAGE(LOG_DUMP, "Need Optimization\n");
-            X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
+            X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3);
             x87_forget(dyn, ninst, x1, x2, 1);
             s0 = x87_stackcount(dyn, ninst, x3);
             if (!BOX64ENV(dynarec_fastround)) u8 = x87_setround(dyn, ninst, x1, x2);
diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c
index cd5f8ee0..37aafc65 100644
--- a/src/dynarec/rv64/dynarec_rv64_db.c
+++ b/src/dynarec/rv64/dynarec_rv64_db.c
@@ -243,14 +243,14 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 case 5:
                     INST_NAME("FLD tbyte");
                     addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 8, 0);
-                    if ((PK(0) == 0xDB && ((PK(1) >> 3) & 7) == 7) || (PK(0) >= 0x40 && PK(0) <= 0x4f && PK(1) == 0xDB && ((PK(2) >> 3) & 7) == 7)) {
+                    if ((PK(0) == 0xDB && ((PK(1) >> 3) & 7) == 7) || (!rex.is32bits && PK(0) >= 0x40 && PK(0) <= 0x4f && PK(1) == 0xDB && ((PK(2) >> 3) & 7) == 7)) {
                         // the FLD is immediatly followed by an FSTP
                         LD(x5, ed, fixedaddress + 0);
                         LH(x6, ed, fixedaddress + 8);
                         // no persistant scratch register, so unrool both instruction here...
                         MESSAGE(LOG_DUMP, "\tHack: FSTP tbyte\n");
                         nextop = F8; // 0xDB or rex
-                        if (nextop >= 0x40 && nextop <= 0x4f) {
+                        if (!rex.is32bits && nextop >= 0x40 && nextop <= 0x4f) {
                             rex.rex = nextop;
                             nextop = F8; // 0xDB
                         } else
@@ -266,7 +266,11 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         } else {
                             ADDI(x1, ed, fixedaddress);
                             X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3);
+                            // sync top
+                            s0 = x87_stackcount(dyn, ninst, x3);
                             CALL(native_fld, -1, x1, 0);
+                            // go back with the top & stack counter
+                            x87_unstackcount(dyn, ninst, x3, s0);
                         }
                     }
                     break;
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index 8dc8f9a4..4f3286fa 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -1023,8 +1023,6 @@ void x87_do_push_empty(dynarec_rv64_t* dyn, int ninst, int s1)
         MESSAGE(LOG_DUMP, "Incoherent x87 stack cache, aborting\n");
         dyn->abort = 1;
     }
-    if (s1)
-        x87_stackcount(dyn, ninst, s1);
 }
 static void internal_x87_dopop(dynarec_rv64_t* dyn)
 {
@@ -1083,11 +1081,7 @@ void x87_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1, int s2, in
         // Sub x87stack to top, with and 7
         LW(s2, xEmu, offsetof(x64emu_t, top));
         // update tags (and top at the same time)
-        if (a > 0) {
-            SUBI(s2, s2, a);
-        } else {
-            ADDI(s2, s2, -a);
-        }
+        SUBI(s2, s2, a);
         ANDI(s2, s2, 7);
         SW(s2, xEmu, offsetof(x64emu_t, top));
         // update tags (and top at the same time)
@@ -1095,7 +1089,7 @@ void x87_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1, int s2, in
         if (a > 0) {
             SLLI(s1, s1, a * 2);
         } else {
-            MOV32w(s3, 0xffff0000);
+            LUI(s3, 0xffff0);
             OR(s1, s1, s3);
             SRLI(s1, s1, -a * 2);
         }