📄 mips64_x86_trans.c
字号:
/* if the branch is not taken, we have to execute the delay slot too */ mips64_jit_fetch_and_emit(cpu,b,1); return(0);}/* BGEZALL (Branch On Greater or Equal Than Zero and Link Likely) */DECLARE_INSN(BGEZALL){ 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 */ mips64_jit_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) */DECLARE_INSN(BGEZL){ 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 */ mips64_jit_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) */DECLARE_INSN(BGTZ){ 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 */ mips64_jit_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 */ mips64_jit_fetch_and_emit(cpu,b,1); return(0);}/* BGTZL (Branch On Greater Than Zero Likely) */DECLARE_INSN(BGTZL){ 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 */ mips64_jit_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) */DECLARE_INSN(BLEZ){ 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 */ mips64_jit_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 */ mips64_jit_fetch_and_emit(cpu,b,1); return(0);}/* BLEZL (Branch On Less or Equal Than Zero Likely) */DECLARE_INSN(BLEZL){ 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 */ mips64_jit_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) */DECLARE_INSN(BLTZ){ 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 */ mips64_jit_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 */ mips64_jit_fetch_and_emit(cpu,b,1); return(0);}/* BLTZAL (Branch On Less Than Zero And Link) */DECLARE_INSN(BLTZAL){ 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 */ mips64_jit_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 */ mips64_jit_fetch_and_emit(cpu,b,1); return(0);}/* BLTZALL (Branch On Less Than Zero And Link Likely) */DECLARE_INSN(BLTZALL){ 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 */ mips64_jit_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) */DECLARE_INSN(BLTZL){ 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 */ mips64_jit_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) */DECLARE_INSN(BNE){ 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 */ mips64_jit_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 */ mips64_jit_fetch_and_emit(cpu,b,1); return(0);}/* BNEL (Branch On Not Equal Likely) */DECLARE_INSN(BNEL){ 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 */ mips64_jit_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); return(0);}/* BREAK */DECLARE_INSN(BREAK){ u_int code = bits(insn,6,25); x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,12); x86_mov_reg_imm(b->jit_ptr,X86_EDX,code); x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4); mips64_emit_basic_c_call(b,mips64_exec_break); x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12); mips64_jit_tcb_push_epilog(b); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -