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

📄 x86_trans.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Emit unhandled instruction code */static int mips64_emit_unknown(cpu_mips_t *cpu,insn_block_t *b,                               mips_insn_t opcode){      x86_mov_reg_imm(b->jit_ptr,X86_EAX,opcode);   x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,4);   x86_push_reg(b->jit_ptr,X86_EAX);   x86_push_reg(b->jit_ptr,X86_EDI);   mips64_emit_c_call(b,mips64_unknown_opcode);   x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);   return(0);}/* Invalid delay slot handler */static fastcall void mips64_invalid_delay_slot(cpu_mips_t *cpu){   printf("MIPS64: invalid instruction in delay slot at 0x%llx (ra=0x%llx)\n",          cpu->pc,cpu->gpr[MIPS_GPR_RA]);   mips64_dump_regs(cpu);   /* Halt the virtual CPU */   cpu->pc = 0;}/* Emit unhandled instruction code */int mips64_emit_invalid_delay_slot(insn_block_t *b){      x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);   mips64_emit_c_call(b,mips64_invalid_delay_slot);   insn_block_push_epilog(b);   return(0);}/* Located in external assembly module */#ifdef FAST_ASMextern void mips64_inc_cp0_cnt_asm(void);#endif/*  * Increment count register and trigger the timer IRQ if value in compare  * register is the same. */void mips64_inc_cp0_count_reg(insn_block_t *b){   x86_inc_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,cp0_virt_cnt_reg));#if 0 /* TIMER_IRQ */#ifdef FAST_ASM   mips64_emit_basic_c_call(b,mips64_inc_cp0_cnt_asm);#else   x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);   mips64_emit_basic_c_call(b,mips64_exec_inc_cp0_cnt);#endif#endif}/* Check if there are pending IRQ */void mips64_check_pending_irq(insn_block_t *b){   u_char *test1;   /* Check the pending IRQ flag */   x86_mov_reg_membase(b->jit_ptr,X86_EAX,                       X86_EDI,OFFSET(cpu_mips_t,irq_pending),4);   x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);   test1 = b->jit_ptr;   x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);   /* Save PC */   mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));   /* Trigger the IRQ */   x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);   mips64_emit_basic_c_call(b,mips64_trigger_irq);   insn_block_push_epilog(b);   x86_patch(test1,b->jit_ptr);}/* Increment the number of executed instructions (performance debugging) */void mips64_inc_perf_counter(insn_block_t *b){   x86_alu_membase_imm(b->jit_ptr,X86_ADD,                       X86_EDI,OFFSET(cpu_mips_t,perf_counter),1);   x86_alu_membase_imm(b->jit_ptr,X86_ADC,                       X86_EDI,OFFSET(cpu_mips_t,perf_counter)+4,0);}/* ADD */static int mips64_emit_ADD(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){	   int rs = bits(insn,21,25);   int rt = bits(insn,16,20);   int rd = bits(insn,11,15);   /* TODO: Exception handling */   x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);   x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EAX,X86_EDI,REG_OFFSET(rt));      x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);   x86_cdq(b->jit_ptr);   x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);   return(0);}/* ADDI */static int mips64_emit_ADDI(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int rs  = bits(insn,21,25);   int rt  = bits(insn,16,20);   int imm = bits(insn,0,15);   m_uint64_t val = sign_extend(imm,16);   /* TODO: Exception handling */   x86_mov_reg_imm(b->jit_ptr,X86_EAX,val & 0xffffffff);   x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EAX,X86_EDI,REG_OFFSET(rs));   x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_EAX,4);   x86_cdq(b->jit_ptr);   x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_EDX,4);   return(0);}/* ADDIU */static int mips64_emit_ADDIU(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int rs  = bits(insn,21,25);   int rt  = bits(insn,16,20);   int imm = bits(insn,0,15);   m_uint64_t val = sign_extend(imm,16);   x86_mov_reg_imm(b->jit_ptr,X86_EAX,val & 0xffffffff);   x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EAX,X86_EDI,REG_OFFSET(rs));   x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_EAX,4);   x86_cdq(b->jit_ptr);   x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_EDX,4);   return(0);}/* ADDU */static int mips64_emit_ADDU(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){	   int rs = bits(insn,21,25);   int rt = bits(insn,16,20);   int rd = bits(insn,11,15);      x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);   x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EAX,X86_EDI,REG_OFFSET(rt));      x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);   x86_cdq(b->jit_ptr);   x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);   return(0);}/* AND */static int mips64_emit_AND(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int rs = bits(insn,21,25);   int rt = bits(insn,16,20);   int rd = bits(insn,11,15);   x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);   x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);   x86_alu_reg_membase(b->jit_ptr,X86_AND,X86_EAX,X86_EDI,REG_OFFSET(rt));   x86_alu_reg_membase(b->jit_ptr,X86_AND,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);   x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);   x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);   return(0);}/* ANDI */static int mips64_emit_ANDI(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int rs  = bits(insn,21,25);   int rt  = bits(insn,16,20);   int imm = bits(insn,0,15);   x86_mov_reg_imm(b->jit_ptr,X86_EAX,imm);   x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EBX);   x86_alu_reg_membase(b->jit_ptr,X86_AND,X86_EAX,X86_EDI,REG_OFFSET(rs));   x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_EAX,4);   x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_EBX,4);   return(0);}/* B (Branch, virtual instruction) */static int mips64_emit_B(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int offset = bits(insn,0,15);   m_uint64_t new_pc;   /* compute the new pc */   new_pc = b->start_pc + (b->mips_trans_pos << 2);   new_pc += sign_extend(offset << 2,18);   /* insert the instruction in the delay slot */   insn_fetch_and_emit(cpu,b,1);   /* set the new pc in cpu structure */   mips64_set_jump(cpu,b,new_pc,1);   return(0);}/* BAL (Branch and Link, virtual instruction) */static int mips64_emit_BAL(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int offset = bits(insn,0,15);   m_uint64_t new_pc;   /* compute the new pc */   new_pc = b->start_pc + (b->mips_trans_pos << 2);   new_pc += sign_extend(offset << 2,18);   /* set the return address (instruction after the delay slot) */   mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));   /* insert the instruction in the delay slot */   insn_fetch_and_emit(cpu,b,1);   /* set the new pc in cpu structure */   mips64_set_jump(cpu,b,new_pc,0);   return(0);}/* BEQ (Branch On Equal) */static int mips64_emit_BEQ(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int rs = bits(insn,21,25);   int rt = bits(insn,16,20);   int offset = bits(insn,0,15);   u_char *test1,*test2;   m_uint64_t new_pc;   /* compute the new pc */   new_pc = b->start_pc + (b->mips_trans_pos << 2);   new_pc += sign_extend(offset << 2,18);      /*     * compare gpr[rs] and gpr[rt].     * compare the low 32 bits first (higher probability).    */   x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);   x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDI,REG_OFFSET(rt));   test1 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);   x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);   x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);   test2 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);   /* insert the instruction in the delay slot */   insn_fetch_and_emit(cpu,b,2);   /* set the new pc in cpu structure */   mips64_set_jump(cpu,b,new_pc,0);   x86_patch(test1,b->jit_ptr);   x86_patch(test2,b->jit_ptr);   /* if the branch is not taken, we have to execute the delay slot too */   insn_fetch_and_emit(cpu,b,1);   return(0);}/* BEQL (Branch On Equal Likely) */static int mips64_emit_BEQL(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int rs = bits(insn,21,25);   int rt = bits(insn,16,20);   int offset = bits(insn,0,15);   u_char *test1,*test2;   m_uint64_t new_pc;   /* compute the new pc */   new_pc = b->start_pc + (b->mips_trans_pos << 2);   new_pc += sign_extend(offset << 2,18);   /*     * compare gpr[rs] and gpr[rt].     * compare the low 32 bits first (higher probability).    */   x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);   x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDI,REG_OFFSET(rt));   test1 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);   x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);   x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);   test2 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);   /* insert the instruction in the delay slot */   insn_fetch_and_emit(cpu,b,1);   /* set the new pc in cpu structure */   mips64_set_jump(cpu,b,new_pc,1);   x86_patch(test1,b->jit_ptr);   x86_patch(test2,b->jit_ptr);   return(0);}/* BEQZ (Branch On Equal Zero - optimization) */static int mips64_emit_BEQZ(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int rs = bits(insn,21,25);   int offset = bits(insn,0,15);   u_char *test1,*test2;   m_uint64_t new_pc;   /* compute the new pc */   new_pc = b->start_pc + (b->mips_trans_pos << 2);   new_pc += sign_extend(offset << 2,18);      /*     * compare gpr[rs] with 0.    * compare the low 32 bits first (higher probability).    */   x86_alu_membase_imm(b->jit_ptr,X86_CMP,X86_EDI,REG_OFFSET(rs),0);   test1 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);   x86_alu_membase_imm(b->jit_ptr,X86_CMP,X86_EDI,REG_OFFSET(rs)+4,0);   test2 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);   /* insert the instruction in the delay slot */   insn_fetch_and_emit(cpu,b,2);   /* set the new pc in cpu structure */   mips64_set_jump(cpu,b,new_pc,1);   x86_patch(test1,b->jit_ptr);   x86_patch(test2,b->jit_ptr);   /* if the branch is not taken, we have to execute the delay slot too */   insn_fetch_and_emit(cpu,b,1);   return(0);}/* BNEZ (Branch On Not Equal Zero - optimization) */static int mips64_emit_BNEZ(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int rs = bits(insn,21,25);   int offset = bits(insn,0,15);   u_char *test1,*test2;   m_uint64_t new_pc;   /* compute the new pc */   new_pc = b->start_pc + (b->mips_trans_pos << 2);   new_pc += sign_extend(offset << 2,18);      /*     * compare gpr[rs] with 0.    * compare the low 32 bits first (higher probability).    */   x86_alu_membase_imm(b->jit_ptr,X86_CMP,X86_EDI,REG_OFFSET(rs),0);   test1 = b->jit_ptr;   x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);   x86_alu_membase_imm(b->jit_ptr,X86_CMP,X86_EDI,REG_OFFSET(rs)+4,0);   test2 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_E, 0, 1);   x86_patch(test1,b->jit_ptr);   /* insert the instruction in the delay slot */   insn_fetch_and_emit(cpu,b,2);   /* set the new pc in cpu structure */   mips64_set_jump(cpu,b,new_pc,1);   x86_patch(test2,b->jit_ptr);   /* if the branch is not taken, we have to execute the delay slot too */   insn_fetch_and_emit(cpu,b,1);   return(0);}/* BGEZ (Branch On Greater or Equal Than Zero) */static int mips64_emit_BGEZ(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int rs = bits(insn,21,25);   int offset = bits(insn,0,15);   u_char *test1;   m_uint64_t new_pc;   /* compute the new pc */   new_pc = b->start_pc + (b->mips_trans_pos << 2);   new_pc += sign_extend(offset << 2,18);   /* If sign bit is set, don't take the branch */   x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);   x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);   test1 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_S, 0, 1);   /* insert the instruction in the delay slot */   insn_fetch_and_emit(cpu,b,2);   /* set the new pc in cpu structure */   mips64_set_jump(cpu,b,new_pc,1);   x86_patch(test1,b->jit_ptr);   /* if the branch is not taken, we have to execute the delay slot too */   insn_fetch_and_emit(cpu,b,1);   return(0);}/* BGEZAL (Branch On Greater or Equal Than Zero And Link) */static int mips64_emit_BGEZAL(cpu_mips_t *cpu,insn_block_t *b,mips_insn_t insn){   int rs = bits(insn,21,25);   int offset = bits(insn,0,15);   u_char *test1;   m_uint64_t new_pc;   /* compute the new pc */   new_pc = b->start_pc + (b->mips_trans_pos << 2);   new_pc += sign_extend(offset << 2,18);   /* set the return address (instruction after the delay slot) */   mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));

⌨️ 快捷键说明

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