diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-04-11 11:14:18 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-04-11 11:14:18 +0200 |
| commit | 7d11254a526635d9305ab36e45bdbafdded42752 (patch) | |
| tree | 429961bb018e655156ce56622add388091143ac2 /src | |
| parent | 3b9feeed120af45a2dc346592b328eb0b2e14911 (diff) | |
| download | box64-7d11254a526635d9305ab36e45bdbafdded42752.tar.gz box64-7d11254a526635d9305ab36e45bdbafdded42752.zip | |
[DYNAREC] Improved (and fixed) Table64 handling
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/dynarec_arm64.c | 17 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 10 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_pass2.h | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_pass3.h | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_private.h | 1 |
5 files changed, 23 insertions, 9 deletions
diff --git a/src/dynarec/dynarec_arm64.c b/src/dynarec/dynarec_arm64.c index 99f8c604..7855f4be 100755 --- a/src/dynarec/dynarec_arm64.c +++ b/src/dynarec/dynarec_arm64.c @@ -315,8 +315,11 @@ int Table64(dynarec_arm_t *dyn, uint64_t val) idx = i; // not found, add it if(idx==-1) { + if(dyn->table64size == dyn->table64cap) { + dyn->table64cap+=4; + dyn->table64 = (uint64_t*)realloc(dyn->table64, dyn->table64cap * sizeof(uint64_t)); + } idx = dyn->table64size++; - dyn->table64 = (uint64_t*)realloc(dyn->table64, dyn->table64size * sizeof(uint64_t)); dyn->table64[idx] = val; } // calculate offset @@ -402,10 +405,12 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) { printFunctionAddr(helper.start, " => "); dynarec_log(LOG_NONE, "%s\n", (box64_dynarec_dump>1)?"\e[m":""); } - helper.arm_size = 0; int oldtable64size = helper.table64size; + int oldarmsize = helper.arm_size; + helper.arm_size = 0; + helper.table64size = 0; // reset table64 (but not the cap) arm_pass3(&helper, addr); - if(sz!=(helper.arm_size + helper.table64size*8)) { + if((oldarmsize!=helper.arm_size) || (oldtable64size<helper.table64size)) { printf_log(LOG_NONE, "BOX64: Warning, size difference in block between pass2 (%d) & pass3 (%d)!\n", sz, helper.arm_size+helper.table64size*8); uint8_t *dump = (uint8_t*)helper.start; printf_log(LOG_NONE, "Dump of %d x64 opcodes:\n", helper.size); @@ -417,10 +422,11 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) { } printf_log(LOG_NONE, "Table64 \t%d -> %d\n", oldtable64size*8, helper.table64size*8); printf_log(LOG_NONE, " ------------\n"); + //TODO: Cancel block and return empty one } // add table64 if needed if(helper.table64size) { - memcpy(p+helper.arm_size, helper.table64, helper.table64size*8); + memcpy((void*)helper.tablestart, helper.table64, helper.table64size*8); } // all done... __clear_cache(p, p+sz); // need to clear the cache before execution... @@ -471,9 +477,10 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) { son->father = block; son->size = sz + son->block - block->block; // update size count, for debugging son->done = 1; - sons[sons_size++] = son; if(!son->parent) son->parent = block->parent; + sons[sons_size] = son; + ++sons_size; } } if(sons_size) { diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index 4050f47b..a86fdca5 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -537,14 +537,20 @@ } \ } else { \ dyn->last_ip = (A); \ - TABLE64(xRIP, dyn->last_ip); \ + if(dyn->last_ip<0xffffffff) { \ + MOV64x(xRIP, dyn->last_ip); \ + } else \ + TABLE64(xRIP, dyn->last_ip); \ } #define GETIP_(A) \ if(dyn->last_ip && ((A)-dyn->last_ip)<0x1000) { \ uint64_t _delta_ip = (A)-dyn->last_ip; \ if(_delta_ip) {ADDx_U12(xRIP, xRIP, _delta_ip);}\ } else { \ - TABLE64(xRIP, (A)); \ + if((A)<0xffffffff) { \ + MOV64x(xRIP, (A)); \ + } else \ + TABLE64(xRIP, (A)); \ } #endif diff --git a/src/dynarec/dynarec_arm64_pass2.h b/src/dynarec/dynarec_arm64_pass2.h index d5d039e5..1be5a0de 100755 --- a/src/dynarec/dynarec_arm64_pass2.h +++ b/src/dynarec/dynarec_arm64_pass2.h @@ -7,5 +7,5 @@ #define INST_EPILOG dyn->insts[ninst].epilog = dyn->arm_size; #define INST_NAME(name) #define NEW_BARRIER_INST if(ninst) ++dyn->sons_size -#define TABLE64(A, V) if((V)>0xffffffffLL) {Table64(dyn, (V)); EMIT(0);} else {MOV64x(A, V);} +#define TABLE64(A, V) {Table64(dyn, (V)); EMIT(0);} #define FTABLE64(A, V) {mmx87_regs_t v = {.d = V}; Table64(dyn, v.q); EMIT(0);} \ No newline at end of file diff --git a/src/dynarec/dynarec_arm64_pass3.h b/src/dynarec/dynarec_arm64_pass3.h index cb6891d4..25b852e3 100755 --- a/src/dynarec/dynarec_arm64_pass3.h +++ b/src/dynarec/dynarec_arm64_pass3.h @@ -32,5 +32,5 @@ ++dyn->sons_size; \ } -#define TABLE64(A, V) if((V)>0xffffffffLL) {int val64offset = Table64(dyn, (V)); MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); LDRx_literal(A, val64offset);} else {MOV64x(A, V);} +#define TABLE64(A, V) {int val64offset = Table64(dyn, (V)); MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); LDRx_literal(A, val64offset);} #define FTABLE64(A, V) {mmx87_regs_t v = {.d = V}; int val64offset = Table64(dyn, v.q); MESSAGE(LOG_DUMP, " FTable64: %g\n", v.d); VLDR64_literal(A, val64offset);} \ No newline at end of file diff --git a/src/dynarec/dynarec_arm64_private.h b/src/dynarec/dynarec_arm64_private.h index 9cadbc63..d1ad28bd 100755 --- a/src/dynarec/dynarec_arm64_private.h +++ b/src/dynarec/dynarec_arm64_private.h @@ -42,6 +42,7 @@ typedef struct dynarec_arm_s { int dfnone; // if defered flags is already set to df_none uint64_t *table64; // table of 64bits value int table64size;// size of table (will be appended at end of executable code) + int table64cap; uintptr_t tablestart; uintptr_t* next; // variable array of "next" jump address int next_sz; |