#include #include #include #include #include #include #include "os.h" #include "debug.h" #include "box64context.h" #include "custommem.h" #include "box64cpu.h" #include "emu/x64emu_private.h" #include "x64emu.h" #include "box64stack.h" #include "callback.h" #include "emu/x64run_private.h" #include "x64trace.h" #include "dynablock.h" #include "../dynablock_private.h" #include "dynarec_native.h" #include "../dynarec_arch.h" void updateflags_pass0(dynarec_arm_t* dyn, uint64_t jmp_df[]); void updateflags_pass1(dynarec_arm_t* dyn, uint64_t jmp_df[]); void updateflags_pass2(dynarec_arm_t* dyn, uint64_t jmp_df[]); void updateflags_pass3(dynarec_arm_t* dyn, uint64_t jmp_df[]); static dynablock_t* updaflags_arm64 = NULL; static uint8_t dummy_code[] = {0x90, 0xc3}; // some dummy code so update_flags dynablock point to something void* create_updateflags() { if(updaflags_arm64) return updaflags_arm64->block; uint64_t jmp_df[d_unknown+1] = {0}; dynarec_arm_t helper = {0}; instruction_arm64_t insts[1] = {0}; helper.insts = insts; helper.need_dump = BOX64ENV(dynarec_dump); helper.cap = 1; helper.f.dfnone = 1; helper.f.pending = SF_NODF; helper.insts[0].x64.gen_flags = X_ALL; // pass 0 updateflags_pass0(&helper, jmp_df); // check if all flags are handled int ok = 1; for(int i=d_none; ix64_addr = &dummy_code; block->isize = 0; block->actual_block = actual_p; helper.relocs = relocs; block->relocs = relocs; block->table64size = helper.table64size; helper.native_start = (uintptr_t)p; helper.tablestart = (uintptr_t)tablestart; helper.jmp_next = (uintptr_t)next+sizeof(void*); helper.instsize = (instsize_t*)instsize; *(dynablock_t**)actual_p = block; helper.table64cap = helper.table64size; helper.table64 = (uint64_t*)helper.tablestart; helper.callrets = (callret_t*)callrets; block->table64 = helper.table64; helper.callret_size = 0; // pass 3, emit (log emit native opcode) if(helper.need_dump) { dynarec_log(LOG_NONE, "%s%04d|Emitting %zu bytes for UpdateFlags", (helper.need_dump>1)?"\e[01;36m":"", GetTID(), helper.native_size); PrintFunctionAddr(helper.start, " => "); dynarec_log_prefix(0, LOG_NONE, "%s\n", (helper.need_dump>1)?"\e[m":""); } helper.native_size = 0; updateflags_pass3(&helper, jmp_df); helper.jmp_sz = helper.jmp_cap = 0; helper.jmps = NULL; // keep size of instructions for signal handling block->instsize = instsize; helper.table64 = NULL; helper.instsize = NULL; helper.predecessor = NULL; block->size = sz; block->isize = helper.size; block->block = p; block->jmpnext = next+sizeof(void*); block->always_test = helper.always_test; block->dirty = block->always_test; block->is32bits = 0; block->relocsize = helper.reloc_size*sizeof(uint32_t); block->arch = NULL; block->arch_size = 0; block->callret_size = helper.callret_size; block->callrets = helper.callrets; block->native_size = native_size; *(dynablock_t**)next = block; *(void**)(next+3*sizeof(void*)) = NULL; CreateJmpNext(block->jmpnext, next+3*sizeof(void*)); ClearCache(block->jmpnext, 4*sizeof(void*)); block->x64_size = 0; // all done... ClearCache(actual_p+sizeof(void*), native_size); // need to clear the cache before execution... updaflags_arm64 = block; return block->block; }