about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-03-08 22:38:22 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-03-08 22:38:22 +0100
commitb1106231033e8d421d8f053c838a30602cf98c23 (patch)
tree6ce8d160de60f70a79bd9a21efbc3d1c4f602767 /src
parent35c1f97115c52e4e64a75056c09fca896afff0a5 (diff)
downloadbox64-b1106231033e8d421d8f053c838a30602cf98c23.tar.gz
box64-b1106231033e8d421d8f053c838a30602cf98c23.zip
[ARM64_DYNAREC] Improced arch_build helpers function to only compute build steps 1 time per dynablock
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_arch.c72
-rw-r--r--src/dynarec/arm64/dynarec_arm64_arch.h2
-rw-r--r--src/dynarec/dynarec_arch.h6
-rw-r--r--src/dynarec/dynarec_native.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_arch.c3
-rw-r--r--src/dynarec/rv64/dynarec_rv64_arch.h2
6 files changed, 53 insertions, 36 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_arch.c b/src/dynarec/arm64/dynarec_arm64_arch.c
index ab927ef0..020d1d85 100644
--- a/src/dynarec/arm64/dynarec_arm64_arch.c
+++ b/src/dynarec/arm64/dynarec_arm64_arch.c
@@ -13,6 +13,7 @@
 #include "dynarec/dynablock_private.h"
 #include "dynarec_arm64_arch.h"
 #include "dynarec_arm64_functions.h"
+#include "dynarec_native.h"
 
 //order might be important, so define SUPER for the right one
 #define SUPER() \
@@ -81,6 +82,8 @@ typedef struct arch_build_s
     #undef GO
 } arch_build_t;
 
+static arch_build_t static_build[MAX_INSTS+2] = {0};
+
 static int arch_build(dynarec_arm_t* dyn, int ninst, arch_build_t* arch)
 {
     memset(arch, 0, sizeof(arch_build_t));
@@ -158,28 +161,43 @@ static int arch_build(dynarec_arm_t* dyn, int ninst, arch_build_t* arch)
     return arch->flags + arch->x87 + arch->mmx + arch->sse + arch->ymm + arch->unaligned;
 }
 
