about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-04-11 11:14:18 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-04-11 11:14:18 +0200
commit7d11254a526635d9305ab36e45bdbafdded42752 (patch)
tree429961bb018e655156ce56622add388091143ac2 /src
parent3b9feeed120af45a2dc346592b328eb0b2e14911 (diff)
downloadbox64-7d11254a526635d9305ab36e45bdbafdded42752.tar.gz
box64-7d11254a526635d9305ab36e45bdbafdded42752.zip
[DYNAREC] Improved (and fixed) Table64 handling
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec_arm64.c17
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h10
-rwxr-xr-xsrc/dynarec/dynarec_arm64_pass2.h2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_pass3.h2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_private.h1
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;