about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-03-30 14:00:27 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-03-30 14:00:27 +0200
commitd93e53498d18cbabb601a4fffb5224925aa5db24 (patch)
tree83a51f24a30a803f73aeead314011b292c2e190b /src
parente82d5264144baa0236d751c63d8700c78eea0b46 (diff)
downloadbox64-d93e53498d18cbabb601a4fffb5224925aa5db24.tar.gz
box64-d93e53498d18cbabb601a4fffb5224925aa5db24.zip
[DYNAREC] Fixed handling of x87 top and stack on TEST_INTERPRETER
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_helper.c57
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_helper.h2
-rwxr-xr-xsrc/dynarec/dynarec_native_pass.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c41
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h2
5 files changed, 100 insertions, 4 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c
index 1f897344..cbbf0c38 100755
--- a/src/dynarec/arm64/dynarec_arm64_helper.c
+++ b/src/dynarec/arm64/dynarec_arm64_helper.c
@@ -906,7 +906,27 @@ void x87_purgecache(dynarec_arm_t* dyn, int ninst, int next, int s1, int s2, int
 
 static void x87_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3)
 {
-    x87_stackcount(dyn, ninst, s1);
+    // Synch top & stack counter
+    int a = dyn->n.x87stack;
+    if(a) {
+        // Add x87stack to emu fpu_stack
+        LDRw_U12(s2, xEmu, offsetof(x64emu_t, fpu_stack));
+        if(a>0) {
+            ADDw_U12(s2, s2, a);
+        } else {
+            SUBw_U12(s2, s2, -a);
+        }
+        STRw_U12(s2, xEmu, offsetof(x64emu_t, fpu_stack));
+        // Sub x87stack to top, with and 7
+        LDRw_U12(s2, xEmu, offsetof(x64emu_t, top));
+        if(a>0) {
+            SUBw_U12(s2, s2, a);
+        } else {
+            ADDw_U12(s2, s2, -a);
+        }
+        ANDw_mask(s2, s2, 0, 2);  //mask=7
+        STRw_U12(s2, xEmu, offsetof(x64emu_t, top));
+    }
     int ret = 0;
     for (int i=0; (i<8) && (!ret); ++i)
         if(dyn->n.x87cache[i] != -1)
@@ -916,7 +936,9 @@ static void x87_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int
     // prepare offset to fpu => s1
     ADDx_U12(s1, xEmu, offsetof(x64emu_t, x87));
     // Get top
-    LDRw_U12(s2, xEmu, offsetof(x64emu_t, top));
+    if(!a) {
+        LDRw_U12(s2, xEmu, offsetof(x64emu_t, top));
+    }
     // loop all cache entries
     for (int i=0; i<8; ++i)
         if(dyn->n.x87cache[i]!=-1) {
@@ -926,6 +948,31 @@ static void x87_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int
         }
 }
 
+static void x87_unreflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3)
+{
+    // go back with the top & stack counter
+    int a = dyn->n.x87stack;
+    if(a) {
+        // Sub x87stack to emu fpu_stack
+        LDRw_U12(s2, xEmu, offsetof(x64emu_t, fpu_stack));
+        if(a>0) {
+            SUBw_U12(s2, s2, a);
+        } else {
+            ADDw_U12(s2, s2, -a);
+        }
+        STRw_U12(s2, xEmu, offsetof(x64emu_t, fpu_stack));
+        // Add x87stack to top, with and 7
+        LDRw_U12(s2, xEmu, offsetof(x64emu_t, top));
+        if(a>0) {
+            ADDw_U12(s2, s2, a);
+        } else {
+            SUBw_U12(s2, s2, -a);
+        }
+        ANDw_mask(s2, s2, 0, 2);  //mask=7
+        STRw_U12(s2, xEmu, offsetof(x64emu_t, top));
+    }
+}
+
 int x87_get_current_cache(dynarec_arm_t* dyn, int ninst, int st, int t)
 {
     // search in cache first
@@ -1753,6 +1800,12 @@ void fpu_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3)
     sse_reflectcache(dyn, ninst, s1);
 }
 
+void fpu_unreflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3)
+{
+    // need to undo some things on the x87 tracking
+    x87_unreflectcache(dyn, ninst, s1, s2, s3);
+}
+
 void fpu_reset(dynarec_arm_t* dyn)
 {
     x87_reset(dyn);
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 64f05583..5c908685 100755
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -979,6 +979,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
 #define mmx_purgecache  STEPNAME(mmx_purgecache)
 #define x87_purgecache  STEPNAME(x87_purgecache)
 #define fpu_reflectcache STEPNAME(fpu_reflectcache)
+#define fpu_unreflectcache STEPNAME(fpu_unreflectcache)
 
 #define CacheTransform       STEPNAME(CacheTransform)
 
@@ -1169,6 +1170,7 @@ void mmx_purgecache(dynarec_arm_t* dyn, int ninst, int next, int s1);
 // purge x87 cache
 void x87_purgecache(dynarec_arm_t* dyn, int ninst, int next, int s1, int s2, int s3);
 void fpu_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3);