+static int sizeof_arch(arch_arch_t* arch)
+{
+    int sz = sizeof(arch_arch_t);
+    #define GO(A)   if(arch->A) sz+=sizeof(arch_##A##_t);
+    SUPER()
+    #undef GO
+    return sz;
+}
+
+static int sizeof_arch_build(arch_build_t* build)
+{
+    int sz = sizeof(arch_arch_t);
+    #define GO(A)   if(build->A) sz+=sizeof(arch_##A##_t);
+    SUPER()
+    #undef GO
+    return sz;
+}
+
 size_t get_size_arch(dynarec_arm_t* dyn)
 {
-    arch_build_t build = {0};
-    arch_build_t previous = {0};
+    arch_build_t* previous = NULL;
     size_t sz = 0;
     int seq = 0;
     int nseq = 0;
     int last = 0;
     if(!dyn->size) return 0;
     for(int i=0; i<dyn->size; ++i) {
-        last = arch_build(dyn, i, &build);
-        if((!memcmp(&build, &previous, sizeof(arch_build_t))) && (seq<((1<<10)-1)) && i) {
+        arch_build_t* build = static_build+i;
+        last = arch_build(dyn, i, build);
+        if(i && (!memcmp(build, previous, sizeof(arch_build_t))) && (seq<((1<<10)-1))) {
             // same sequence, increment
             ++seq;
         } else {
             seq = 0;
             ++nseq;
-            memcpy(&previous, &build, sizeof(arch_build_t));
-            sz+=sizeof(arch_arch_t);
-            #define GO(A) if(build.A) sz+=sizeof(arch_##A##_t);
-            SUPER()
-            #undef GO
+            previous = build;
+            sz += sizeof_arch_build(build);
         }
     }
     if(nseq==1 && !last)
@@ -196,45 +214,43 @@ static void build_next(arch_arch_t* arch, arch_build_t* build)
     arch->seq = 0;
     void* p = ((void*)arch)+sizeof(arch_arch_t);
     #define GO(A)                                           \
-    if(arch->A) {                                           \
-        memcpy(p, &build->A##_, sizeof(arch_ ##A##_t));     \
+    if(build->A) {                                          \
+        memcpy(p, &(build->A##_), sizeof(arch_ ##A##_t));   \
         p+=sizeof(arch_##A##_t);                            \
     }
     SUPER()
     #undef GO
 }
 
-static int sizeof_arch(arch_arch_t* arch)
+void* populate_arch(dynarec_arm_t* dyn, void* p, size_t tot_sz)
 {
-    int sz = sizeof(arch_arch_t);
-    #define GO(A)   if(arch->A) sz+=sizeof(arch_##A##_t);
-    SUPER()
-    #undef GO
-    return sz;
-}
-
-void populate_arch(dynarec_arm_t* dyn, void* p)
-{
-    arch_build_t build = {0};
-    arch_build_t previous = {0};
+    arch_build_t* previous = NULL;
     arch_arch_t* arch = p;
     arch_arch_t* next = p;
     int seq = 0;
+    size_t total = 0;
+    if(!tot_sz) return NULL;
     for(int i=0; i<dyn->size; ++i) {
-        arch_build(dyn, i, &build);
-        if((!memcmp(&build, &previous, sizeof(arch_build_t))) && (seq<((1<<10)-1)) && i) {
+        arch_build_t* build = static_build+i;
+        if(i && (!memcmp(build, previous, sizeof(arch_build_t))) && (seq<((1<<10)-1))) {
             // same sequence, increment
             seq++;
             arch->seq = seq;
         } else {
+            int sz = sizeof_arch_build(build);
+            if(total+sz>tot_sz) {
+                printf_log(LOG_INFO, "Warning: populate_arch oversized\n");
+                return NULL;
+            }
             arch = next;
-            build_next(arch, &build);
+            build_next(arch, build);
             seq = 0;
-            memcpy(&previous, &build, sizeof(arch_build_t));
-            int sz = sizeof_arch(arch);
+            previous = build;
+            total += sz;
             next = (arch_arch_t*)((uintptr_t)arch+sz);
         }
     }
+    return p;
 }
 
 int getX64AddressInst(dynablock_t* db, uintptr_t x64pc); // define is signal.c
diff --git a/src/dynarec/arm64/dynarec_arm64_arch.h b/src/dynarec/arm64/dynarec_arm64_arch.h
index 308e2e45..955114e8 100644
--- a/src/dynarec/arm64/dynarec_arm64_arch.h
+++ b/src/dynarec/arm64/dynarec_arm64_arch.h
@@ -12,7 +12,7 @@
 // get size of arch specific info (can be 0)
 size_t get_size_arch(dynarec_arm_t* dyn);
 //populate the array
-void populate_arch(dynarec_arm_t* dyn, void* p);
+void* populate_arch(dynarec_arm_t* dyn, void* p, size_t sz);
 //adjust flags and more
 void adjust_arch(dynablock_t* db, x64emu_t* emu, ucontext_t* p, uintptr_t x64pc);
 // get if instruction can be regenerated for unaligned access
diff --git a/src/dynarec/dynarec_arch.h b/src/dynarec/dynarec_arch.h
index a1af30c4..679e2f1b 100644
--- a/src/dynarec/dynarec_arch.h
+++ b/src/dynarec/dynarec_arch.h
@@ -26,7 +26,7 @@
 #define PREUPDATE_SPECIFICS(A)

 

 #define ARCH_SIZE(A)    get_size_arch(A)

-#define ARCH_FILL(A, B) populate_arch(A, B)

+#define ARCH_FILL(A, B, C) populate_arch(A, B, C)

 #define ARCH_ADJUST(A, B, C, D) adjust_arch(A, B, C, D)

 #define STOP_NATIVE_FLAGS(A, B)   A->insts[B].nat_flags_op = NAT_FLAG_OP_UNUSABLE

 #define ARCH_UNALIGNED(A, B) arch_unaligned(A, B)

@@ -53,7 +53,7 @@
 #define PREUPDATE_SPECIFICS(A) updateNativeFlags(A)

 

 #define ARCH_SIZE(A)    0

-#define ARCH_FILL(A, B)  {}

+#define ARCH_FILL(A, B, C)  {}

 #define ARCH_ADJUST(A, B, C, D) {}

 #define STOP_NATIVE_FLAGS(A, B) {}

 #define ARCH_UNALIGNED(A, B) 0

@@ -83,7 +83,7 @@
 #define PREUPDATE_SPECIFICS(A) updateNativeFlags(A)

 

 #define ARCH_SIZE(A)    get_size_arch(A)

-#define ARCH_FILL(A, B) populate_arch(A, B)

+#define ARCH_FILL(A, B, C) populate_arch(A, B, C)

 #define ARCH_ADJUST(A, B, C, D) {}

 #define STOP_NATIVE_FLAGS(A, B) {}

 #define ARCH_UNALIGNED(A, B) arch_unaligned(A, B)

diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index 62081334..678f5426 100644
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -821,9 +821,9 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
     block->dirty = block->always_test;
     block->is32bits = is32bits;
     if(arch_size) {
-        block->arch = arch;
         block->arch_size = arch_size;
-        ARCH_FILL(&helper, arch);
+        block->arch = ARCH_FILL(&helper, arch, arch_size);
+        if(!block->arch) block->arch_size = 0;
     } else {
         block->arch = NULL;
         block->arch_size = arch_size;
diff --git a/src/dynarec/rv64/dynarec_rv64_arch.c b/src/dynarec/rv64/dynarec_rv64_arch.c
index 25555c1f..df4ca848 100644
--- a/src/dynarec/rv64/dynarec_rv64_arch.c
+++ b/src/dynarec/rv64/dynarec_rv64_arch.c
@@ -144,7 +144,7 @@ static int sizeof_arch(arch_arch_t* arch)
     return sz;
 }
 
-void populate_arch(dynarec_rv64_t* dyn, void* p)
+void* populate_arch(dynarec_rv64_t* dyn, void* p, size_t sz)
 {
     arch_build_t build = {0};
     arch_build_t previous = {0};
@@ -166,6 +166,7 @@ void populate_arch(dynarec_rv64_t* dyn, void* p)
             next = (arch_arch_t*)((uintptr_t)arch+sz);
         }
     }
+    return p;
 }
 
 int getX64AddressInst(dynablock_t* db, uintptr_t x64pc); // define is signal.c
diff --git a/src/dynarec/rv64/dynarec_rv64_arch.h b/src/dynarec/rv64/dynarec_rv64_arch.h
index 2045da64..814918be 100644
--- a/src/dynarec/rv64/dynarec_rv64_arch.h
+++ b/src/dynarec/rv64/dynarec_rv64_arch.h
@@ -12,7 +12,7 @@
 // get size of arch specific info (can be 0)
 size_t get_size_arch(dynarec_rv64_t* dyn);
 //populate the array
-void populate_arch(dynarec_rv64_t* dyn, void* p);
+void* populate_arch(dynarec_rv64_t* dyn, void* p, size_t sz);
 //adjust flags and more
 void adjust_arch(dynablock_t* db, x64emu_t* emu, ucontext_t* p, uintptr_t x64pc);
 // get if instruction can be regenerated for unaligned access