diff options
Diffstat (limited to 'src/dynarec')
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_pass2.h | 4 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_pass3.h | 7 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_private.h | 4 | ||||
| -rwxr-xr-x | src/dynarec/dynablock.c | 129 | ||||
| -rwxr-xr-x | src/dynarec/dynablock_private.h | 5 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_native.c | 82 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_pass2.h | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_pass3.h | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_private.h | 4 |
9 files changed, 155 insertions, 88 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_pass2.h b/src/dynarec/arm64/dynarec_arm64_pass2.h index 57a37572..86692795 100755 --- a/src/dynarec/arm64/dynarec_arm64_pass2.h +++ b/src/dynarec/arm64/dynarec_arm64_pass2.h @@ -14,5 +14,5 @@ } #define INST_EPILOG dyn->insts[ninst].epilog = dyn->native_size; #define INST_NAME(name) -#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 +#define TABLE64(A, V) {Table64(dyn, (V), 2); EMIT(0);} +#define FTABLE64(A, V) {mmx87_regs_t v = {.d = V}; Table64(dyn, v.q, 2); EMIT(0);} \ No newline at end of file diff --git a/src/dynarec/arm64/dynarec_arm64_pass3.h b/src/dynarec/arm64/dynarec_arm64_pass3.h index c39aa5e4..bdc41db9 100755 --- a/src/dynarec/arm64/dynarec_arm64_pass3.h +++ b/src/dynarec/arm64/dynarec_arm64_pass3.h @@ -6,7 +6,8 @@ #define EMIT(A) \ do{ \ if(box64_dynarec_dump) print_opcode(dyn, ninst, (uint32_t)(A)); \ - *(uint32_t*)(dyn->block) = (uint32_t)(A); \ + if((uintptr_t)dyn->block<dyn->tablestart) \ + *(uint32_t*)(dyn->block) = (uint32_t)(A); \ dyn->block += 4; dyn->native_size += 4; \ dyn->insts[ninst].size2 += 4; \ }while(0) @@ -17,5 +18,5 @@ addInst(dyn->instsize, &dyn->insts_size, dyn->insts[ninst-1].x64.size, dyn->insts[ninst-1].size/4); #define INST_EPILOG #define INST_NAME(name) inst_name_pass3(dyn, ninst, name) -#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);} +#define TABLE64(A, V) {int val64offset = Table64(dyn, (V), 3); 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, 3); MESSAGE(LOG_DUMP, " FTable64: %g\n", v.d); VLDR64_literal(A, val64offset);} diff --git a/src/dynarec/arm64/dynarec_arm64_private.h b/src/dynarec/arm64/dynarec_arm64_private.h index 15705634..be57a790 100755 --- a/src/dynarec/arm64/dynarec_arm64_private.h +++ b/src/dynarec/arm64/dynarec_arm64_private.h @@ -95,6 +95,7 @@ typedef struct dynarec_arm_s { int table64size;// size of table (will be appended at end of executable code) int table64cap; uintptr_t tablestart; + uintptr_t jmp_next; // address of the jump_next address flagcache_t f; neoncache_t n; // cache for the 8..31 double reg from fpu, plus x87 stack delta uintptr_t* next; // variable array of "next" jump address @@ -112,6 +113,7 @@ typedef struct dynarec_arm_s { int forward_ninst; // ninst at the forward point uint8_t doublepush; uint8_t doublepop; + uint8_t always_test; } dynarec_arm_t; void add_next(dynarec_arm_t *dyn, uintptr_t addr); @@ -119,7 +121,7 @@ uintptr_t get_closest_next(dynarec_arm_t *dyn, uintptr_t addr); int is_nops(dynarec_arm_t *dyn, uintptr_t addr, int n); int is_instructions(dynarec_arm_t *dyn, uintptr_t addr, int n); -int Table64(dynarec_arm_t *dyn, uint64_t val); // add a value to etable64 (if needed) and gives back the imm19 to use in LDR_literal +int Table64(dynarec_arm_t *dyn, uint64_t val, int pass); // add a value to etable64 (if needed) and gives back the imm19 to use in LDR_literal void CreateJmpNext(void* addr, void* next); diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index 17c6aa0c..d5c95111 100755 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -37,6 +37,39 @@ uint32_t X31_hash_code(void* addr, int len) return (uint32_t)h; } +dynablock_t* InvalidDynablock(dynablock_t* db, int need_lock) +{ + if(db) { + if(db->gone) + return NULL; // already in the process of deletion! + dynarec_log(LOG_DEBUG, "InvalidDynablock(%p), db->block=%p x64=%p:%p already gone=%d\n", db, db->block, db->x64_addr, db->x64_addr+db->x64_size-1, db->gone); + if(need_lock) + mutex_lock(&my_context->mutex_dyndump); + // remove jumptable + setJumpTableDefault64(db->x64_addr); + db->done = 0; + db->gone = 1; + if(need_lock) + mutex_unlock(&my_context->mutex_dyndump); + } + return db; +} + +void FreeInvalidDynablock(dynablock_t* db, int need_lock) +{ + if(db) { + if(!db->gone) + return; // already in the process of deletion! + dynarec_log(LOG_DEBUG, "FreeInvalidDynablock(%p), db->block=%p x64=%p:%p already gone=%d\n", db, db->block, db->x64_addr, db->x64_addr+db->x64_size-1, db->gone); + if(need_lock) + mutex_lock(&my_context->mutex_dyndump); + FreeDynarecMap((uintptr_t)db->actual_block); + customFree(db); + if(need_lock) + mutex_unlock(&my_context->mutex_dyndump); + } +} + void FreeDynablock(dynablock_t* db, int need_lock) { if(db) { @@ -50,6 +83,8 @@ void FreeDynablock(dynablock_t* db, int need_lock) dynarec_log(LOG_DEBUG, " -- FreeDyrecMap(%p, %d)\n", db->actual_block, db->size); db->done = 0; db->gone = 1; + if(db->previous) + FreeInvalidDynablock(db->previous, 0); FreeDynarecMap((uintptr_t)db->actual_block); customFree(db); if(need_lock) @@ -57,14 +92,26 @@ void FreeDynablock(dynablock_t* db, int need_lock) } } + + void MarkDynablock(dynablock_t* db) { if(db) { - if(db->need_test) - return; // already done dynarec_log(LOG_DEBUG, "MarkDynablock %p %p-%p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1); - db->need_test = 1; - setJumpTableIfRef64(db->x64_addr, db->jmpnext, db->block); + if(!setJumpTableIfRef64(db->x64_addr, db->jmpnext, db->block)) { + dynablock_t* old = db; + db = getDB((uintptr_t)old->x64_addr); + if(!old->gone && db!=old) { + printf_log(LOG_INFO, "Warning, couldn't mark block as dirty for %p, block=%p, current_block=%p\n", old->x64_addr, old, db); + // the block is lost, need to invalidate it... + old->gone = 1; + old->done = 0; + if(!db || db->previous) + FreeInvalidDynablock(old, 1); + else + db->previous = old; + } + } } } @@ -78,7 +125,7 @@ static int IntervalIntersects(uintptr_t start1, uintptr_t end1, uintptr_t start2 static int MarkedDynablock(dynablock_t* db) { if(db) { - if(db->need_test) + if(getNeedTest((uintptr_t)db->x64_addr)) return 1; // already done } return 0; @@ -90,9 +137,8 @@ void MarkRangeDynablock(dynablock_t* db, uintptr_t addr, uintptr_t size) if(!db) return; dynarec_log(LOG_DEBUG, "MarkRangeDynablock %p-%p .. startdb=%p, sizedb=%p\n", (void*)addr, (void*)addr+size-1, (void*)db->x64_addr, (void*)db->x64_size); - if(!MarkedDynablock(db)) - if(IntervalIntersects((uintptr_t)db->x64_addr, (uintptr_t)db->x64_addr+db->x64_size-1, addr, addr+size+1)) - MarkDynablock(db); + if(IntervalIntersects((uintptr_t)db->x64_addr, (uintptr_t)db->x64_addr+db->x64_size-1, addr, addr+size+1)) + MarkDynablock(db); } int FreeRangeDynablock(dynablock_t* db, uintptr_t addr, uintptr_t size) @@ -153,13 +199,11 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t if(mutex_trylock(&my_context->mutex_dyndump)) // FillBlock not available for now return NULL; } - } - - block = getDB(addr); // just in case - if(block) { - if(need_lock) + block = getDB(addr); // just in case + if(block) { mutex_unlock(&my_context->mutex_dyndump); - return block; + return block; + } } block = AddNewDynablock(addr); @@ -184,9 +228,10 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t if(blocksz>my_context->max_db_size) my_context->max_db_size = blocksz; // fill-in jumptable - if(!addJumpTableIfDefault64(block->x64_addr, block->block)) { + if(!addJumpTableIfDefault64(block->x64_addr, block->dirty?block->jmpnext:block->block)) { FreeDynablock(block, 0); block = getDB(addr); + MarkDynablock(block); // just in case... } else { if(block->x64_size) block->done = 1; // don't validate the block if the size is null, but keep the block @@ -203,7 +248,9 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create) { dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1); - if(db && db->done && db->block && db->need_test) { + if(db && db->done && db->block && getNeedTest(addr)) { + if(db->always_test) + sched_yield(); // just calm down... if(AreaInHotPage((uintptr_t)db->x64_addr, (uintptr_t)db->x64_addr + db->x64_size - 1)) { emu->test.test = 0; if(box64_dynarec_fastpage) { @@ -221,25 +268,30 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create) } } uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size); - if(mutex_trylock(&my_context->mutex_dyndump)) { - dynarec_log(LOG_DEBUG, "mutex_dyndump not available when trying to validate block %p from %p:%p (hash:%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, (void*)addr); - return NULL; - } + int need_lock = mutex_trylock(&my_context->mutex_dyndump); if(hash!=db->hash) { db->done = 0; // invalidating the block dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, hash, db->hash, (void*)addr); // Free db, it's now invalid! - FreeDynablock(db, 0); + dynablock_t* old = InvalidDynablock(db, need_lock); // start again... (will create a new block) - db = internalDBGetBlock(emu, addr, addr, create, 0); + db = internalDBGetBlock(emu, addr, addr, create, need_lock); + if(db) { + if(db->previous) + FreeInvalidDynablock(db->previous, need_lock); + db->previous = old; + } else + FreeInvalidDynablock(old, need_lock); } else { - db->need_test = 0; dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, (void*)addr); protectDB((uintptr_t)db->x64_addr, db->x64_size); // fill back jumptable - setJumpTableIfRef64(db->x64_addr, db->block, db->jmpnext); + if(isprotectedDB((uintptr_t)db->x64_addr, db->x64_size) && !db->always_test) { + setJumpTableIfRef64(db->x64_addr, db->block, db->jmpnext); + } } - mutex_unlock(&my_context->mutex_dyndump); + if(!need_lock) + mutex_unlock(&my_context->mutex_dyndump); } if(!db || !db->block || !db->done) emu->test.test = 0; @@ -251,26 +303,33 @@ dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr) dynarec_log(LOG_DEBUG, "Creating AlternateBlock at %p for %p\n", (void*)addr, (void*)filladdr); int create = 1; dynablock_t *db = internalDBGetBlock(emu, addr, filladdr, create, 1); - if(db && db->done && db->block && db->need_test) { - if(mutex_trylock(&my_context->mutex_dyndump)) { - emu->test.test = 0; - return NULL; - } + if(db && db->done && db->block && getNeedTest(filladdr)) { + if(db->always_test) + sched_yield(); // just calm down... + int need_lock = mutex_trylock(&my_context->mutex_dyndump); uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size); if(hash!=db->hash) { db->done = 0; // invalidating the block dynarec_log(LOG_DEBUG, "Invalidating alt block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size, hash, db->hash, (void*)addr); // Free db, it's now invalid! - FreeDynablock(db, 0); + dynablock_t* old = InvalidDynablock(db, need_lock); // start again... (will create a new block) - db = internalDBGetBlock(emu, addr, filladdr, create, 0); + db = internalDBGetBlock(emu, addr, filladdr, create, need_lock); + if(db) { + if(db->previous) + FreeInvalidDynablock(db->previous, need_lock); + db->previous = old; + } else + FreeInvalidDynablock(old, need_lock); } else { - db->need_test = 0; protectDB((uintptr_t)db->x64_addr, db->x64_size); // fill back jumptable - addJumpTableIfDefault64(db->x64_addr, db->block); + if(isprotectedDB((uintptr_t)db->x64_addr, db->x64_size) && !db->always_test) { + setJumpTableIfRef64(db->x64_addr, db->block, db->jmpnext); + } } - mutex_unlock(&my_context->mutex_dyndump); + if(!need_lock) + mutex_unlock(&my_context->mutex_dyndump); } if(!db || !db->block || !db->done) emu->test.test = 0; diff --git a/src/dynarec/dynablock_private.h b/src/dynarec/dynablock_private.h index dbe8c502..18666e04 100755 --- a/src/dynarec/dynablock_private.h +++ b/src/dynarec/dynablock_private.h @@ -9,14 +9,15 @@ typedef struct instsize_s { typedef struct dynablock_s { void* block; // block-sizeof(void*) == self void* actual_block; // the actual start of the block (so block-sizeof(void*)) + struct dynablock_s* previous; // a previous block that might need to be freed int size; void* x64_addr; uintptr_t x64_size; uint32_t hash; - uint8_t need_test; uint8_t done; uint8_t gone; - uint8_t dummy; + uint8_t always_test; + uint8_t dirty; // if need to be tested as soon as it's created int isize; instsize_t* instsize; void* jmpnext; // a branch jmpnext code when block is marked diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c index c57b7d64..64d28342 100755 --- a/src/dynarec/dynarec_native.c +++ b/src/dynarec/dynarec_native.c @@ -267,7 +267,7 @@ void addInst(instsize_t* insts, size_t* size, int x64_size, int native_size) } // add a value to table64 (if needed) and gives back the imm19 to use in LDR_literal -int Table64(dynarec_native_t *dyn, uint64_t val) +int Table64(dynarec_native_t *dyn, uint64_t val, int pass) { // find the value if already present int idx = -1; @@ -278,10 +278,12 @@ int Table64(dynarec_native_t *dyn, uint64_t val) if(idx==-1) { if(dyn->table64size == dyn->table64cap) { dyn->table64cap+=16; - dyn->table64 = (uint64_t*)customRealloc(dyn->table64, dyn->table64cap * sizeof(uint64_t)); + if(pass<3) // do not resize on pass3, it's not the same type of memory anymore + dyn->table64 = (uint64_t*)customRealloc(dyn->table64, dyn->table64cap * sizeof(uint64_t)); } idx = dyn->table64size++; - dyn->table64[idx] = val; + if(dyn->table64size <= dyn->table64cap) + dyn->table64[idx] = val; } // calculate offset int delta = dyn->tablestart + idx*sizeof(uint64_t) - (uintptr_t)dyn->block; @@ -381,19 +383,17 @@ void CancelBlock64(int need_lock) mutex_lock(&my_context->mutex_dyndump); dynarec_native_t* helper = (dynarec_native_t*)current_helper; current_helper = NULL; - if(!helper) { - if(need_lock) - mutex_unlock(&my_context->mutex_dyndump); - return; + if(helper) { + customFree(helper->next); + customFree(helper->insts); + customFree(helper->predecessor); + if(helper->table64 && (helper->table64!=(uint64_t*)helper->tablestart)) + customFree(helper->table64); + if(helper->dynablock && helper->dynablock->actual_block) { + FreeDynarecMap((uintptr_t)helper->dynablock->actual_block); + helper->dynablock->actual_block = NULL; + } } - customFree(helper->next); - customFree(helper->insts); - customFree(helper->predecessor); - customFree(helper->table64); - if(helper->dynablock && helper->dynablock->actual_block) - FreeDynarecMap((uintptr_t)helper->dynablock->actual_block); - else if(helper->dynablock && helper->block) - FreeDynarecMap((uintptr_t)helper->block-sizeof(void*)); if(need_lock) mutex_unlock(&my_context->mutex_dyndump); } @@ -421,7 +421,6 @@ void* CreateEmptyBlock(dynablock_t* block, uintptr_t addr) { *(dynablock_t**)actual_p = block; *(void**)(p+2*sizeof(void*)) = native_epilog; CreateJmpNext(block->jmpnext, p+2*sizeof(void*)); - block->need_test = 0; // all done... __clear_cache(actual_p, actual_p+sz); // need to clear the cache before execution... return block; @@ -491,6 +490,8 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) { if(helper.insts[i].x64.jmp) { uintptr_t j = helper.insts[i].x64.jmp; if(j<start || j>=end || j==helper.insts[i].x64.addr) { + if(j==helper.insts[i].x64.addr) // if there is a loop on some opcode, make the block "always to tested" + helper.always_test = 1; helper.insts[i].x64.jmp_insts = -1; helper.insts[i].x64.need_after |= X_PEND; } else { @@ -525,7 +526,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) { size_t sz = sizeof(void*) + native_size + helper.table64size*sizeof(uint64_t) + 4*sizeof(void*) + insts_rsize; // dynablock_t* block (arm insts) table64 jmpnext code instsize void* actual_p = (void*)AllocDynarecMap(sz); - void* p = actual_p + sizeof(void*); + void* p = (void*)(((uintptr_t)actual_p) + sizeof(void*)); void* next = p + native_size + helper.table64size*sizeof(uint64_t); void* instsize = next + 4*sizeof(void*); if(actual_p==NULL) { @@ -534,11 +535,16 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) { return NULL; } helper.block = p; + block->actual_block = actual_p; helper.native_start = (uintptr_t)p; helper.tablestart = helper.native_start + native_size; + helper.jmp_next = (uintptr_t)next+sizeof(void*); helper.insts_size = 0; // reset helper.instsize = (instsize_t*)instsize; *(dynablock_t**)actual_p = block; + helper.table64cap = helper.table64size; + customFree(helper.table64); + helper.table64 = (uint64_t*)helper.tablestart; // pass 3, emit (log emit native opcode) if(box64_dynarec_dump) { dynarec_log(LOG_NONE, "%s%04d|Emitting %zu bytes for %u x64 bytes", (box64_dynarec_dump>1)?"\e[01;36m":"", GetTID(), helper.native_size, helper.isize); @@ -550,43 +556,24 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) { helper.native_size = 0; helper.table64size = 0; // reset table64 (but not the cap) native_pass3(&helper, addr); - if((oldnativesize!=helper.native_size) || (oldtable64size<helper.table64size)) { - printf_log(LOG_NONE, "BOX64: Warning, size difference in block between pass2 (%zu) & pass3 (%zu)!\n", sz, helper.native_size+helper.table64size*8); - uint8_t *dump = (uint8_t*)helper.start; - printf_log(LOG_NONE, "Dump of %d x64 opcodes:\n", helper.size); - for(int i=0; i<helper.size; ++i) { - printf_log(LOG_NONE, "%p:", dump); - for(; dump<(uint8_t*)helper.insts[i+1].x64.addr; ++dump) - printf_log(LOG_NONE, " %02X", *dump); - printf_log(LOG_NONE, "\t%d -> %d\n", helper.insts[i].size2, helper.insts[i].size); - } - 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((void*)helper.tablestart, helper.table64, helper.table64size*8); - } // keep size of instructions for signal handling block->instsize = instsize; // ok, free the helper now customFree(helper.insts); helper.insts = NULL; - customFree(helper.table64); helper.table64 = NULL; helper.instsize = NULL; customFree(helper.predecessor); helper.predecessor = NULL; block->size = sz; block->isize = helper.size; - block->actual_block = actual_p; block->block = p; block->jmpnext = next+sizeof(void*); + block->always_test = helper.always_test; + block->dirty = block->always_test; *(dynablock_t**)next = block; *(void**)(next+3*sizeof(void*)) = native_next; CreateJmpNext(block->jmpnext, next+3*sizeof(void*)); - block->need_test = 0; //block->x64_addr = (void*)start; block->x64_size = end-start; // all done... @@ -599,10 +586,25 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) { CancelBlock64(0); return NULL; } + if((oldnativesize!=helper.native_size) || (oldtable64size<helper.table64size)) { + printf_log(LOG_NONE, "BOX64: Warning, size difference in block between pass2 (%zu) & pass3 (%zu)!\n", sz, helper.native_size+helper.table64size*8); + uint8_t *dump = (uint8_t*)helper.start; + printf_log(LOG_NONE, "Dump of %d x64 opcodes:\n", helper.size); + for(int i=0; i<helper.size; ++i) { + printf_log(LOG_NONE, "%p:", dump); + for(; dump<(uint8_t*)helper.insts[i+1].x64.addr; ++dump) + printf_log(LOG_NONE, " %02X", *dump); + printf_log(LOG_NONE, "\t%d -> %d\n", helper.insts[i].size2, helper.insts[i].size); + } + printf_log(LOG_NONE, "Table64 \t%d -> %d\n", oldtable64size*8, helper.table64size*8); + printf_log(LOG_NONE, " ------------\n"); + CancelBlock64(0); + return NULL; + } if(!isprotectedDB(addr, end-addr)) { - dynarec_log(LOG_DEBUG, "Warning, block unprotected while being processed %p:%ld, cancelling\n", block->x64_addr, block->x64_size); + dynarec_log(LOG_DEBUG, "Warning, block unprotected while being processed %p:%ld, marking as need_test\n", block->x64_addr, block->x64_size); AddHotPage(addr); - block->need_test = 1; + block->dirty = 1; //protectDB(addr, end-addr); } current_helper = NULL; diff --git a/src/dynarec/rv64/dynarec_rv64_pass2.h b/src/dynarec/rv64/dynarec_rv64_pass2.h index 176d512d..d71f9180 100644 --- a/src/dynarec/rv64/dynarec_rv64_pass2.h +++ b/src/dynarec/rv64/dynarec_rv64_pass2.h @@ -14,5 +14,5 @@ } #define INST_EPILOG dyn->insts[ninst].epilog = dyn->native_size; #define INST_NAME(name) -#define TABLE64(A, V) {Table64(dyn, (V)); EMIT(0); EMIT(0);} -#define FTABLE64(A, V) {mmx87_regs_t v = {.d = V}; Table64(dyn, v.q); EMIT(0); EMIT(0);} \ No newline at end of file +#define TABLE64(A, V) {Table64(dyn, (V), 2); EMIT(0); EMIT(0);} +#define FTABLE64(A, V) {mmx87_regs_t v = {.d = V}; Table64(dyn, v.q, 2); EMIT(0); EMIT(0);} \ No newline at end of file diff --git a/src/dynarec/rv64/dynarec_rv64_pass3.h b/src/dynarec/rv64/dynarec_rv64_pass3.h index 24ab0dfa..dafef0c5 100644 --- a/src/dynarec/rv64/dynarec_rv64_pass3.h +++ b/src/dynarec/rv64/dynarec_rv64_pass3.h @@ -19,5 +19,5 @@ #define INST_EPILOG #define INST_NAME(name) inst_name_pass3(dyn, ninst, name) -#define TABLE64(A, V) {int val64offset = Table64(dyn, (V)); MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); AUIPC(A, SPLIT20(val64offset)); LD(A, A, SPLIT12(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); AUIPC(x1, SPLIT20(val64offset)); FLD(A, x1, SPLIT12(val64offset));} +#define TABLE64(A, V) {int val64offset = Table64(dyn, (V), 3); MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); AUIPC(A, SPLIT20(val64offset)); LD(A, A, SPLIT12(val64offset));} +#define FTABLE64(A, V) {mmx87_regs_t v = {.d = V}; int val64offset = Table64(dyn, v.q, 3); MESSAGE(LOG_DUMP, " FTable64: %g\n", v.d); AUIPC(x1, SPLIT20(val64offset)); FLD(A, x1, SPLIT12(val64offset));} diff --git a/src/dynarec/rv64/dynarec_rv64_private.h b/src/dynarec/rv64/dynarec_rv64_private.h index 3d6205d9..01657427 100644 --- a/src/dynarec/rv64/dynarec_rv64_private.h +++ b/src/dynarec/rv64/dynarec_rv64_private.h @@ -96,6 +96,7 @@ typedef struct dynarec_rv64_s { int table64size;// size of table (will be appended at end of executable code) int table64cap; uintptr_t tablestart; + uintptr_t jmp_next; // address of the jump_next address flagcache_t f; extcache_t e; // cache for the 10..31 0..1 double reg from fpu, plus x87 stack delta uintptr_t* next; // variable array of "next" jump address @@ -111,6 +112,7 @@ typedef struct dynarec_rv64_s { uintptr_t forward_to; // address of the next jump to (to check if everything is ok) int32_t forward_size; // size at the forward point int forward_ninst; // ninst at the forward point + uint8_t always_test; } dynarec_rv64_t; // convert idx (0..24) to reg index (10..31 0..1) @@ -123,7 +125,7 @@ uintptr_t get_closest_next(dynarec_rv64_t *dyn, uintptr_t addr); int is_nops(dynarec_rv64_t *dyn, uintptr_t addr, int n); int is_instructions(dynarec_rv64_t *dyn, uintptr_t addr, int n); -int Table64(dynarec_rv64_t *dyn, uint64_t val); // add a value to etable64 (if needed) and gives back the imm19 to use in LDR_literal +int Table64(dynarec_rv64_t *dyn, uint64_t val, int pass); // add a value to etable64 (if needed) and gives back the imm19 to use in LDR_literal void CreateJmpNext(void* addr, void* next); |