+void fpu_unreflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3);
 void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07);
 void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07);
 
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c
index d81ef6ee..be9ebd7e 100755
--- a/src/dynarec/dynarec_native_pass.c
+++ b/src/dynarec/dynarec_native_pass.c
@@ -87,6 +87,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr)
             MESSAGE(LOG_DUMP, "TEST INIT ----\n");
             fpu_reflectcache(dyn, ninst, x1, x2, x3);
             GO_TRACE(x64test_init, 1);
+            fpu_unreflectcache(dyn, ninst, x1, x2, x3);
             MESSAGE(LOG_DUMP, "----------\n");
         }
 #ifdef HAVE_TRACE
@@ -96,6 +97,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr)
                 MESSAGE(LOG_DUMP, "TRACE ----\n");
                 fpu_reflectcache(dyn, ninst, x1, x2, x3);
                 GO_TRACE(PrintTrace, 1);
+                fpu_unreflectcache(dyn, ninst, x1, x2, x3);
                 MESSAGE(LOG_DUMP, "----------\n");
             }
         }
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index d031a434..6b44a2b7 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -745,7 +745,19 @@ void x87_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1, int s2, in
 
 static void x87_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3)
 {
-    x87_stackcount(dyn, ninst, s1);
+    //Sync top and stack count
+    int a = dyn->e.x87stack;
+    if(a) {
+        // Add x87stack to emu fpu_stack
+        LW(s2, xEmu, offsetof(x64emu_t, fpu_stack));
+        ADDI(s2, s2, a);
+        SW(s2, xEmu, offsetof(x64emu_t, fpu_stack));
+        // Sub x87stack to top, with and 7
+        LW(s2, xEmu, offsetof(x64emu_t, top));
+        SUBI(s2, s2, a);
+        ANDI(s2, s2, 7);
+        SW(s2, xEmu, offsetof(x64emu_t, top));
+    }
     int ret = 0;
     for (int i=0; (i<8) && (!ret); ++i)
         if(dyn->e.x87cache[i] != -1)
@@ -754,7 +766,9 @@ static void x87_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int
         return;
     // prepare offset to fpu => s1
     // Get top
-    LW(s2, xEmu, offsetof(x64emu_t, top));
+    if(!a) {
+        LW(s2, xEmu, offsetof(x64emu_t, top));
+    }
     // loop all cache entries
     for (int i=0; i<8; ++i)
         if(dyn->e.x87cache[i]!=-1) {
@@ -766,6 +780,23 @@ static void x87_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int
         }
 }
 
+static void x87_unreflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3)
+{
+    // revert top and stack count
+    int a = dyn->e.x87stack;
+    if(a) {
+        // Sub x87stack to emu fpu_stack
+        LW(s2, xEmu, offsetof(x64emu_t, fpu_stack));
+        SUBI(s2, s2, a);
+        SW(s2, xEmu, offsetof(x64emu_t, fpu_stack));
+        // Add x87stack to top, with and 7
+        LW(s2, xEmu, offsetof(x64emu_t, top));
+        ADDI(s2, s2, a);
+        ANDI(s2, s2, 7);
+        SW(s2, xEmu, offsetof(x64emu_t, top));
+    }
+}
+
 int x87_get_current_cache(dynarec_rv64_t* dyn, int ninst, int st, int t)
 {
     // search in cache first
@@ -1698,6 +1729,12 @@ void fpu_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3)
     sse_reflectcache(dyn, ninst, s1);
 }
 
+void fpu_unreflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3)
+{
+    // need to undo the top and stack tracking that must not be reflected permenatly yet
+    x87_reflectcache(dyn, ninst, s1, s2, s3);
+}
+
 void fpu_reset(dynarec_rv64_t* dyn)
 {
     x87_reset(dyn);
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 4c8651c3..cd795aa6 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -801,6 +801,7 @@ void* rv64_next(x64emu_t* emu, uintptr_t addr);
 #define x87_purgecache  STEPNAME(x87_purgecache)
 #define sse_purgecache  STEPNAME(sse_purgecache)
 #define fpu_reflectcache STEPNAME(fpu_reflectcache)
+#define fpu_unreflectcache STEPNAME(fpu_unreflectcache)
 
 #define CacheTransform       STEPNAME(CacheTransform)
 #define rv64_move64     STEPNAME(rv64_move64)
@@ -991,6 +992,7 @@ void mmx_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1);
 // purge x87 cache
 void x87_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1, int s2, int s3);
 void fpu_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3);
+void fpu_unreflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3);
 void fpu_pushcache(dynarec_rv64_t* dyn, int ninst, int s1, int not07);
 void fpu_popcache(dynarec_rv64_t* dyn, int ninst, int s1, int not07);