about summary refs log tree commit diff stats
path: root/src/dynarec/dynarec_native_pass.c
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-12-12 12:42:22 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-12-12 12:42:22 +0100
commit99a938ef379192005943ecc76ba6245ebee4016d (patch)
treefab3458b2f097d7e66aa1037acddfab7edd28b42 /src/dynarec/dynarec_native_pass.c
parentb07ea3460ea337f6ac45d6ea53d0c890923d408e (diff)
downloadbox64-99a938ef379192005943ecc76ba6245ebee4016d.tar.gz
box64-99a938ef379192005943ecc76ba6245ebee4016d.zip
[DYNAREC] New attempt to make callret optim stable and usable
Diffstat (limited to 'src/dynarec/dynarec_native_pass.c')
-rw-r--r--src/dynarec/dynarec_native_pass.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c
index b6b31c12..e67a9848 100644
--- a/src/dynarec/dynarec_native_pass.c
+++ b/src/dynarec/dynarec_native_pass.c
@@ -77,6 +77,9 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
             dyn->last_ip = 0;   // reset IP if some jump are coming here
         fpu_propagate_stack(dyn, ninst);
         NEW_INST;
+        if(ninst && dyn->insts[ninst-1].x64.barrier_next) {
+            BARRIER(dyn->insts[ninst-1].x64.barrier_next);
+        }
         if(!ninst) {
             GOTEST(x1, x2);
         }
@@ -178,7 +181,9 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
         if(dyn->forward) {
             if(dyn->forward_to == addr && !need_epilog) {
                 // we made it!
-                if(box64_dynarec_dump) dynarec_log(LOG_NONE, "Forward extend block for %d bytes %p -> %p\n", dyn->forward_to-dyn->forward, (void*)dyn->forward, (void*)dyn->forward_to);
+                if(box64_dynarec_dump) dynarec_log(LOG_NONE, "Forward extend block for %d bytes %s%p -> %p\n", dyn->forward_to-dyn->forward, dyn->insts[dyn->forward_ninst].x64.has_callret?"(opt. call) ":"", (void*)dyn->forward, (void*)dyn->forward_to);
+                if(dyn->insts[dyn->forward_ninst].x64.has_callret && !dyn->insts[dyn->forward_ninst].x64.has_next)
+                    dyn->insts[dyn->forward_ninst].x64.has_next = 1;  // this block actually continue
                 dyn->forward = 0;
                 dyn->forward_to = 0;
                 dyn->forward_size = 0;
@@ -205,14 +210,18 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
                     /*||(((next-addr)<30) && is_instructions(dyn, addr, next-addr))*/ ))
                 {
                     ok = 1;
-                    // need to find back that instruction to copy the caches, as previous version cannot be used anymore
-                    reset_n = -2;
-                    for(int ii=0; ii<ninst; ++ii)
-                        if(dyn->insts[ii].x64.jmp == next) {
-                            reset_n = ii;
-                            ii=ninst;
-                        }
-                    if(box64_dynarec_dump) dynarec_log(LOG_NONE, "Extend block %p, %p -> %p (ninst=%d, jump from %d)\n", dyn, (void*)addr, (void*)next, ninst, reset_n);
+                    if(dyn->insts[ninst].x64.has_callret && !dyn->insts[ninst].x64.has_next) {
+                        dyn->insts[ninst].x64.has_next = 1;  // this block actually continue
+                    } else {
+                        // need to find back that instruction to copy the caches, as previous version cannot be used anymore
+                        reset_n = -2;
+                        for(int ii=0; ii<ninst; ++ii)
+                            if(dyn->insts[ii].x64.jmp == next) {
+                                reset_n = ii;
+                                ii=ninst;
+                            }
+                    }
+                    if(box64_dynarec_dump) dynarec_log(LOG_NONE, "Extend block %p, %s%p -> %p (ninst=%d, jump from %d)\n", dyn, dyn->insts[ninst].x64.has_callret?"(opt. call) ":"", (void*)addr, (void*)next, ninst, dyn->insts[ninst].x64.has_callret?ninst:reset_n);
                 } else if(next && (next-addr)<box64_dynarec_forward && (getProtection(next)&PROT_READ)/*box64_dynarec_bigblock>=stopblock*/) {
                     if(!((box64_dynarec_bigblock<stopblock) && !isJumpTableDefault64((void*)next))) {
                         if(dyn->forward) {