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

📄 ppc32_x86_trans.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 5 页
字号:
   /* EDX = $rb + $ra */   if (update || (ra != 0))       ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,X86_EDX,ra);   if (update)      x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EDX,4);   /* ECX = target register */   x86_mov_reg_imm(iop->ob_ptr,X86_ECX,target);      /* EAX = CPU instance pointer */   x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);   /* Call memory function */   x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);   x86_call_membase(iop->ob_ptr,X86_EDI,MEMOP_OFFSET(op));   x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);      if (update)      ppc32_store_gpr(&iop->ob_ptr,ra,X86_ESI);}typedef void (*memop_fast_access)(jit_op_t *iop,int target);/* Fast LBZ */static void ppc32_memop_fast_lbz(jit_op_t *iop,int target){   x86_clear_reg(iop->ob_ptr,X86_ECX);   x86_mov_reg_memindex(iop->ob_ptr,X86_ECX,X86_EAX,0,X86_EBX,0,1);   ppc32_store_gpr(&iop->ob_ptr,target,X86_ECX);}/* Fast STB */static void ppc32_memop_fast_stb(jit_op_t *iop,int target){   ppc32_load_gpr(&iop->ob_ptr,X86_EDX,target);   x86_mov_memindex_reg(iop->ob_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,1);}/* Fast LWZ */static void ppc32_memop_fast_lwz(jit_op_t *iop,int target){   x86_mov_reg_memindex(iop->ob_ptr,X86_EAX,X86_EAX,0,X86_EBX,0,4);   x86_bswap(iop->ob_ptr,X86_EAX);   ppc32_store_gpr(&iop->ob_ptr,target,X86_EAX);}/* Fast STW */static void ppc32_memop_fast_stw(jit_op_t *iop,int target){   ppc32_load_gpr(&iop->ob_ptr,X86_EDX,target);   x86_bswap(iop->ob_ptr,X86_EDX);   x86_mov_memindex_reg(iop->ob_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,4);}/* Fast memory operation */static void ppc32_emit_memop_fast(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,                                  int write_op,int opcode,                                  int base,int offset,int target,                                  memop_fast_access op_handler){   m_uint32_t val = sign_extend(offset,16);   u_char *test1,*test2,*p_exit,*p_fast_exit;   jit_op_t *iop;   /*     * Since an exception can be triggered, clear JIT state. This allows    * to use branch target tag (we can directly branch on this instruction).    */   ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET);   ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);   iop = ppc32_op_emit_insn_output(cpu,5,"memop_fast");   test2 = NULL;   if (val != 0) {      /* EBX = sign-extended offset */      ppc32_load_imm(&iop->ob_ptr,X86_EBX,val);      /* EBX = GPR[base] + sign-extended offset */      if (base != 0)         ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,X86_EBX,base);   } else {      if (base != 0)         ppc32_load_gpr(&iop->ob_ptr,X86_EBX,base);      else         ppc32_load_imm(&iop->ob_ptr,X86_EBX,0);   }#if 0   /* ======= zzz ======= */   {      u_char *testZ;      x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EBX,4);      x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_MASK);      x86_alu_reg_membase(iop->ob_ptr,X86_CMP,X86_ESI,X86_EDI,                          OFFSET(cpu_ppc_t,vtlb[base].vaddr));      testZ = iop->ob_ptr;      x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);      x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_EBX,PPC32_MIN_PAGE_IMASK);      x86_mov_reg_membase(iop->ob_ptr,X86_EAX,                          X86_EDI,OFFSET(cpu_ppc_t,vtlb[base].haddr),4);      /* Memory access */      op_handler(iop,target);      p_fast_exit = iop->ob_ptr;      x86_jump8(iop->ob_ptr,0);      x86_patch(testZ,iop->ob_ptr);   }#endif   /* EAX = mts32_entry index */   x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EBX,4);   x86_shift_reg_imm(iop->ob_ptr,X86_SHR,X86_EAX,MTS32_HASH_SHIFT);   x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_EAX,MTS32_HASH_MASK);   /* EDX = mts32_entry */   x86_mov_reg_membase(iop->ob_ptr,X86_EDX,                       X86_EDI,OFFSET(cpu_ppc_t,mts_cache[PPC32_MTS_DCACHE]),                       4);   x86_shift_reg_imm(iop->ob_ptr,X86_SHL,X86_EAX,4);   x86_alu_reg_reg(iop->ob_ptr,X86_ADD,X86_EDX,X86_EAX);   /* Compare virtual page address (ESI = vpage) */   x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EBX,4);   x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_MASK);   x86_alu_reg_membase(iop->ob_ptr,X86_CMP,X86_ESI,X86_EDX,                       OFFSET(mts32_entry_t,gvpa));   test1 = iop->ob_ptr;   x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);   /* Test if we are writing to a COW page */   if (write_op) {      x86_test_membase_imm(iop->ob_ptr,X86_EDX,OFFSET(mts32_entry_t,flags),                           MTS_FLAG_COW|MTS_FLAG_EXEC);      test2 = iop->ob_ptr;      x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);   }   /* EBX = offset in page, EAX = Host Page Address */   x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_EBX,PPC32_MIN_PAGE_IMASK);   x86_mov_reg_membase(iop->ob_ptr,X86_EAX,                       X86_EDX,OFFSET(mts32_entry_t,hpa),4);#if 0   /* zzz */   {      x86_mov_membase_reg(iop->ob_ptr,                          X86_EDI,OFFSET(cpu_ppc_t,vtlb[base].vaddr),                          X86_ESI,4);      x86_mov_membase_reg(iop->ob_ptr,                          X86_EDI,OFFSET(cpu_ppc_t,vtlb[base].haddr),                          X86_EAX,4);   }#endif   /* Memory access */   op_handler(iop,target);    p_exit = iop->ob_ptr;   x86_jump8(iop->ob_ptr,0);   /* === Slow lookup === */   x86_patch(test1,iop->ob_ptr);   if (test2)      x86_patch(test2,iop->ob_ptr);   /* Update IA (EBX = vaddr) */   ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));   /* EDX = virtual address */   x86_mov_reg_reg(iop->ob_ptr,X86_EDX,X86_EBX,4);   /* ECX = target register */   x86_mov_reg_imm(iop->ob_ptr,X86_ECX,target);   /* EAX = CPU instance pointer */   x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);   /* Call memory function */   x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);   x86_call_membase(iop->ob_ptr,X86_EDI,MEMOP_OFFSET(opcode));   x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);      x86_patch(p_exit,iop->ob_ptr);   /* zzz */#if 0   x86_patch(p_fast_exit,iop->ob_ptr);#endif}/* Emit unhandled instruction code */static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,                              ppc_insn_t opcode){   u_char *test1;   jit_op_t *iop;   iop = ppc32_op_emit_insn_output(cpu,3,"unknown");   /* Update IA */   ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));   /* Fallback to non-JIT mode */   x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);   x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);   x86_mov_reg_imm(iop->ob_ptr,X86_EDX,opcode);   ppc32_emit_basic_c_call(&iop->ob_ptr,ppc32_exec_single_insn_ext);   x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);      x86_test_reg_reg(iop->ob_ptr,X86_EAX,X86_EAX);   test1 = iop->ob_ptr;   x86_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);   ppc32_jit_tcb_push_epilog(&iop->ob_ptr);   x86_patch(test1,iop->ob_ptr);   /* Signal this as an EOB to reset JIT state */   ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);   return(0);}/* Virtual Breakpoint */void ppc32_emit_breakpoint(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b){   jit_op_t *iop;   iop = ppc32_op_emit_insn_output(cpu,2,"breakpoint");   x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);   x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);   ppc32_emit_c_call(b,iop,ppc32_run_breakpoint);   x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);   /* Signal this as an EOB to to reset JIT state */   ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);}/* Dump regs */static void ppc32_emit_dump_regs(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b){      jit_op_t *iop;      iop = ppc32_op_emit_insn_output(cpu,2,"dump_regs");   x86_mov_reg_membase(iop->ob_ptr,X86_EAX,X86_EDI,OFFSET(cpu_ppc_t,gen),4);      x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST-4);   x86_push_reg(iop->ob_ptr,X86_EAX);   ppc32_emit_c_call(b,iop,ppc32_dump_regs);   x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);   /* Signal this as an EOB to to reset JIT state */   ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);}/* Increment the number of executed instructions (performance debugging) */void ppc32_inc_perf_counter(cpu_ppc_t *cpu){    jit_op_t *iop;      iop = ppc32_op_emit_insn_output(cpu,1,"perf_cnt");   x86_inc_membase(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,perf_counter));}/* ======================================================================== *//* BLR - Branch to Link Register */DECLARE_INSN(BLR){   jit_op_t *iop;   int hreg;   ppc32_jit_start_hreg_seq(cpu,"blr");   hreg = ppc32_jit_alloc_hreg(cpu,-1);   ppc32_op_emit_alter_host_reg(cpu,hreg);   iop = ppc32_op_emit_insn_output(cpu,2,"blr");   x86_mov_reg_membase(iop->ob_ptr,hreg,X86_EDI,OFFSET(cpu_ppc_t,lr),4);   x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),hreg,4);   /* set the return address */   if (insn & 1)      ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));   ppc32_jit_tcb_push_epilog(&iop->ob_ptr);   ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);   ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));   ppc32_jit_close_hreg_seq(cpu);   return(0);}/* BCTR - Branch to Count Register */DECLARE_INSN(BCTR){   jit_op_t *iop;   int hreg;   ppc32_jit_start_hreg_seq(cpu,"bctr");   hreg = ppc32_jit_alloc_hreg(cpu,-1);   ppc32_op_emit_alter_host_reg(cpu,hreg);   iop = ppc32_op_emit_insn_output(cpu,2,"bctr");   x86_mov_reg_membase(iop->ob_ptr,hreg,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);   x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),hreg,4);   /* set the return address */   if (insn & 1)      ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));   ppc32_jit_tcb_push_epilog(&iop->ob_ptr);   ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);   ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));   ppc32_jit_close_hreg_seq(cpu);   return(0);}/* MFLR - Move From Link Register */DECLARE_INSN(MFLR){   int rd = bits(insn,21,25);   int hreg_rd;   jit_op_t *iop;   ppc32_jit_start_hreg_seq(cpu,"mflr");   hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);   iop = ppc32_op_emit_insn_output(cpu,1,"mflr");   x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,lr),4);   ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);   ppc32_jit_close_hreg_seq(cpu);   return(0);}/* MTLR - Move To Link Register */DECLARE_INSN(MTLR){   int rs = bits(insn,21,25);   int hreg_rs;   jit_op_t *iop;      ppc32_jit_start_hreg_seq(cpu,"mtlr");   hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);   ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);   iop = ppc32_op_emit_insn_output(cpu,1,"mtlr");   x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),hreg_rs,4);   ppc32_jit_close_hreg_seq(cpu);   return(0);}/* MFCTR - Move From Counter Register */DECLARE_INSN(MFCTR){   int rd = bits(insn,21,25);   int hreg_rd;   jit_op_t *iop;      ppc32_jit_start_hreg_seq(cpu,"mfctr");   hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);   iop = ppc32_op_emit_insn_output(cpu,1,"mfctr");   x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);   ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);   ppc32_jit_close_hreg_seq(cpu);   return(0);}/* MTCTR - Move To Counter Register */DECLARE_INSN(MTCTR){   int rs = bits(insn,21,25);   int hreg_rs;   jit_op_t *iop;   ppc32_jit_start_hreg_seq(cpu,"mtctr");   hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);   ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);   iop = ppc32_op_emit_insn_output(cpu,1,"mtctr");   x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr),hreg_rs,4);   ppc32_jit_close_hreg_seq(cpu);   return(0);}/* MFTBU - Move from Time Base (Up) */DECLARE_INSN(MFTBU){   int rd = bits(insn,21,25);   int hreg_rd;   jit_op_t *iop;   ppc32_jit_start_hreg_seq(cpu,"mftbu");   hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);   iop = ppc32_op_emit_insn_output(cpu,1,"mftbu");   x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);   ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);   ppc32_jit_close_hreg_seq(cpu);   return(0);}#define PPC32_TB_INCREMENT  50/* MFTBL - Move from Time Base (Lo) */DECLARE_INSN(MFTBL){   int rd = bits(insn,21,25);   int hreg_rd,hreg_t0;   jit_op_t *iop;   ppc32_jit_start_hreg_seq(cpu,"mftbl");   hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);   hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);   iop = ppc32_op_emit_insn_output(cpu,3,"mftbl");   x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,tb),4);   /* Increment the time base register */   x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,tb),4);   x86_mov_reg_membase(iop->ob_ptr,hreg_t0,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);   x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,PPC32_TB_INCREMENT);   x86_alu_reg_imm(iop->ob_ptr,X86_ADC,hreg_t0,0);

⌨️ 快捷键说明

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