📄 amd64_trans.c
字号:
AMD64_R15,OFFSET(cpu_mips_t,cp0_virt_cnt_reg),4); amd64_inc_reg_size(b->jit_ptr,AMD64_RAX,4); amd64_mov_membase_reg(b->jit_ptr,AMD64_R15, OFFSET(cpu_mips_t,cp0_virt_cnt_reg), AMD64_RAX,4); /* check with the virtual compare register */ amd64_alu_reg_membase_size(b->jit_ptr,X86_CMP,AMD64_RAX, AMD64_R15,OFFSET(cpu_mips_t,cp0_virt_cmp_reg),4); test1 = b->jit_ptr; amd64_branch8(b->jit_ptr, X86_CC_NE, 0, 1); /* we have to trigger the timer irq */ amd64_mov_reg_reg(b->jit_ptr,AMD64_RDI,AMD64_R15,8); mips64_emit_basic_c_call(b,mips64_trigger_timer_irq); amd64_patch(test1,b->jit_ptr);#endif}/* Check if there are pending IRQ */void mips64_check_pending_irq(insn_block_t *b){ u_char *test1; /* Check the pending IRQ flag */ amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX, AMD64_R15,OFFSET(cpu_mips_t,irq_pending),4); amd64_test_reg_reg_size(b->jit_ptr,AMD64_RAX,AMD64_RAX,4); test1 = b->jit_ptr; amd64_branch8(b->jit_ptr, X86_CC_Z, 0, 1); /* Update PC */ mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); /* Trigger the IRQ */ amd64_mov_reg_reg(b->jit_ptr,AMD64_RDI,AMD64_R15,8); mips64_emit_basic_c_call(b,mips64_trigger_irq); insn_block_push_epilog(b); amd64_patch(test1,b->jit_ptr);}/* Increment the number of executed instructions (performance debugging) */void mips64_inc_perf_counter(insn_block_t *b){ amd64_inc_membase(b->jit_ptr,AMD64_R15,OFFSET(cpu_mips_t,perf_counter));}/* 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); amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_alu_reg_membase(b->jit_ptr,X86_ADD,AMD64_RAX,AMD64_R15, REG_OFFSET(rt)); amd64_movsxd_reg_reg(b->jit_ptr,AMD64_RAX,X86_EAX); amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,REG_OFFSET(rd),AMD64_RAX,8); 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 */ mips64_load_imm(b,AMD64_RAX,val); amd64_alu_reg_membase(b->jit_ptr,X86_ADD,AMD64_RAX, AMD64_R15,REG_OFFSET(rs)); amd64_movsxd_reg_reg(b->jit_ptr,AMD64_RAX,X86_EAX); amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,REG_OFFSET(rt),AMD64_RAX,8); 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); mips64_load_imm(b,AMD64_RAX,val); if (rs != 0) { amd64_alu_reg_membase(b->jit_ptr,X86_ADD,AMD64_RAX, AMD64_R15,REG_OFFSET(rs)); } amd64_movsxd_reg_reg(b->jit_ptr,AMD64_RDX,X86_EAX); amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,REG_OFFSET(rt),AMD64_RDX,8); 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); amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_alu_reg_membase(b->jit_ptr,X86_ADD,AMD64_RAX,AMD64_R15, REG_OFFSET(rt)); amd64_movsxd_reg_reg(b->jit_ptr,AMD64_RAX,X86_EAX); amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,REG_OFFSET(rd),AMD64_RAX,8); 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); amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_alu_reg_membase(b->jit_ptr,X86_AND,AMD64_RAX,AMD64_R15, REG_OFFSET(rt)); amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,REG_OFFSET(rd),AMD64_RAX,8); 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); mips64_load_imm(b,AMD64_RAX,imm); amd64_alu_reg_membase(b->jit_ptr,X86_AND,AMD64_RAX, AMD64_R15,REG_OFFSET(rs)); amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,REG_OFFSET(rt),AMD64_RAX,8); 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; 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]. */ amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_alu_reg_membase(b->jit_ptr,X86_CMP,AMD64_RAX, AMD64_R15,REG_OFFSET(rt)); test1 = b->jit_ptr; amd64_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); amd64_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);}/* 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; 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]. */ amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_alu_reg_membase(b->jit_ptr,X86_CMP,AMD64_RAX, AMD64_R15,REG_OFFSET(rt)); test1 = b->jit_ptr; amd64_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); amd64_patch(test1,b->jit_ptr); return(0);}/* BEQZ (Branch On Equal Zero) */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; 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. */ amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_test_reg_reg(b->jit_ptr,AMD64_RAX,AMD64_RAX); test1 = b->jit_ptr; amd64_branch32(b->jit_ptr, X86_CC_NZ, 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); amd64_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);}/* BNEZ (Branch On Not Equal Zero) */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; 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. */ amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_test_reg_reg(b->jit_ptr,AMD64_RAX,AMD64_RAX); test1 = b->jit_ptr; amd64_branch32(b->jit_ptr, X86_CC_Z, 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); amd64_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);}/* 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 */ amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_test_reg_reg(b->jit_ptr,AMD64_RAX,AMD64_RAX); test1 = b->jit_ptr; amd64_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); amd64_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)); /* If sign bit is set, don't take the branch */ amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_test_reg_reg(b->jit_ptr,AMD64_RAX,AMD64_RAX); test1 = b->jit_ptr; amd64_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); amd64_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 */ amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_test_reg_reg(b->jit_ptr,AMD64_RAX,AMD64_RAX); test1 = b->jit_ptr; amd64_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); amd64_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 */ amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX,AMD64_R15,REG_OFFSET(rs),8); amd64_test_reg_reg(b->jit_ptr,AMD64_RAX,AMD64_RAX); test1 = b->jit_ptr; amd64_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); amd64_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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -