📄 ppc32_x86_trans.c
字号:
/* $ra = $rs & imm */ ppc32_jit_start_hreg_seq(cpu,"andis"); hreg_rs = ppc32_jit_alloc_hreg(cpu,rs); hreg_ra = ppc32_jit_alloc_hreg(cpu,ra); ppc32_op_emit_load_gpr(cpu,hreg_rs,rs); iop = ppc32_op_emit_insn_output(cpu,2,"andis"); if (ra != rs) x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4); x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,tmp); ppc32_op_emit_store_gpr(cpu,ra,hreg_ra); ppc32_op_emit_update_flags(cpu,0,TRUE); ppc32_jit_close_hreg_seq(cpu); return(0);}/* B - Branch */DECLARE_INSN(B){ m_uint32_t offset = bits(insn,2,25); m_uint32_t new_ia; jit_op_t *iop; iop = ppc32_op_emit_insn_output(cpu,4,"b"); /* compute the new ia */ new_ia = b->start_ia + (b->ppc_trans_pos << 2); new_ia += sign_extend(offset << 2,26); ppc32_set_jump(cpu,b,iop,new_ia,TRUE); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); ppc32_op_emit_branch_target(cpu,b,new_ia); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2)); return(0);}/* BA - Branch Absolute */DECLARE_INSN(BA){ m_uint32_t offset = bits(insn,2,25); m_uint32_t new_ia; jit_op_t *iop; iop = ppc32_op_emit_insn_output(cpu,4,"ba"); /* compute the new ia */ new_ia = sign_extend(offset << 2,26); ppc32_set_jump(cpu,b,iop,new_ia,TRUE); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); ppc32_op_emit_branch_target(cpu,b,new_ia); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2)); return(0);}/* BL - Branch and Link */DECLARE_INSN(BL){ m_uint32_t offset = bits(insn,2,25); m_uint32_t new_ia; jit_op_t *iop; iop = ppc32_op_emit_insn_output(cpu,4,"bl"); /* compute the new ia */ new_ia = b->start_ia + (b->ppc_trans_pos << 2); new_ia += sign_extend(offset << 2,26); /* set the return address */ ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_set_jump(cpu,b,iop,new_ia,TRUE); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); ppc32_op_emit_branch_target(cpu,b,new_ia); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2)); return(0);}/* BLA - Branch and Link Absolute */DECLARE_INSN(BLA){ m_uint32_t offset = bits(insn,2,25); m_uint32_t new_ia; jit_op_t *iop; iop = ppc32_op_emit_insn_output(cpu,4,"bla"); /* compute the new ia */ new_ia = sign_extend(offset << 2,26); /* set the return address */ ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_set_jump(cpu,b,iop,new_ia,TRUE); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); ppc32_op_emit_branch_target(cpu,b,new_ia); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2)); return(0);}/* BC - Branch Conditional (Condition Check only) */DECLARE_INSN(BCC){ int bo = bits(insn,21,25); int bi = bits(insn,16,20); int bd = bits(insn,2,15); jit_op_t *iop; u_int cr_field,cr_bit; m_uint32_t new_ia; u_char *jump_ptr; int local_jump; int cond; ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_JUMP); iop = ppc32_op_emit_insn_output(cpu,5,"bcc"); /* Get the wanted value for the condition bit */ cond = (bo >> 3) & 0x1; /* Set the return address */ if (insn & 1) { ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2)); } /* Compute the new ia */ new_ia = sign_extend_32(bd << 2,16); if (!(insn & 0x02)) new_ia += b->start_ia + (b->ppc_trans_pos << 2); /* Test the condition bit */ cr_field = ppc32_get_cr_field(bi); cr_bit = ppc32_get_cr_bit(bi); ppc32_op_emit_require_flags(cpu,cr_field); x86_test_membase_imm(iop->ob_ptr, X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field), (1 << cr_bit)); local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr); /* * Optimize the jump, depending if the destination is in the same * page or not. */ if (local_jump) { ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia); x86_branch32(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,0,FALSE); } else { jump_ptr = iop->ob_ptr; x86_branch32(iop->ob_ptr,(cond) ? X86_CC_Z : X86_CC_NZ,0,FALSE); ppc32_set_jump(cpu,b,iop,new_ia,TRUE); x86_patch(jump_ptr,iop->ob_ptr); } ppc32_op_emit_branch_target(cpu,b,new_ia); return(0);}/* BC - Branch Conditional */DECLARE_INSN(BC){ int bo = bits(insn,21,25); int bi = bits(insn,16,20); int bd = bits(insn,2,15); int hreg_t0,hreg_t1; jit_op_t *iop; u_int cr_field,cr_bit; m_uint32_t new_ia; u_char *jump_ptr; int local_jump; int cond,ctr; ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_JUMP); iop = ppc32_op_emit_insn_output(cpu,5,"bc"); ppc32_jit_start_hreg_seq(cpu,"bc"); hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1); hreg_t1 = ppc32_jit_get_tmp_hreg(cpu); ppc32_op_emit_alter_host_reg(cpu,hreg_t0); /* Get the wanted value for the condition bit and CTR value */ cond = (bo >> 3) & 0x1; ctr = (bo >> 1) & 0x1; /* Set the return address */ if (insn & 1) { ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2)); } /* Compute the new ia */ new_ia = sign_extend_32(bd << 2,16); if (!(insn & 0x02)) new_ia += b->start_ia + (b->ppc_trans_pos << 2); x86_mov_reg_imm(iop->ob_ptr,hreg_t0,1); /* Decrement the count register */ if (!(bo & 0x04)) { x86_dec_membase(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr)); x86_set_reg(iop->ob_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,hreg_t1,FALSE); x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1); } /* Test the condition bit */ if (!((bo >> 4) & 0x01)) { cr_field = ppc32_get_cr_field(bi); cr_bit = ppc32_get_cr_bit(bi); ppc32_op_emit_require_flags(cpu,cr_field); x86_test_membase_imm(iop->ob_ptr, X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field), (1 << cr_bit)); x86_set_reg(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,hreg_t1,FALSE); x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1); } x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01); local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr); /* * Optimize the jump, depending if the destination is in the same * page or not. */ if (local_jump) { ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia); x86_branch32(iop->ob_ptr,X86_CC_NZ,0,FALSE); } else { jump_ptr = iop->ob_ptr; x86_branch32(iop->ob_ptr,X86_CC_Z,0,FALSE); ppc32_set_jump(cpu,b,iop,new_ia,TRUE); x86_patch(jump_ptr,iop->ob_ptr); } ppc32_op_emit_branch_target(cpu,b,new_ia); ppc32_jit_close_hreg_seq(cpu); return(0);}/* BCLR - Branch Conditional to Link register */DECLARE_INSN(BCLR){ int bo = bits(insn,21,25); int bi = bits(insn,16,20); int bd = bits(insn,2,15); int hreg_t0,hreg_t1; jit_op_t *iop; u_int cr_field,cr_bit; m_uint32_t new_ia; u_char *jump_ptr; int cond,ctr; ppc32_jit_start_hreg_seq(cpu,"bclr"); hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1); hreg_t1 = ppc32_jit_get_tmp_hreg(cpu); ppc32_op_emit_alter_host_reg(cpu,hreg_t0); iop = ppc32_op_emit_insn_output(cpu,5,"bclr"); /* Get the wanted value for the condition bit and CTR value */ cond = (bo >> 3) & 0x1; ctr = (bo >> 1) & 0x1; /* Compute the new ia */ new_ia = sign_extend_32(bd << 2,16); if (!(insn & 0x02)) new_ia += b->start_ia + (b->ppc_trans_pos << 2); x86_mov_reg_imm(iop->ob_ptr,hreg_t0,1); /* Decrement the count register */ if (!(bo & 0x04)) { x86_dec_membase(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr)); x86_set_reg(iop->ob_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,hreg_t1,FALSE); x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1); } /* Test the condition bit */ if (!((bo >> 4) & 0x01)) { cr_field = ppc32_get_cr_field(bi); cr_bit = ppc32_get_cr_bit(bi); ppc32_op_emit_require_flags(cpu,cr_field); x86_test_membase_imm(iop->ob_ptr, X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field), (1 << cr_bit)); x86_set_reg(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,hreg_t1,FALSE); x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1); } /* Set the return address */ x86_mov_reg_membase(iop->ob_ptr,hreg_t1,X86_EDI,OFFSET(cpu_ppc_t,lr),4); if (insn & 1) { ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2)); } /* Branching */ x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01); jump_ptr = iop->ob_ptr; x86_branch32(iop->ob_ptr,X86_CC_Z,0,FALSE); x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t1,0xFFFFFFFC); x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),hreg_t1,4); ppc32_jit_tcb_push_epilog(&iop->ob_ptr); x86_patch(jump_ptr,iop->ob_ptr); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CMP - Compare */DECLARE_INSN(CMP){ int rd = bits(insn,23,25); int ra = bits(insn,16,20); int rb = bits(insn,11,15); int hreg_ra,hreg_rb; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"cmp"); hreg_ra = ppc32_jit_alloc_hreg(cpu,ra); hreg_rb = ppc32_jit_alloc_hreg(cpu,rb); ppc32_op_emit_load_gpr(cpu,hreg_ra,ra); ppc32_op_emit_load_gpr(cpu,hreg_rb,rb); iop = ppc32_op_emit_insn_output(cpu,1,"cmp"); x86_alu_reg_reg(iop->ob_ptr,X86_CMP,hreg_ra,hreg_rb); ppc32_op_emit_update_flags(cpu,rd,TRUE); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CMPI - Compare Immediate */DECLARE_INSN(CMPI){ int rd = bits(insn,23,25); int ra = bits(insn,16,20); m_uint16_t imm = bits(insn,0,15); m_uint32_t tmp = sign_extend_32(imm,16); int hreg_ra; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"cmpi"); hreg_ra = ppc32_jit_alloc_hreg(cpu,ra); ppc32_op_emit_load_gpr(cpu,hreg_ra,ra); iop = ppc32_op_emit_insn_output(cpu,1,"cmpi"); x86_alu_reg_imm(iop->ob_ptr,X86_CMP,hreg_ra,tmp); ppc32_op_emit_update_flags(cpu,rd,TRUE); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CMPL - Compare Logical */DECLARE_INSN(CMPL){ int rd = bits(insn,23,25); int ra = bits(insn,16,20); int rb = bits(insn,11,15); int hreg_ra,hreg_rb; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"cmpl"); hreg_ra = ppc32_jit_alloc_hreg(cpu,ra); hreg_rb = ppc32_jit_alloc_hreg(cpu,rb); ppc32_op_emit_load_gpr(cpu,hreg_ra,ra); ppc32_op_emit_load_gpr(cpu,hreg_rb,rb); iop = ppc32_op_emit_insn_output(cpu,1,"cmpl"); x86_alu_reg_reg(iop->ob_ptr,X86_CMP,hreg_ra,hreg_rb); ppc32_op_emit_update_flags(cpu,rd,FALSE); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CMPLI - Compare Immediate */DECLARE_INSN(CMPLI){ int rd = bits(insn,23,25); int ra = bits(insn,16,20); m_uint32_t imm = bits(insn,0,15); int hreg_ra; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"cmpli"); hreg_ra = ppc32_jit_alloc_hreg(cpu,ra); ppc32_op_emit_load_gpr(cpu,hreg_ra,ra); iop = ppc32_op_emit_insn_output(cpu,1,"cmpli"); x86_alu_reg_imm(iop->ob_ptr,X86_CMP,hreg_ra,imm); ppc32_op_emit_update_flags(cpu,rd,FALSE); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CRAND - Condition Register AND */DECLARE_INSN(CRAND){ int bd = bits(insn,21,25); int bb = bits(insn,16,20); int ba = bits(insn,11,15); int hreg_t0; jit_op_t *iop; ppc32_op_emit_alter_host_reg(cpu,X86_EDX); ppc32_jit_start_hreg_seq(cpu,"crand"); hreg_t0 = ppc32_jit_get_tmp_hreg(cpu); ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -