void mips_dyncom_run(cpu_t *cpu) { mips_core_t *core = (mips_core_t*)cpu->cpu_data; addr_t phys_pc = core->pc; int rc = cpu_run(cpu); switch (rc) { case JIT_RETURN_NOERR: break; case JIT_RETURN_SINGLESTEP: case JIT_RETURN_FUNCNOTFOUND: cpu_tag(cpu, core->gpr[15]); cpu->dyncom_engine->cur_tagging_pos ++; cpu_translate(cpu, core->gpr[15]); /* * IF singlestep, we run it here, otherwise, break. */ if(cpu->dyncom_engine->flags_debug & CPU_DEBUG_SINGLESTEP) { rc = cpu_run(cpu); if(rc != JIT_RETURN_TRAP) break; } else break; case JIT_RETURN_TRAP: break; default: fprintf(stderr, "unknown return code:%d\n", rc); skyeye_exit(-1); } return; }
void arm_dyncom_run(cpu_t* cpu){ arm_core_t* core = (arm_core_t*)cpu->cpu_data; addr_t phys_pc = core->Reg[15]; #if 0 if(mmu_read_(core, core->pc, PPC_MMU_CODE, &phys_pc) != PPC_MMU_OK){ /* we donot allow mmu exception in tagging state */ fprintf(stderr, "In %s, can not translate the pc 0x%x\n", __FUNCTION__, core->pc); exit(-1); } #endif #if 0 cpu->dyncom_engine->code_start = phys_pc; cpu->dyncom_engine->code_end = get_end_of_page(phys_pc); cpu->dyncom_engine->code_entry = phys_pc; #endif int rc = cpu_run(cpu); switch (rc) { case JIT_RETURN_NOERR: /* JIT code wants us to end execution */ break; case JIT_RETURN_SINGLESTEP: case JIT_RETURN_FUNCNOTFOUND: cpu_tag(cpu, core->Reg[15]); cpu->dyncom_engine->functions = 0; cpu_translate(cpu); /* *If singlestep,we run it here,otherwise,break. */ if (cpu->dyncom_engine->flags_debug & CPU_DEBUG_SINGLESTEP){ rc = cpu_run(cpu); if(rc != JIT_RETURN_TRAP) break; } else break; case JIT_RETURN_TRAP: break; default: fprintf(stderr, "unknown return code: %d\n", rc); skyeye_exit(-1); }// switch (rc) return; }
int cpu_run(cpu_t *cpu, debug_function_t debug_function) { addr_t pc = 0, orig_pc = 0; uint32_t i; int ret; bool success; bool do_translate = true; /* try to find the entry in all functions */ while(true) { if (do_translate) { cpu_translate(cpu); pc = cpu->f.get_pc(cpu, cpu->rf.grf); } orig_pc = pc; success = false; for (i = 0; i < cpu->functions; i++) { fp_t FP = (fp_t)cpu->fp[i]; update_timing(cpu, TIMER_RUN, true); breakpoint(); ret = FP(cpu->RAM, cpu->rf.grf, cpu->rf.frf, debug_function); update_timing(cpu, TIMER_RUN, false); pc = cpu->f.get_pc(cpu, cpu->rf.grf); if (ret != JIT_RETURN_FUNCNOTFOUND) return ret; if (!is_inside_code_area(cpu, pc)) return ret; if (pc != orig_pc) { success = true; break; } } if (!success) { LOG("{%" PRIx64 "}", pc); cpu_tag(cpu, pc); do_translate = true; } } }
int main(int argc, char **argv) { char *executable; cpu_arch_t arch; cpu_t *cpu; uint8_t *RAM; FILE *f; int ramsize; int singlestep = SINGLESTEP_NONE; int log = 1; int print_ir = 0; /* parameter parsing */ if (argc < 2) { printf("Usage: %s [--print-ir] <binary>\n", argv[0]); return 0; } if (!strcmp(argv[1], "--print-ir")) { print_ir = 1; argv++; } executable = argv[1]; arch = CPU_ARCH_I386; ramsize = 1*1024*1024; RAM = (uint8_t*)malloc(ramsize); cpu = cpu_new(arch, 0, 0); cpu_set_flags_codegen(cpu, CPU_CODEGEN_OPTIMIZE); cpu_set_flags_debug(cpu, 0 | (print_ir? CPU_DEBUG_PRINT_IR : 0) | (print_ir? CPU_DEBUG_PRINT_IR_OPTIMIZED : 0) | (log? CPU_DEBUG_LOG :0) | (singlestep == SINGLESTEP_STEP? CPU_DEBUG_SINGLESTEP : 0) | (singlestep == SINGLESTEP_BB? CPU_DEBUG_SINGLESTEP_BB : 0) ); cpu_set_ram(cpu, RAM); /* load code */ if (!(f = fopen(executable, "rb"))) { printf("Could not open %s!\n", executable); return 2; } cpu->code_start = START; cpu->code_end = cpu->code_start + fread(&RAM[cpu->code_start], 1, ramsize-cpu->code_start, f); fclose(f); cpu->code_entry = cpu->code_start + ENTRY; cpu_tag(cpu, cpu->code_entry); cpu_translate(cpu); /* force translation now */ printf("\n*** Executing...\n"); printf("GUEST run..."); fflush(stdout); cpu_run(cpu, debug_function); printf("done!\n"); cpu_free(cpu); return 0; }
int main(int ac, char **av, char **ep) { int rc; cpu_t *cpu; xec_guest_info_t guest_info; xec_mem_if_t *mem_if; xec_monitor_t *monitor; xec_us_syscall_if_t *us_syscall; m88k_uintptr_t stack_top; nix_env_t *env; bool debugging = false; aspace_lock(); if (ac < 2) { fprintf(stderr, "usage: %s <executable> [args...]\n", *av); exit(EXIT_FAILURE); } /* Initialize xec, nix and loader. */ xec_init(); obsd41_init(); loader_init(); /* Create CPU */ cpu = cpu_new(CPU_ARCH_M88K, CPU_FLAG_ENDIAN_BIG, 0); if (cpu == NULL) { fprintf(stderr, "error: failed initializing M88K architecture.\n"); exit(EXIT_FAILURE); } /* Create XEC bridge mem-if */ mem_if = run88_new_mem_if(); /* Create the XEC US Syscall */ us_syscall = obsd41_us_syscall_create(mem_if); if (us_syscall == NULL) { fprintf(stderr, "error: failed creating xec userspace syscall.\n"); exit(EXIT_FAILURE); } /* Create NIX env */ env = nix_env_create(mem_if); if (env == NULL) { fprintf(stderr, "error: failed creating nix environment.\n"); exit(EXIT_FAILURE); } /* Load the executable */ rc = loader_load(mem_if, av[1]); if (rc != LOADER_SUCCESS) { fprintf(stderr, "error: cannot load executable '%s', error=%d.\n", av[1], rc); exit(EXIT_FAILURE); } /* Setup arguments */ g_uframe_log = xec_log_register("uframe"); #ifndef DEBUGGER xec_log_disable("nix"); xec_log_disable("openbsd41"); xec_log_disable("uframe"); xec_log_disable(NULL); #endif openbsd_m88k_setup_uframe(cpu, mem_if, ac - 1, av + 1, ep, &stack_top); /* Setup the CPU */ cpu_set_flags_codegen(cpu, CPU_CODEGEN_OPTIMIZE|CPU_CODEGEN_TAG_LIMIT); cpu_set_flags_debug(cpu, CPU_DEBUG_NONE); //cpu_set_flags_debug(cpu, CPU_DEBUG_SINGLESTEP_BB); cpu_set_flags_hint(cpu, CPU_HINT_TRAP_RETURNS_TWICE); cpu_set_ram(cpu, RAM); /* Create XEC bridge monitor */ guest_info.name = cpu->info.name; guest_info.endian = (cpu->info.common_flags & CPU_FLAG_ENDIAN_MASK) == CPU_FLAG_ENDIAN_BIG ? XEC_ENDIAN_BIG : XEC_ENDIAN_LITTLE; guest_info.byte_size = cpu->info.byte_size; guest_info.word_size = cpu->info.word_size; guest_info.page_size = cpu->info.default_page_size; monitor = xec_monitor_create(&guest_info, mem_if, cpu->rf.grf, NULL); if (monitor == NULL) { fprintf(stderr, "error: failed createc xec monitor.\n"); exit(EXIT_FAILURE); } /* Setup registers for execution */ PC = g_ahdr.entry; R[31] = stack_top; // Stack Pointer R[1] = -1; // Return Address cpu->code_start = g_ahdr.tstart; cpu->code_end = g_ahdr.tstart + g_ahdr.tsize; cpu->code_entry = g_ahdr.entry; cpu_tag(cpu, cpu->code_entry); dump_state(RAM, (m88k_grf_t*)cpu->rf.grf); #ifdef DEBUGGER debugging = true; #else fprintf(stderr, "Translating..."); fflush(stderr); cpu_translate(cpu); fprintf(stderr, "done.\n"); #endif aspace_unlock(); for (;;) { if (debugging) { rc = cpu_debugger(cpu, debug_function); if (rc < 0) { debugging = false; continue; } } else { rc = cpu_run(cpu, debug_function); } switch (rc) { case JIT_RETURN_NOERR: /* JIT code wants us to end execution */ break; case JIT_RETURN_FUNCNOTFOUND: #ifndef DEBUGGER fprintf(stderr, "%s: error: 0x%llX not found!\n", __func__, (unsigned long long)PC); fprintf(stderr, "Translating..."); fflush(stderr); cpu_tag(cpu, PC); cpu_flush(cpu); cpu_translate(cpu); fprintf(stderr, "done.\n"); #else dump_state(RAM, (m88k_grf_t*)cpu->rf.grf); if (PC == (uint32_t)(-1U)) goto exit_loop; // bad :( fprintf(stderr, "%s: warning: 0x%llX not found!\n", __func__, (unsigned long long)PC); fprintf(stderr, "PC: "); for (size_t i = 0; i < 16; i++) fprintf(stderr, "%02X ", RAM[PC+i]); fprintf(stderr, "\n"); exit(EXIT_FAILURE); #endif break; case JIT_RETURN_TRAP: // printf("TRAP %u / %u!\n", TRAPNO, R[13]); if (TRAPNO == 0x80 && R[13] == 1) // exit goto exit_loop; // printf("BEFORE:\n"); // dump_state(RAM, (m88k_grf_t*)cpu->rf.grf); xec_us_syscall_dispatch(us_syscall, monitor); // printf("AFTER:\n"); // dump_state(RAM, (m88k_grf_t*)cpu->rf.grf); break; case JIT_RETURN_SINGLESTEP: break; default: fprintf(stderr, "unknown return code: %d\n", rc); goto exit_loop; } if (cpu->flags_debug & (CPU_DEBUG_SINGLESTEP | CPU_DEBUG_SINGLESTEP_BB)) cpu_flush(cpu); } exit_loop: cpu_free(cpu); fprintf(stderr, ">> run88 success\n"); exit(EXIT_SUCCESS); }
/** * @brief search the function of current address in map.If find,run it.Other wise,return. * * @param cpu CPU core structure * @param debug_function debug function * * @return the return value of JIT Function */ int cpu_run(cpu_t *cpu) { addr_t pc = 0, orig_pc = 0; uint64_t icounter, orig_icounter; uint32_t i; int ret; bool success; bool do_translate = true; fp_t pfunc = NULL; /* try to find the entry in all functions */ while(true) { pc = cpu->f.get_pc(cpu, cpu->rf.grf); #ifdef HASH_FAST_MAP fast_map hash_map = cpu->dyncom_engine->fmap; pfunc = (fp_t)hash_map[pc & 0x1fffff]; if(pfunc) do_translate = false; else return JIT_RETURN_FUNCNOTFOUND; #else fast_map &func_addr = cpu->dyncom_engine->fmap; fast_map::const_iterator it = func_addr.find(pc); if (it != func_addr.end()) { pfunc = (fp_t)it->second; do_translate = false; } else{ LOG("jitfunction not found:key=0x%x\n", pc); return JIT_RETURN_FUNCNOTFOUND; } #endif //LOG("find jitfunction:key=0x%x\n", pc); //orig_pc = pc; //orig_icounter = REG(SR(ICOUNTER)); //success = false; UPDATE_TIMING(cpu, TIMER_RUN, true); //breakpoint(); #if PRINT_REG for (int i = 0; i < 16; i++) { LOG("%d:%x ", i, *(uint32_t*)((uint8_t*)cpu->rf.grf + 4*i)); } LOG("\n"); LOG("############### Begin to execute JIT\n"); #endif ret = pfunc(cpu->dyncom_engine->RAM, cpu->rf.grf, cpu->rf.srf, cpu->rf.frf, read_memory, write_memory); //*(uint32_t*)((uint8_t*)cpu->rf.grf + 8) = 0; //ret = FP(cpu->dyncom_engine->RAM, cpu->rf.grf, cpu->rf.frf, debug_function); #if PRINT_REG for (int i = 0; i < 16; i++) { LOG("%d:%x ", i, *(uint32_t*)((uint8_t*)cpu->rf.grf + 4*i)); } LOG("pc : %x\n ret : %x", cpu->f.get_pc(cpu, cpu->rf.grf), ret); LOG("\n"); #endif UPDATE_TIMING(cpu, TIMER_RUN, false); //pc = cpu->f.get_pc(cpu, cpu->rf.grf); //icounter = REG(SR(ICOUNTER)); //pc = 0x4d495354; //return ret; if (ret != JIT_RETURN_FUNCNOTFOUND) return ret; #if 0 if (!is_inside_code_area(cpu, pc)) return ret; #endif #if 0 /* simulator run new instructions ? */ if (icounter != orig_icounter) { success = true; //break; } //} if (!success) { LOG("{%llx}", pc); cpu_tag(cpu, pc); do_translate = true; } #endif } }
int main(int argc, char **argv) { char *s_arch; char *executable; cpu_arch_t arch; cpu_t *cpu; uint8_t *RAM; FILE *f; int ramsize; int r1, r2; uint64_t t1, t2, t3, t4; unsigned start_no = START_NO; int singlestep = SINGLESTEP_NONE; int log = 1; int print_ir = 1; /* parameter parsing */ if (argc < 3) { printf("Usage: %s executable [arch] [itercount] [entries]\n", argv[0]); return 0; } s_arch = argv[1]; executable = argv[2]; if (argc >= 4) start_no = atoi(argv[3]); if (!strcmp("mips", s_arch)) arch = CPU_ARCH_MIPS; else if (!strcmp("m88k", s_arch)) arch = CPU_ARCH_M88K; else if (!strcmp("arm", s_arch)) arch = CPU_ARCH_ARM; else if (!strcmp("fapra", s_arch)) arch = CPU_ARCH_FAPRA; else { printf("unknown architecture '%s'!\n", s_arch); return 0; } ramsize = 5*1024*1024; RAM = (uint8_t*)malloc(ramsize); cpu = cpu_new(arch, 0, 0); cpu_set_flags_codegen(cpu, CPU_CODEGEN_OPTIMIZE); cpu_set_flags_debug(cpu, 0 | (print_ir? CPU_DEBUG_PRINT_IR : 0) | (print_ir? CPU_DEBUG_PRINT_IR_OPTIMIZED : 0) | (log? CPU_DEBUG_LOG :0) | (singlestep == SINGLESTEP_STEP? CPU_DEBUG_SINGLESTEP : 0) | (singlestep == SINGLESTEP_BB? CPU_DEBUG_SINGLESTEP_BB : 0) ); cpu_set_ram(cpu, RAM); /* load code */ if (!(f = fopen(executable, "rb"))) { printf("Could not open %s!\n", executable); return 2; } cpu->code_start = START; cpu->code_end = cpu->code_start + fread(&RAM[cpu->code_start], 1, ramsize-cpu->code_start, f); fclose(f); cpu->code_entry = cpu->code_start + ENTRY; cpu_tag(cpu, cpu->code_entry); cpu_translate(cpu); /* force translation now */ printf("\n*** Executing...\n"); printf("number of iterations: %u\n", start_no); uint32_t *reg_pc, *reg_lr, *reg_param, *reg_result; switch (arch) { case CPU_ARCH_M88K: reg_pc = &((m88k_grf_t*)cpu->rf.grf)->sxip; reg_lr = &((m88k_grf_t*)cpu->rf.grf)->r[1]; reg_param = &((m88k_grf_t*)cpu->rf.grf)->r[2]; reg_result = &((m88k_grf_t*)cpu->rf.grf)->r[2]; break; case CPU_ARCH_MIPS: reg_pc = &((reg_mips32_t*)cpu->rf.grf)->pc; reg_lr = &((reg_mips32_t*)cpu->rf.grf)->r[31]; reg_param = &((reg_mips32_t*)cpu->rf.grf)->r[4]; reg_result = &((reg_mips32_t*)cpu->rf.grf)->r[4]; break; case CPU_ARCH_ARM: reg_pc = &((reg_arm_t*)cpu->rf.grf)->pc; reg_lr = &((reg_arm_t*)cpu->rf.grf)->r[14]; reg_param = &((reg_arm_t*)cpu->rf.grf)->r[0]; reg_result = &((reg_arm_t*)cpu->rf.grf)->r[0]; break; case CPU_ARCH_FAPRA: reg_pc = &((reg_fapra32_t*)cpu->rf.grf)->pc; reg_lr = &((reg_fapra32_t*)cpu->rf.grf)->r[0]; reg_param = &((reg_fapra32_t*)cpu->rf.grf)->r[3]; reg_result = &((reg_fapra32_t*)cpu->rf.grf)->r[3]; break; default: fprintf(stderr, "architecture %u not handled.\n", arch); exit(EXIT_FAILURE); } *reg_pc = cpu->code_entry; *reg_lr = RET_MAGIC; *reg_param = start_no; printf("GUEST run..."); fflush(stdout); t1 = abs_time(); cpu_run(cpu, debug_function); t2 = abs_time(); r1 = *reg_result; printf("done!\n"); printf("HOST run..."); fflush(stdout); t3 = abs_time(); r2 = fib(start_no); t4 = abs_time(); printf("done!\n"); cpu_free(cpu); printf("Time GUEST: %lld\n", t2-t1); printf("Time HOST: %lld\n", t4-t3); printf("Result HOST: %d\n", r2); printf("Result GUEST: %d\n", r1); printf("GUEST required \033[1m%.2f%%\033[22m of HOST time.\n", (float)(t2-t1)/(float)(t4-t3)*100); if (r1 == r2) printf("\033[1mSUCCESS!\033[22m\n\n"); else printf("\033[1mFAILED!\033[22m\n\n"); return 0; }