about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-04-02 21:34:49 +0800
committerGitHub <noreply@github.com>2024-04-02 15:34:49 +0200
commit0505b193789261501bc203783350bbda79f43b36 (patch)
tree03d39bf7f2dafcbdc66242d2f2133b68f8c3b033 /src
parente18e532846bda3462daf3458c5e528086348f3c8 (diff)
downloadbox64-0505b193789261501bc203783350bbda79f43b36.tar.gz
box64-0505b193789261501bc203783350bbda79f43b36.zip
[RV64_DYNAREC] Fixed some issue with x87 stack managment (ported from ARM64) (#1401)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index 1bb36b07..6c5d25ee 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -979,30 +979,36 @@ void x87_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1, int s2, in
         // loop all cache entries
         for (int i=0; i<8; ++i)
             if(dyn->e.x87cache[i]!=-1) {
+                int st = dyn->e.x87cache[i]+dyn->e.stack_pop;
                 #if STEP == 1
                 if(!next) {   // don't force promotion here
                     // pre-apply pop, because purge happens in-between
-                    extcache_promote_double(dyn, ninst, dyn->e.x87cache[i]+dyn->e.stack_pop);
+                    extcache_promote_double(dyn, ninst, st);
                 }
                 #endif
                 #if STEP == 3
-                if(!next && extcache_get_st_f(dyn, ninst, dyn->e.x87cache[i])>=0) {
-                    MESSAGE(LOG_DUMP, "Warning, incoherency with purged ST%d cache\n", dyn->e.x87cache[i]);
+                if(!next && extcache_get_current_st(dyn, ninst, st) != EXT_CACHE_ST_D) {
+                    MESSAGE(LOG_DUMP, "Warning, incoherency with purged ST%d cache\n", st);
                 }
                 #endif
-                ADDI(s3, s2, dyn->e.x87cache[i]);
+                ADDI(s3, s2, dyn->e.x87cache[i]); // unadjusted count, as it's relative to real top
                 ANDI(s3, s3, 7);   // (emu->top + st)&7
                 if(rv64_zba) SH3ADD(s1, s3, xEmu); else {SLLI(s1, s3, 3); ADD(s1, xEmu, s1);}
-                if(next) {
-                    // need to check if a ST_F need local promotion
-                    if(extcache_get_st_f(dyn, ninst, dyn->e.x87cache[i])>=0) {
+                switch(extcache_get_current_st(dyn, ninst, st)) {
+                    case EXT_CACHE_ST_D:
+                        FSD(dyn->e.x87reg[i], s1, offsetof(x64emu_t, x87));    // save the value
+                        break;
+                    case EXT_CACHE_ST_F:
                         FCVTDS(SCRATCH0, dyn->e.x87reg[i]);
                         FSD(SCRATCH0, s1, offsetof(x64emu_t, x87));    // save the value
-                    } else {
-                        FSD(dyn->e.x87reg[i], s1, offsetof(x64emu_t, x87));    // save the value
-                    }
-                } else {
-                    FSD(dyn->e.x87reg[i], s1, offsetof(x64emu_t, x87));
+                        break;
+                    case EXT_CACHE_ST_I64:
+                        FMVXD(s2, dyn->e.x87reg[i]);
+                        FCVTDL(SCRATCH0, s2, RD_RTZ);
+                        FSD(SCRATCH0, s1, offsetof(x64emu_t, x87));    // save the value
+                        break;
+                }
+                if(!next) {
                     fpu_free_reg(dyn, dyn->e.x87reg[i]);
                     dyn->e.x87reg[i] = -1;
                     dyn->e.x87cache[i] = -1;