about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-02-11 16:52:51 +0100
committerptitSeb <sebastien.chev@gmail.com>2022-02-11 16:52:51 +0100
commit27a07d23d7fe45e35c5b6d0e47f8ab96d91b1d00 (patch)
tree9e69f17d69efbc6c4ec95e3b0eced4d3a8b5c448 /src
parent30050fd7ecb43cac6a8e632c538b8c01cfd247cd (diff)
downloadbox64-27a07d23d7fe45e35c5b6d0e47f8ab96d91b1d00.tar.gz
box64-27a07d23d7fe45e35c5b6d0e47f8ab96d91b1d00.zip
[DYNAREC] Fixed an optimisation (intra-dynablock jump) that was broken for a long time (mora than 10% perf gain on '7z b')
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec_arm64.c3
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c10
-rw-r--r--src/dynarec/dynarec_arm64_64.c2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_pass.c9
-rwxr-xr-xsrc/dynarec/dynarec_arm64_pass0.h10
-rwxr-xr-xsrc/dynarec/dynarec_arm64_pass1.h8
6 files changed, 22 insertions, 20 deletions
diff --git a/src/dynarec/dynarec_arm64.c b/src/dynarec/dynarec_arm64.c
index a24ddce7..18e05bce 100755
--- a/src/dynarec/dynarec_arm64.c
+++ b/src/dynarec/dynarec_arm64.c
@@ -402,10 +402,11 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
             else {
                 // find jump address instruction
                 int k=-1;
-                for(int i2=0; i2<helper.size && k==-1; ++i2) {
+                for(int i2=0; (i2<helper.size) && (k==-1); ++i2) {
                     if(helper.insts[i2].x64.addr==j)
                         k=i2;
                 }
+
                 if(k!=-1)   // -1 if not found, mmm, probably wrong, exit anyway
                     helper.insts[k].x64.barrier = 1;
                 helper.insts[i].x64.jmp_insts = k;
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index c4c8a5f2..28720e31 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -2092,7 +2092,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 default:
-                    if(ninst && dyn->insts && dyn->insts[ninst-1].x64.set_flags) {
+                    if(ninst && dyn->insts[ninst-1].x64.set_flags) {
                         READFLAGS(X_PEND);  // that's suspicious
                     } else {
                         SETFLAGS(X_ALL, SF_SET);    // Hack to set flags to "dont'care" state
@@ -2100,10 +2100,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     // regular call
                     BARRIER(1);
                     BARRIER_NEXT(1);
-                    if(!dyn->insts || ninst==dyn->size-1) {
-                        *need_epilog = 0;
-                        *ok = 0;
-                    }
+                    *need_epilog = 0;
+                    *ok = 0;
                     TABLE64(x2, addr);
                     PUSH1(x2);
                     if(addr+i32==0) {   // self modifying code maybe? so use indirect address fetching
@@ -2291,7 +2289,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         MOVw_REG(xRAX, x2);
                         MOVw_REG(xRDX, x4);
                     } else {
-                        if(ninst && dyn->insts 
+                        if(ninst 
                            && dyn->insts[ninst-1].x64.addr 
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x31 
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0xD2) {
diff --git a/src/dynarec/dynarec_arm64_64.c b/src/dynarec/dynarec_arm64_64.c
index ba283920..871d0e20 100644
--- a/src/dynarec/dynarec_arm64_64.c
+++ b/src/dynarec/dynarec_arm64_64.c
@@ -752,7 +752,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         MOVw_REG(xRAX, x2);
                         MOVw_REG(xRDX, x4);
                     } else {
-                        if(ninst && dyn->insts 
+                        if(ninst
                            && dyn->insts[ninst-1].x64.addr 
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x31 
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0xD2) {
diff --git a/src/dynarec/dynarec_arm64_pass.c b/src/dynarec/dynarec_arm64_pass.c
index 8bc587f7..c4a31aaf 100755
--- a/src/dynarec/dynarec_arm64_pass.c
+++ b/src/dynarec/dynarec_arm64_pass.c
@@ -99,9 +99,6 @@ uintptr_t arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
                 dyn->dfnone = 0;
             }
         }
-        if(!ok && !need_epilog && (addr < (dyn->start+dyn->isize))) {
-            ok = 1;
-        }
         #if STEP == 0
         if(!ok && !need_epilog && box64_dynarec_bigblock && getProtection(addr+3)&~PROT_CUSTOM && !IsInHotPage(addr+3))
             if(*(uint32_t*)addr!=0) {   // check if need to continue (but is next 4 bytes are 0, stop)
@@ -116,13 +113,17 @@ uintptr_t arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
                     dynarec_log(LOG_DEBUG, "Cannot extend block %p -> %p (%02X %02X %02X %02X %02X %02X %02X %02x)\n", (void*)addr, (void*)next, PK(0), PK(1), PK(2), PK(3), PK(4), PK(5), PK(6), PK(7));
                 }
             }
+        #else
+        if(!ok && !need_epilog && (addr < (dyn->start+dyn->isize))) {
+            ok = 1;
+        }
         #endif
         if(ok<0)  {ok = 0; need_epilog=1;}
         ++ninst;
         #if STEP == 0
         if(ok && !isJumpTableDefault64((void*)addr))
         #else
-        if(ok && dyn->insts && (ninst==dyn->size))
+        if(ok && (ninst==dyn->size))
         #endif
         {
             #if STEP == 3
diff --git a/src/dynarec/dynarec_arm64_pass0.h b/src/dynarec/dynarec_arm64_pass0.h
index 98d683ab..d4818ac5 100755
--- a/src/dynarec/dynarec_arm64_pass0.h
+++ b/src/dynarec/dynarec_arm64_pass0.h
@@ -1,6 +1,10 @@
 
 #define INIT    uintptr_t sav_addr=addr
-#define FINI    dyn->isize = addr-sav_addr
+#define FINI    \
+    dyn->isize = addr-sav_addr;         \
+    dyn->insts[ninst].x64.addr = addr;  \
+    if(ninst) dyn->insts[ninst-1].x64.size = dyn->insts[ninst].x64.addr - dyn->insts[ninst-1].x64.addr
+
 #define MESSAGE(A, ...)  
 #define SETFLAGS(A, B)  
 #define READFLAGS(A)    
@@ -14,7 +18,9 @@
                 memset(&dyn->insts[dyn->cap], 0, sizeof(instruction_arm64_t)*dyn->cap);   \
                 dyn->cap *= 2;                  \
         }                                       \
-        ++dyn->size
+        ++dyn->size;                            \
+        dyn->insts[ninst].x64.addr = ip;        \
+        if(ninst) dyn->insts[ninst-1].x64.size = dyn->insts[ninst].x64.addr - dyn->insts[ninst-1].x64.addr
 #define INST_EPILOG         
 #define INST_NAME(name) 
 #define DEFAULT                         \
diff --git a/src/dynarec/dynarec_arm64_pass1.h b/src/dynarec/dynarec_arm64_pass1.h
index 20534879..a4abcf19 100755
--- a/src/dynarec/dynarec_arm64_pass1.h
+++ b/src/dynarec/dynarec_arm64_pass1.h
@@ -1,14 +1,10 @@
 #define INIT    
-#define FINI     \
-    dyn->insts[ninst].x64.addr = addr; \
-    if(ninst) dyn->insts[ninst-1].x64.size = dyn->insts[ninst].x64.addr - dyn->insts[ninst-1].x64.addr;
+#define FINI
 #define MESSAGE(A, ...)  
 #define EMIT(A)     
 #define READFLAGS(A)    dyn->insts[ninst].x64.use_flags = A
 #define SETFLAGS(A,B)   {dyn->insts[ninst].x64.set_flags = A; dyn->insts[ninst].x64.state_flags = B;}
 
-#define NEW_INST \
-    dyn->insts[ninst].x64.addr = ip; \
-    if(ninst) dyn->insts[ninst-1].x64.size = dyn->insts[ninst].x64.addr - dyn->insts[ninst-1].x64.addr;
+#define NEW_INST
 #define INST_EPILOG
 #define INST_NAME(name)