x86_trans.c

来自「思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco ro」· C语言 代码 · 共 2,177 行 · 第 1/5 页

C
2,177
字号
   /* 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);}/* BGEZALL (Branch On Greater or Equal Than Zero and Link Likely) */static int mips64_emit_BGEZALL(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));   /* 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,1);   /* set the new pc in cpu structure */   mips64_set_jump(cpu,b,new_pc,1);   x86_patch(test1,b->jit_ptr);   return(0);}/* BGEZL (Branch On Greater or Equal Than Zero Likely) */static int mips64_emit_BGEZL(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,1);   /* set the new pc in cpu structure */   mips64_set_jump(cpu,b,new_pc,1);   x86_patch(test1,b->jit_ptr);   return(0);}/* BGTZ (Branch On Greater Than Zero) */static int mips64_emit_BGTZ(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,*test3;   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);   /*     * test the hi word of gpr[rs]    */   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);   test2 = b->jit_ptr;   x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);   /* test the lo word of gpr[rs] (here hi word = 0) */   x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs),4);   x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);   test3 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_Z, 0, 1);   /* here, we take the branch */   x86_patch(test2,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(test1,b->jit_ptr);   x86_patch(test3,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);}/* BGTZL (Branch On Greater Than Zero Likely) */static int mips64_emit_BGTZL(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,*test3;   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);   /*     * test the hi word of gpr[rs]    */   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);   test2 = b->jit_ptr;   x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);   /* test the lo word of gpr[rs] (here hi word = 0) */   x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs),4);   x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);   test3 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_Z, 0, 1);   /* here, we take the branch */   x86_patch(test2,b->jit_ptr);   /* 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(test3,b->jit_ptr);   return(0);}/* BLEZ (Branch On Less or Equal Than Zero) */static int mips64_emit_BLEZ(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,*test3;   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);   /*     * test the hi word of gpr[rs]    */   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_branch8(b->jit_ptr, X86_CC_S, 0, 1);   test2 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_NZ, 0, 1);   /* test the lo word of gpr[rs] (here hi word = 0) */   x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs),4);   x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);   test3 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_NZ, 0, 1);   /* here, we take the branch */   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);   x86_patch(test3,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);}/* BLEZL (Branch On Less or Equal Than Zero Likely) */static int mips64_emit_BLEZL(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,*test3;   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);   /*     * test the hi word of gpr[rs]    */   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_branch8(b->jit_ptr, X86_CC_S, 0, 1);   test2 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_NZ, 0, 1);   /* test the lo word of gpr[rs] (here hi word = 0) */   x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs),4);   x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);   test3 = b->jit_ptr;   x86_branch32(b->jit_ptr, X86_CC_NZ, 0, 1);   /* here, we take the branch */   x86_patch(test1,b->jit_ptr);   /* 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(test2,b->jit_ptr);   x86_patch(test3,b->jit_ptr);   return(0);}/* BLTZ (Branch On Less Than Zero) */static int mips64_emit_BLTZ(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);   /*     * test the sign bit of gpr[rs], if set, 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_NS, 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);}/* BLTZAL (Branch On Less Than Zero And Link) */static int mips64_emit_BLTZAL(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));   /*     * test the sign bit of gpr[rs], if set, 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_NS, 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);}/* BLTZALL (Branch On Less Than Zero And Link Likely) */static int mips64_emit_BLTZALL(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));   /*     * test the sign bit of gpr[rs], if set, 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_NS, 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);   return(0);}/* BLTZL (Branch On Less Than Zero Likely) */static int mips64_emit_BLTZL(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);   /*     * test the sign bit of gpr[rs], if set, 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_NS, 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);   return(0);}/* BNE (Branch On Not Equal) */static int mips64_emit_BNE(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_branch8(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_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);}/* BNEL (Branch On Not Equal Likely) */static int mips64_emit_BNEL(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;

⌨️ 快捷键说明

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