/** * @brief Create llvm JIT Function and translate instructions to fill the JIT Function. * Optimize the llvm IR and save the function and its entry address to map. * * @param cpu CPU core structure */ static void cpu_translate_function(cpu_t *cpu) { BasicBlock *bb_ret, *bb_trap, *label_entry, *bb_start; addr_t start_addr = cpu->f.get_pc(cpu, cpu->rf.grf); /* create function and fill it with std basic blocks */ cpu->dyncom_engine->cur_func = cpu_create_function(cpu, "jitmain", &bb_ret, &bb_trap, &label_entry); /* TRANSLATE! */ UPDATE_TIMING(cpu, TIMER_FE, true); if (cpu->dyncom_engine->flags_debug & CPU_DEBUG_SINGLESTEP) { bb_start = cpu_translate_singlestep(cpu, bb_ret, bb_trap); } else if (cpu->dyncom_engine->flags_debug & CPU_DEBUG_SINGLESTEP_BB) { bb_start = cpu_translate_singlestep_bb(cpu, bb_ret, bb_trap); } else { bb_start = cpu_translate_all(cpu, bb_ret, bb_trap); } UPDATE_TIMING(cpu, TIMER_FE, false); /* finish entry basicblock */ BranchInst::Create(bb_start, label_entry); /* make sure everything is OK */ verifyFunction(*cpu->dyncom_engine->cur_func, AbortProcessAction); if (cpu->dyncom_engine->flags_debug & CPU_DEBUG_PRINT_IR) cpu->dyncom_engine->mod->dump(); if (cpu->dyncom_engine->flags_codegen & CPU_CODEGEN_OPTIMIZE) { UPDATE_TIMING(cpu, TIMER_OPT, true); LOG("*** Optimizing..."); optimize(cpu); LOG("done.\n"); UPDATE_TIMING(cpu, TIMER_OPT, false); if (cpu->dyncom_engine->flags_debug & CPU_DEBUG_PRINT_IR_OPTIMIZED) cpu->dyncom_engine->mod->dump(); } LOG("*** Translating..."); UPDATE_TIMING(cpu, TIMER_BE, true); cpu->dyncom_engine->fp[cpu->dyncom_engine->functions] = cpu->dyncom_engine->exec_engine->getPointerToFunction(cpu->dyncom_engine->cur_func); //cpu->dyncom_engine->fmap[start_addr] = cpu->dyncom_engine->fp[cpu->dyncom_engine->functions]; save_addr_in_func(cpu, cpu->dyncom_engine->fp[cpu->dyncom_engine->functions]); LOG("Generate native code for %x\n", start_addr); UPDATE_TIMING(cpu, TIMER_BE, false); LOG("done.\n"); cpu->dyncom_engine->functions++;/* Bug."functions" member could not be reset. */ }
static void cpu_translate_function(cpu_t *cpu) { BasicBlock *bb_ret, *bb_trap, *label_entry, *bb_start; /* create function and fill it with std basic blocks */ cpu->cur_func = cpu_create_function(cpu, "jitmain", &bb_ret, &bb_trap, &label_entry); cpu->func[cpu->functions] = cpu->cur_func; /* TRANSLATE! */ update_timing(cpu, TIMER_FE, true); if (cpu->flags_debug & CPU_DEBUG_SINGLESTEP) { bb_start = cpu_translate_singlestep(cpu, bb_ret, bb_trap); } else if (cpu->flags_debug & CPU_DEBUG_SINGLESTEP_BB) { bb_start = cpu_translate_singlestep_bb(cpu, bb_ret, bb_trap); } else { bb_start = cpu_translate_all(cpu, bb_ret, bb_trap); } update_timing(cpu, TIMER_FE, false); /* finish entry basicblock */ BranchInst::Create(bb_start, label_entry); /* make sure everything is OK */ verifyFunction(*cpu->cur_func, PrintMessageAction); if (cpu->flags_debug & CPU_DEBUG_PRINT_IR) cpu->mod->dump(); if (cpu->flags_codegen & CPU_CODEGEN_OPTIMIZE) { LOG("*** Optimizing..."); optimize(cpu); LOG("done.\n"); if (cpu->flags_debug & CPU_DEBUG_PRINT_IR_OPTIMIZED) cpu->mod->dump(); } LOG("*** Translating..."); update_timing(cpu, TIMER_BE, true); cpu->fp[cpu->functions] = cpu->exec_engine->getPointerToFunction(cpu->cur_func); update_timing(cpu, TIMER_BE, false); LOG("done.\n"); cpu->functions++; }