⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppc32_jit.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 3 页
字号:
                                                ppc32_jit_tcb_t *block){   struct ppc32_insn_tag *tag;   ppc_insn_t code;   code = insn_fetch(block);   tag = insn_tag_find(code);   assert(tag);   tag->emit(cpu,block,code);   return tag;}/* Add end of JIT block */static void ppc32_jit_tcb_add_end(ppc32_jit_tcb_t *b){   ppc32_set_ia(&b->jit_ptr,b->start_ia+(b->ppc_trans_pos<<2));   ppc32_jit_tcb_push_epilog(&b->jit_ptr);}/* Record a patch to apply in a compiled block */int ppc32_jit_tcb_record_patch(ppc32_jit_tcb_t *block,jit_op_t *iop,                               u_char *jit_ptr,m_uint32_t vaddr){   struct ppc32_jit_patch_table *ipt = block->patch_table;   struct ppc32_insn_patch *patch;   /* pc must be 32-bit aligned */   if (vaddr & 0x03) {      fprintf(stderr,              "Block 0x%8.8x: trying to record an invalid IA (0x%8.8x)\n",              block->start_ia,vaddr);      return(-1);   }   if (!ipt || (ipt->cur_patch >= PPC32_INSN_PATCH_TABLE_SIZE))   {      /* full table or no table, create a new one */      ipt = malloc(sizeof(*ipt));      if (!ipt) {         fprintf(stderr,"Block 0x%8.8x: unable to create patch table.\n",                 block->start_ia);         return(-1);      }      memset(ipt,0,sizeof(*ipt));      ipt->next = block->patch_table;      block->patch_table = ipt;   }#if DEBUG_BLOCK_PATCH   printf("Block 0x%8.8x: recording patch [JIT:%p->ppc:0x%8.8x], "          "MTP=%d\n",block->start_ia,jit_ptr,vaddr,block->ppc_trans_pos);#endif   patch = &ipt->patches[ipt->cur_patch];   patch->jit_insn = jit_ptr;   patch->ppc_ia = vaddr;   ipt->cur_patch++;    patch->next = iop->arg_ptr;   iop->arg_ptr = patch;   return(0);}/* Apply patches for a JIT instruction block */static int ppc32_jit_tcb_apply_patches(cpu_ppc_t *cpu,                                       ppc32_jit_tcb_t *block,                                       jit_op_t *iop){   struct ppc32_insn_patch *patch;   u_char *jit_ptr,*jit_dst;   u_int pos;   for(patch=iop->arg_ptr;patch;patch=patch->next) {      jit_ptr = (patch->jit_insn - iop->ob_data) + iop->ob_final;      pos = (patch->ppc_ia & PPC32_MIN_PAGE_IMASK) >> 2;      jit_dst = block->jit_insn_ptr[pos];      if (jit_dst) {#if DEBUG_BLOCK_PATCH                printf("Block 0x%8.8x: applying patch "                "[JIT:%p->ppc:0x%8.8x=JIT:%p, ]\n",                block->start_ia,patch->jit_insn,patch->ppc_ia,jit_dst);#endif         ppc32_jit_tcb_set_patch(jit_ptr,jit_dst);      } else {         printf("Block 0x%8.8x: null dst for patch!\n",block->start_ia);      }   }      return(0);}/* Free the patch table */static void ppc32_jit_tcb_free_patches(ppc32_jit_tcb_t *block){   struct ppc32_jit_patch_table *p,*next;   for(p=block->patch_table;p;p=next) {      next = p->next;      free(p);   }   block->patch_table = NULL;}/* Adjust the JIT buffer if its size is not sufficient */static int ppc32_jit_tcb_adjust_buffer(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block){   insn_exec_page_t *new_buffer;   if ((block->jit_ptr - block->jit_buffer->ptr) <= (PPC_JIT_BUFSIZE - 512))      return(0);#if DEBUG_BLOCK_CHUNK     printf("Block 0x%8.8x: adjusting JIT buffer...\n",block->start_ia);#endif   if (block->jit_chunk_pos >= PPC_JIT_MAX_CHUNKS) {      fprintf(stderr,"Block 0x%8.8x: too many JIT chunks.\n",block->start_ia);      return(-1);   }   if (!(new_buffer = exec_page_alloc(cpu)))      return(-1);   /* record the new exec page */   block->jit_chunks[block->jit_chunk_pos++] = block->jit_buffer;   block->jit_buffer = new_buffer;   /* jump to the new exec page (link) */   ppc32_jit_tcb_set_jump(block->jit_ptr,new_buffer->ptr);   block->jit_ptr = new_buffer->ptr;   return(0);}/* Allocate an instruction block */static inline ppc32_jit_tcb_t *ppc32_jit_tcb_alloc(cpu_ppc_t *cpu){   ppc32_jit_tcb_t *p;   if (cpu->tcb_free_list) {      p = cpu->tcb_free_list;      cpu->tcb_free_list = p->next;   } else {      if (!(p = malloc(sizeof(*p))))         return NULL;   }   memset(p,0,sizeof(*p));   return p;}/* Free the code chunks */static void ppc32_jit_tcb_free_code_chunks(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block){   int i;   /* Free code pages */   for(i=0;i<PPC_JIT_MAX_CHUNKS;i++) {      exec_page_free(cpu,block->jit_chunks[i]);      block->jit_chunks[i] = NULL;   }   /* Free the current JIT buffer */   exec_page_free(cpu,block->jit_buffer);   block->jit_buffer = NULL;}/* Free an instruction block */void ppc32_jit_tcb_free(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block,                        int list_removal){   if (block) {      if (list_removal) {         /* Remove the block from the linked list */         if (block->next)            block->next->prev = block->prev;         else            cpu->tcb_last = block->prev;         if (block->prev)            block->prev->next = block->next;         else            cpu->tcb_list = block->next;         /* Remove the block from the physical mapping hash table */         if (block->phys_pprev) {            if (block->phys_next)               block->phys_next->phys_pprev = block->phys_pprev;                        *(block->phys_pprev) = block->phys_next;                        block->phys_pprev = NULL;            block->phys_next = NULL;         }      }      /* Free the patch tables */      ppc32_jit_tcb_free_patches(block);      /* Free code pages */      ppc32_jit_tcb_free_code_chunks(cpu,block);      /* Free the PowerPC-to-native code mapping */      free(block->jit_insn_ptr);            block->next = cpu->tcb_free_list;      cpu->tcb_free_list = block;   }}/* Create an instruction block */static ppc32_jit_tcb_t *ppc32_jit_tcb_create(cpu_ppc_t *cpu,m_uint32_t vaddr){   ppc32_jit_tcb_t *block = NULL;   m_uint32_t phys_page;   if (unlikely(cpu->translate(cpu,cpu->ia,PPC32_MTS_ICACHE,&phys_page)))      return NULL;   if (!(block = ppc32_jit_tcb_alloc(cpu)))      goto err_block_alloc;   block->start_ia = vaddr;   block->phys_page = phys_page;   block->phys_hash = ppc32_jit_get_phys_hash(phys_page);      /* Allocate the first JIT buffer */   if (!(block->jit_buffer = exec_page_alloc(cpu)))      goto err_jit_alloc;   block->jit_ptr = block->jit_buffer->ptr;   block->ppc_code = cpu->mem_op_lookup(cpu,block->start_ia,PPC32_MTS_ICACHE);   if (!block->ppc_code) {      fprintf(stderr,"%% No memory map for code execution at 0x%8.8x\n",              block->start_ia);      goto err_lookup;   }#if DEBUG_BLOCK_TIMESTAMP   block->tm_first_use = block->tm_last_use = jit_jiffies;#endif   return block; err_lookup: err_jit_alloc:   ppc32_jit_tcb_free(cpu,block,FALSE); err_block_alloc:   fprintf(stderr,"%% Unable to create instruction block for vaddr=0x%8.8x\n",            vaddr);   return NULL;}/* ======================================================================== *//* Dump a JIT opcode */static void ppc32_op_dump_opcode(jit_op_t *op){   switch(op->opcode) {      case JIT_OP_BRANCH_TARGET:         printf("branch_target");         break;      case JIT_OP_BRANCH_JUMP:         printf("branch_jump");         break;      case JIT_OP_EOB:         printf("eob");         break;      case JIT_OP_LOAD_GPR:         printf("load_gpr(%d,$%d,r:%d)",                op->param[0],op->param[1],op->param[2]);         break;      case JIT_OP_STORE_GPR:         printf("store_gpr(%d,$%d,r:%d)",                op->param[0],op->param[1],op->param[2]);         break;      case JIT_OP_ALTER_HOST_REG:         printf("alter_host_reg(%d)",op->param[0]);         break;      case JIT_OP_UPDATE_FLAGS:         printf("update_flags(%d,%s)",                op->param[0],(op->param[1] ? "signed" : "unsigned"));         break;      case JIT_OP_REQUIRE_FLAGS:         printf("require_flags(%d)",op->param[0]);         break;      case JIT_OP_TRASH_FLAGS:         printf("trash_flags(%d)",op->param[0]);         break;      case JIT_OP_INSN_OUTPUT:         printf("insn_out(\"%s\")",op->insn_name);         break;      case JIT_OP_SET_HOST_REG_IMM32:         printf("set_host_reg_imm32(%d,0x%8.8x)",op->param[0],op->param[1]);         break;      default:         printf("op(%u)",op->opcode);   }}/* Dump JIT operations (debugging) */static void ppc32_op_dump(cpu_gen_t *cpu,ppc32_jit_tcb_t *b){   m_uint32_t ia = b->start_ia;   jit_op_t *op;   int i;   printf("PPC32-JIT: dump of page 0x%8.8x\n",ia);   for(i=0;i<PPC32_INSN_PER_PAGE;i++,ia+=sizeof(ppc_insn_t)) {      printf("  0x%8.8x: ", ia);      for(op=cpu->jit_op_array[i];op;op=op->next) {         ppc32_op_dump_opcode(op);         printf(" ");      }      printf("\n");   }   printf("\n");}/* PPC register mapping */typedef struct {   int host_reg;   jit_op_t *last_store;   m_uint32_t last_store_ia;}ppc_reg_map_t;/* Clear register mapping (with PPC register) */static void ppc32_clear_ppc_reg_map(ppc_reg_map_t *ppc_map,int *host_map,                                    int reg){   int i,hreg;   if (reg == JIT_OP_ALL_REGS) {      for(i=0;i<PPC32_GPR_NR;i++) {         ppc_map[i].host_reg = JIT_OP_INV_REG;         ppc_map[i].last_store = NULL;      }      for(i=0;i<JIT_HOST_NREG;i++)         host_map[i] = JIT_OP_INV_REG;   } else {      hreg = ppc_map[reg].host_reg;      if (hreg != JIT_OP_INV_REG)         host_map[hreg] = JIT_OP_INV_REG;            ppc_map[reg].host_reg = JIT_OP_INV_REG;      ppc_map[reg].last_store = NULL;   }}/* Clear register mapping (with host register) */static void ppc32_clear_host_reg_map(ppc_reg_map_t *ppc_map,int *host_map,                                     int reg){   int ppc_reg;   if (host_map[reg] != JIT_OP_INV_REG) {      ppc_reg = host_map[reg];      ppc_map[ppc_reg].host_reg = JIT_OP_INV_REG;      ppc_map[ppc_reg].last_store = NULL;      host_map[reg] = JIT_OP_INV_REG;   }}/* Dump register mapping */static void ppc32_dump_reg_map(ppc_reg_map_t *map_array,int *host_map){   int i;   printf("PPC32-JIT: current register mapping:\n");   for(i=0;i<PPC32_GPR_NR;i++)      printf("  ppc reg %2.2d: %d\n",i,map_array[i].host_reg);   printf("\n");   for(i=0;i<JIT_HOST_NREG;i++)      printf("  hreg %d: %d\n",i,host_map[i]);   printf("\n");}/* Check register mapping consistency */static int ppc32_check_reg_map(ppc_reg_map_t *map_array,int *host_map){   ppc_reg_map_t *map;   int i;   for(i=0;i<PPC32_GPR_NR;i++) {      map = &map_array[i];      if ((map->host_reg != JIT_OP_INV_REG) && (host_map[map->host_reg] != i))          goto error;   }   for(i=0;i<JIT_HOST_NREG;i++) {      if ((host_map[i] != JIT_OP_INV_REG) &&           (map_array[host_map[i]].host_reg != i))         goto error;   }   return(0); error:   printf("PPC32_JIT: inconsistency in register mapping.\n");   ppc32_dump_reg_map(map_array,host_map);   exit(1);}/* Optimize JIT operations */static void ppc32_op_optimize(cpu_gen_t *cpu,ppc32_jit_tcb_t *b){   ppc_reg_map_t ppc_map[PPC32_GPR_NR],*map;   int reg,host_map[JIT_HOST_NREG];   jit_op_t *op,*opx,*last_cr_update[8];   m_uint32_t cur_ia;   int i,j;   ppc32_clear_ppc_reg_map(ppc_map,host_map,JIT_OP_ALL_REGS);   for(i=0;i<8;i++)      last_cr_update[i] = NULL;   for(i=0;i<PPC32_INSN_PER_PAGE;i++) {      for(op=cpu->jit_op_array[i];op;op=op->next)       {         //ppc32_check_reg_map(ppc_map,host_map);         cur_ia = b->start_ia + (i << 2);         switch(op->opcode) {            /* Clear mapping if end of block or branch target */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -