diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-03-08 22:38:22 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-03-08 22:38:22 +0100 |
| commit | b1106231033e8d421d8f053c838a30602cf98c23 (patch) | |
| tree | 6ce8d160de60f70a79bd9a21efbc3d1c4f602767 /src | |
| parent | 35c1f97115c52e4e64a75056c09fca896afff0a5 (diff) | |
| download | box64-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.c | 72 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_arch.h | 2 | ||||
| -rw-r--r-- | src/dynarec/dynarec_arch.h | 6 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_arch.c | 3 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_arch.h | 2 |
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 |